Basically I have three models , Wedding , invites , and users. Weddings has invites and invites has users ( keeping in mind that user can belong to multiple invites ). I want to access $wedding->users directly.
Wedding.php
class Wedding extends Model
{
public function invites()
{
return $this->hasMany(Invite::class);
}
...
Invites.php
class Invite extends Model
{
public function user()
{
return $this->belongsTo(User::class);
}
...
Tables:
Wedding
- id
- name
Invite
- invite_date
- wedding_id
- user_id
User
- id
- name
- email
And i want to access retrieve users directly , using $wedding->users
What's the relationship between Wedding and users?
It's a BelongsToMany relationship:
public function users() {
return $this->belongsToMany(User::class, 'invites');
}
Add this method to your Widding class
public function users()
{
return $this->hasManyThrough('App\User', 'App\Invite');
}
for more about hasManyThrough see the documentation.
Related
I am new to Laravel, I have a question regarding Eloquent:
This is my DB table structure:
users
- id
- user_id
- username
- name
- email
- password
- email_verified_at
- remember_tok
- created_at
- updated_at
challenges
- id
- challenge_id
- category_id
- hashtag
- title
- description
- duration
- link
- created_at
- updated_at
- user_id
user_challenges
- user_id
- challenge_id
- duration
- created_at
- updated_at
What I want to achieve is to display the user's challenges, so for example, if a user joins a challenge in the user dashboard I want to display the challenges that he joined, but also the challenges that the user has created (if he has created any);
Models\User.php
class User extends Authenticatable
{
use Notifiable;
public function challenges() {
return $this->hasMany(Challenge::class, 'user_id');
}
public function userChallenges() {
return $this->hasMany(UserChallenge::class, 'user_id');
}
}
Models\Challenge.php
class Challenge extends Model
{
public function user () {
return $this->belongsTo(User::class, 'user_id');
}
}
Models\UserChallenge.php
class UserChallenge extends Model
{
public function user () {
return $this->belongsTo(User::class, 'user_id');
}
}
This is what I have in my Home Controller:
App\Http\Controllers\HomeController.php
class HomeController extends Controller
{
public function index()
{
$user_id = auth()->id();
$user = User::find($user_id);
return view('home')
->with('challenges', $user->challenges)
->with('userChallenges', $user->userChallenges);
}
}
This is what I get currently for the "Joined Challenges" in My Dashboard - but how can I join the tables when returning the view so I can also get the challenge hashtag title? Like I get above under "My Challenges" section?
Dashboard
UPDATE:
What should I add to my database so I can count the number of users that have joined the challenge?
To get user created challenges, I believe you are already doing it correctly.
And to get user joined challenges. You almost get it right with your pivot table. You can have look on many-to-many relationship in laravel documentation.
These are the sample code to retrieve challenges created by a user and challenges joined by a user. These code should reside in your User Model, you should keep the model.
public function created_challenges()
{
return $this->hasMany(Challenge::class,'user_id','id');
}
public function joined_challenges()
{
return $this->belongsToMany(Challenges::class, 'user_challenges', 'user_id', 'challenges_id');
}
Once you get the relationship working right, you can simply use the collection returned from the relationship. Once you pass the $user->joined_challenges to your view, you can do as below
#foreach ($joined_challenges as $challenge)
<p>{{$challenge->hashtag}}</p>
<p>{{$challenge->title}}</p>
#endforeach
Let me know it this works, cheers! ;)
I need advice about my model relationships,
Logic
Group has many users
Group has many admins
User has many groups (as user)
User has many groups (as admin)
Database Structure
Group Table
User Table
Group_Users table (save id of user and id of group)
Group_Admins table (save id of user and id of group)
Relationship Code
User model
public function groupsUser() {
return $this->hasMany(GroupUser::class);
}
public function groupsAdmin() {
return $this->hasMany(GroupAdmin::class);
}
Group model
public function users() {
return $this->hasMany(GroupUser::class);
}
public function admins() {
return $this->hasMany(GroupAdmin::class);
}
GroupUser model
public function group() {
return $this->belongsTo(Group::class);
}
public function user() {
return $this->belongsTo(User::class);
}
GroupAdmin model
public function group() {
return $this->belongsTo(Group::class);
}
public function user() {
return $this->belongsTo(User::class);
}
Help wanted
Basically as the relationships between users and groups is many to many normally I shouldn't need models of GroupUser and GroupAdmin and then just using sync() function in order to add/remove users and group id's from those tables.
What is my concerns then?
Normally I use that type of connection when I want input bulk ids into database (let say adding tags to posts, suddenly relate 10 tags id to 1 post) that moment using sync() and removing GroupUser and GroupAdmin models makes sense but in my case as users joins/adds to groups one by one, what do you suggest for this relationships?
Is my current approach makes sense?
Is is better if I remove those GroupUser and GroupAdmin models and add them to user, group model like:
public function users()
{
return $this->hasMany(User::class, 'group_users', 'user_id', 'id');
}
and such so?
What do you think is the best practice?
users and groups is many to many
your tables like this?
users, user_group , groups ?
How about use 'belongsToMany' relation?
Laravel many to many relation
// User model
public function groups() {
return $this->belognsToMany(Group::class);
}
// Group model
public function users() {
return $this->belognsToMany(User::class);
}
And use like.
User::find(1)->groups; // return user 1 groups
User::find(1)->groups()->sync($groupIds); // relate user and groups
Group::find(1)->users; // return group 1 users
If you have role column in your users table, you cold add relation like.
// Group model
public function users() {
return $this->belognsToMany(User::class)->where('role', 'the role of normal user');
}
public function admins() {
return $this->belognsToMany(User::class)->where('role', 'the role of admin user');
}
Hope it helps you.
I want to have two tables one for Employees and one for Companies, both Employees & Companies should be registered within the site, thus they should have records in the users table provided with Laravel. How should I structure the relationships between the models, should I go for polymorphic relationships or use one to one?
The answer is to add two columns to the "users" table: userable_id and userable_type. userable_id will be used to store the id of the row for the entity (Employee or Company), and the userable_type will hold the class path for the Eloquent model.
in create_users_table migration file add these two lines:
// ...
$table->integer('userable_id')->unsigned();
$table->string('userable_type');
// ...
in User.php model:
class User extends Model {
// Add this declaration.
public function userable()
{
return $this->morphTo();
}
}
in your Company.php model:
class Company extends Model
{
// Add this method.
public function user()
{
return $this->morphMany(User::class, 'userable');
}
}
in the Employee.php model do the same as above:
class Employee extends Model
{
// Add this method.
public function user()
{
return $this->morphMany(User::class, 'userable');
}
}
Now you should be able to access the user by running:
App\Company::all()->get(1)->user;
// or
App\Employee::all()->get(1)->user;
And access the entity with this one-liner:
App\User::all()->get(1)->userable;
I am not much familiar with eloquent orm in laravel
I have 3 tables they are
-- leads
|
Lead_appointments
and users table
since lead_appointments belongs to leads references id on leads by lead_id
the leads_appointments has a column called created_by with user's id in it
I am trying to query user's name and email along with the result as another column when query using eloquent
Lead Model
class Leads extends Model
{
public function appointments()
{
return $this->hasMany('App\Models\LeadsAppointments', 'lead_id');
}
}
My eloquent query in controller
return $this->lead->with('appointments')->find($id);
the result is like this
In under appointments i also want user email and name along with created by in it
But I couldn't figure it out
Add a relation to LeadAppointment model like this:
class LeadAppointment extends Model
{
public function users()
{
return $this->belongsTo('App\Models\User', 'created_by');
}
}
and change leads model like this:
class Leads extends Model
{
public function appointments()
{
return $this->hasMany('App\Models\LeadsAppointments', 'lead_id')->with('users');
}
}
I'm having a hard time understanding on how to model a triple relation in Laravel.
I have 3 models: User, Tour and Photo
Each tour has users associated with it and all users can post photos. Which means the database looks something like this:
id , tour_id, user_id, photo_id
This way I know which user posted which photo for which tour. My question is, how do I model this in Eloquent?
Update Based on your last comment.
The simplest answer to your question is by using relations belongsToMany and hasMany.
Let me explain.
You need 4 table users, tours, tour_user and photos.
users table contain id,name
tours table contain id,name,
tour_user table contain id,tour_id,user_id
photos table contain id,name,user_id,tour_id
Why belongsToMany ? because each user has more than one tour and each tour has more than one users. So we link both tables by using a third table tour_user. It also helps in normalization.
Now that we have examined the table structure for the relationship, let's define it on the User model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
public function tours()
{
return $this->belongsToMany('App\Tour');
}
/* To retrieve photos of a user */
public function photos()
{
return $this->hasMany('App\Photo');
}
}
Tour model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Tour extends Model
{
public function users()
{
return $this->belongsToMany('App\User');
}
/* To retrieve photos of a tour*/
public function photos()
{
return $this->hasMany('App\Photo');
}
}
Now Photo model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Photo extends Model
{
public function users()
{
return $this->belongsTo('App\User');
}
public function tours()
{
return $this->belongsTo('App\Tour');
}
}
Now let find all tour of a specific user by using
public function show($id)
{
$user = User::find($id);
return view('show')->withUser($user) ;
}
Now in show view, page lets extract all tours of that user and his photos
#foreach($user->tours as $tour)
{{ $tour->name }}
#foreach($tour->photos as $photo)
#if($user->id == $photo->user_id)
{{ $photo->name }}
#endif
#endforeach
#endforeach
You should have: one to many Tour > user and
one to many User > Photo
include this function in your Tour model.
public function allusers()
{
return $this->hasMany(User::class);
}
and this in your User model.
public function allphotos()
{
return $this->hasMany(Photos::class);
}
Then you can get a tour $tour = Tour::find(1);
and just use the function to get the users with this:
$usersOnTour = $tour->allusers();
First make sure you have a user_id foriegn key field in your tour model and 'photo_id' foriegn key field in your user moel
the trick is to have user model with a hasOne/hasMany relationship with photo model and then have tour model with a hasOne/hasMany relationship with the user model.
1 - first in your user model define a relationship like this
public function photo()
{
return $this->hasOne('App\Photo');
}
2 - In your tour model define a hasMany relationship like this
public function users()
{
return $this->hasMany('App\User');
}
so when you fetch a tour model like
$a = tour::All();
you can do
$a->users->'field_in_user_table'
or
$a->users->photo; // to get the photo field value from photo table