Laravel - how to display data of two tables using their pivot table - php

There are three tables:
-
users (id, name,email,password)
-roles(id, name)
-user_roles(user_id,role_id)
What I am trying to do
Get the user_id from user_roles and using a foreach loop, display which role_id are assigned from role to it e.g.
John Doe | Manager
Jane Doe | Admin
EDIT: In response to Andy Holmes comment below:
In User model, the following relationship exists, with an inverse in the Role model.
public function roles(){
return $this->belongsToMany('App\Role')->withTimestamps();
}

If I understand the scenario correctly, you should be able to access this directly from your Model's Relationship.
You can do the following to access the user's role information:
$user->roles and place this inside your loop

Related

No data fetched from associated table : Laravel

I have users and user_roles tables, and id of user_roles is used as foreign key in users. I fetched data from users using User::with('userRole')->find($user). In returned result userRole is present, however it is empty, instead it was supposed to have data from user_roles for the particular foreign key.
Please, share what can be the possible issues with the functionality or if anyone can explain working of laravel associations in brief.
/* User Model */
public function userRole()
{
return $this->belongsTo('App\UserRole');
}
/* UserRole Model */
public function user()
{
return $this->hasMany('App\User');
}
Thank You,
Many to many relationships in Laravel often require you to have 2 models and 3 tables. One to many relationships require you to have 2 models and 2 tables. One to one relationship also requires you to have 2 models and 2 tables.
Many to many relationship
Let's take User and Role models, since each User can have multiple roles and one Role can be assigned to different users, you will naturally want a Many to many relationship. Now, you will need to create an intermediate table in which you will store the results, why? Because you already defined both User and Role and since it is Many to many none of those objects will have any identifier of the other one inside of them, but rather will have their own identifier in the intermediate table, and this is how Laravel fetches the relationship, it connects Models primary key with foreign key inside of the intermediate table.
One to many relationships
Let's take User and Role models again and let's say that this time, one Role can be assigned to multiple users, but one User can ONLY have 1 Role. Naturally you will have a field role_id inside of your User model and you will connect role_id from users with id from roles.
One to one relationships
Lets take User and Role models again :D Let's say you want to create a separate Role for every user, then you will have 2 models and 2 tables where your users table will have all the users and your roles table will contain id, name, user_id and now when you try to retrieve the relationship, if you define one to one laravel will return only 1 result, no matter if you have multiple same user_id on the roles table, Laravel will return only 1 role because you told him explicitly it's 1-to-1 relationship.
EDIT:
Here is an example of one to one relationship:
/* User Model */
public function userRole()
{
return $this->belongsTo('App\UserRole', 'user_role_id', 'id');
}
#Tim and #Nikola
Thank you, for your efforts mates.
However, I found the reason behind the problem. It was because the wrong naming of userRole function in User model.
I was using foreign key of user_roles as user_roles_id in users table and defined function with name of userRole in User model. This leads to ORM not found the relevant column for attaching user_roles data.
The solution is either I have to change the name of user_roles_id to user_role_id or userRole function name to userRoles. And I choose the first one and it worked fine. :)
For reference on the naming conventions of laravel please refer to Laravel - Database, Table and Column Naming Conventions?.

Eloquent hasManyThrough also get pivot table record

I have the following relation in my Users model
public function events($user_id)
{
return $this->find($user_id)->hasManyThrough('Event', 'Event_Member', 'user_id', 'id');
}
And the three tables
User
id|name|...
1 |bob |
2 |mike|
Event
id|name |location
1 |meeting|office
Event_Member
user_id|event_id|status
1 |1 |Owner
2 |1 |Guest
The hasManyThrough relationship gives me the information from the Event table, but I also need the status information from the pivot table, how can this be done?
What you have looks like a many-to-many relation rather than a has-many-through one. You have two tables connected through a pivot, not three parent-child-grandchild tables.
I would strongly suggest changing the relationship in both models. In the user model, it would look like this:
public function events()
{
return $this->belongsToMany('Event', 'event_members');
}
Note that a pivot table is typically called model1_model2 in alphabetical order - that is, event_user in this case. I assumed your pivot table is called event_members, if not just change it. Also note that I removed the user_id since the user model already knows which user it's using.
Then you can access pivot data easily, e.g. like this:
foreach ($user->events as $event) {
echo $event->pivot->status;
}

Laravel: Complicated Eloquent Relationship - hasManyThrough or belongsToMany approach?

I have three Models (Organization, User, Visit) and 4 tables (organizations, users, organization_user, visits). I'm trying to get the accumulative total of user visits for an Organization.
Organization
------------
id,
name
User
---------
id,
name
Organization_User
----------------
id,
organization_id,
user_id
Visit
--------------
id,
user_id
views
Just to clarify, there is no Organization_User model, that is just the pivot table used by User and Organization:
$organization->belongsToMany('User');
$user->belongsToMany('Organization');
I could query all the user_ids from the pivot table by group_id, and then get all the visits for each user_id, but what's the more Eloquent approach?
A User hasMany Visits and a Visit belongsTo a User. A Visit doesn't belong to an Organization.
Solved it by using whereIn(). Basically with no change to my current relationship setup...to get accumulative views I did this:
$org = Organization::find($org_id);
return DB::table('visits')->whereIn('user_id', $org->users->modelKeys())->sum("views");
The modelKeys() returns all the user ids tied to that Organization. Then I get the sum of all the views for those users.
*Note it's also important to use Organization::find and not DB::table('organization') in order to maintain the Eloquent relationship. Otherwise $organization->users will give an error.
I think you might want a 'Has Many Through' relationship like so:
class Organization extends Model
{
public function visits()
{
return $this->hasManyThrough('App\Visit', 'App\User');
}
}
Then you could call count().
Laravel 5.1 doc

Laravel get model by hasManyThrough

I have 3 classes - User, Business and BusinessRoleUser (and respective tables)
(user) id | first_name | last_name
(business) business_id | business_name
(business_role_user) user_id | business_id | role_id
I have combined the role of the user in the same table as their are multiple roles that user's can have towards a business i.e. admin, staff, etc. which are in the business_roles table.
I would like to access the Business Model through a logged in User to update fields i.e.
$business = User::find(Auth::id())->business();
$business->fill(Input::all());
$business->save();
At present in my User class I have the following (really each user will only be associated to one business):
public function business()
{
return $this->hasManyThrough('App\Business', 'App\BusinessRoleUser', 'business_id', 'user_id');
}
But If I do a simple dd(User::find(Auth::id())->business->business_name);
it throws an error
business name is undefined
It's not actually finding the business model associated to the user. I've looked at many examples of hasManyThrough but am failing to get this to work, appreciate the help!
(note user table uses id where as other tables use user_id, not sure if this is causing an issue)

How to get courses through transactions table Laravel

I want to get all users with courses through transaction table.
Here is my db structure
course
id | name | description | price
transactions
id | course_id | user_id | name | description | expires
users
id | username | email
http://laravel.io/bin/da08n
I have tried with joins but it returns the same user multiple times.
DB::table('transactions')->join('users', 'transactions.user_id', '=', 'users.id')->join('courses', 'transactions.course_id', '=', 'courses.id')->distinct()->get();
How can I achieve this with Eloquent or in an other way?
Well.
you have a table called transactions, and a table of courses. Now, each transaction is related to a course.
Pay Attention: You have one record in one table which is related to another one record in another table, this is called one-to-one relationship.
In laravel, you achieve this by using Model's relationship.
You have one model called 'Transaction', and another model which is called 'Courses".
You get, for example one record from courses table by using Cources::find($myId).
Now, if you want to get a record of transactions by relating it to courses table., you should do this (in Laravel):
In your translation model define a method called course:
public function course ()
{
$this->hasOne("course"); // course is the name of another model which should be related
}
And then you use it like this:
$result = Transaction::find($myCourseId)->course();
Though for your case, you want to get many records through matching one record of a table to the another record of another table. Well:
In Transaction model add the following method:
public function Users()
{
return $this->hasManyThrough('User', 'Course');
}
With the above method you should be able to get the Users through Course method based on transactions.
More on that, please visit:
http://laravel.com/docs/eloquent#relationships

Categories