Order by related table column - laravel

I have a query like:
$users = User::with('role')
->get();
How can I order the results by the related table, so it's something like:
$users = User::with('role')
->orderBy('role.id', 'DESC')
->get();
Is there a way to do it without joining the role table (since we're already doing with('role')?

what are you trying to order. the list of users or the roles.
if you are trying to sort the users base on role do.
$users = User::with('role')->orderBy('role_id', 'DESC')
->get();
if you are trying to sort the roles of the user then pocho's answer is correct.
$users = User::with(array('role' => function($query)
{
$query->orderBy('id', 'DESC');
}))->get();

From the documentation:
$users = User::with(array('role' => function($query)
{
$query->orderBy('id', 'DESC');
}))->get();
You can also do a raw query using DB::raw like in the examples here.

You can always sort the returned collection quite easily...
$users = User::with('role')
->get()
->sortBy(function($user, $key)
{
return $user->role->id;
});
This is assuming a user hasOne or belongsTo a role. If your relationship is something that can return multiple roles, then it becomes a bit more complex because you need to decide which of the user's roles to sort by.

Related

Eloquent Get Models based on fields in related tables

I have multiple Models related to my User model(eg: profiles, addresses, orders,...etc)
I want to get all the users that were updated in the past 24 hours, based on the update_at field in each of the related tables accordingly.
I have found the following if u have one related table, but in my case I have more than 3 tables that I need to check:
$users = User::with('orders')
->where('updated_at', $valueA)
->whereHas('orders', function($query)
{
$query->where('updated_at', $valueB);
})->get();
I hope someone can help me to know how to apply this for multiple where clauses n=on multiple related tables.
Try the below code,
$users = User::with(['profiles', 'addresses', 'orders'])
->whereDate('updated_at','>', $yesterdayDate)
->orWhereHas('orders', function($query) use ($yesterdayDate){
$query->whereDate('updated_at','>', $yesterdayDate);
})->orWhereHas('addresses', function($query) use ($yesterdayDate) {
$query->where('updated_at','>', $yesterdayDate);
})->orWhereHas('profiles', function($query) use ($yesterdayDate){
$query->where('updated_at','>', $yesterdayDate);
})->get();
If you have direct relation from users to all models like orders, profiles, addresses etc then you can try this.
$valueA = $time // whatever time you want
$users = User::
where('updated_at', $valueA)
->whereHas('orders', function($query) use ($valueA)
{
$query->where('updated_at', $valueA);
})
with('orders')
->whereHas('profiles', function($query) use ($valueA)
{
$query->where('updated_at', $valueA);
})
with('profiles')
->whereHas('addresses', function($query) use ($valueA)
{
$query->where('updated_at', $valueA);
})
with('addresses')
->get();
Thank you.

Laravel Eloquent Relationship For Multiple tables

There is 3 tables in my database: Users, Biodata, Roles.
Users and Roles are in relation with Pivot table role_user.
Users have role student & employer.
I want all the users with role student also with biodata.
I tried many times but couldnot find the solution. Hope you guys help me
$users = User::with('roles')->with('biodata')->get();
try this:
$users = User::with('biodata')->whereHas('roles', function($query) {
$query->where('name', 'student');
})->get();
Use whereHas , which is used to where query in realtion.
$users = User::whereHas('roles', function ($query) {
$query->where('name', '=', 'student');
})->with('biodata')->get();
You're looking for this: $user = User::with('roles', 'biodata')->get();

Sort Users based on specific Value(string) in Laravel

I want to sort users based on the specific value. For example I have Users table and has relation with Profiles Table. In the Profiles table I have saved Country (string) of the user.
Now I want to sort specific country users first and then the other country Users.
Please guide me how can I do this in Laravel.
Thanks
You can play with that code.
$users = Users::with(['profiles' => function ($query) {
$query->where('country', 'USA');
$query->orWhere('country', 'Poland')
}])->get();
I have not check this but You may try this solution. It will help you.
$users = Users::with(['profiles' => function ($query) {
$query->orderBy("country='your country name'", 'DESC')
$query->orderBy('country', 'ASC')
}])->get();
You can use this
$users = Users::with(['profiles' => function ($query) use($country) {
$query->orderBy(DB::raw('case when country="'.$country.'" then 1 else 2 end'))->orderBy('country', 'ASC');
}])->get();

How to sort users by max number of posts in Laravel

I want to sort all my users by the number of their posts. Like:
User1(100 posts)
User2(90 posts)
User3(80 posts)
How can I do this in laravel elequont relationship.
Use withCount to get the posts count without loading the relationship and sort the result using posts_count. You can also apply additional conditions if required. As a bonus you get the posts count with each user.
$users = User::withCount('posts')
->orderBy('posts_count', 'desc')
->get();
Try this :
$data = User::select(DB::raw('users.*, count(*) as total_posts'))
->join('posts', 'users.id', '=', 'posts.user_id')
->groupBy('user_id')
->orderBy('total_posts', 'desc')
->get();
You can do it like this :
$users = User::with('posts')->get()-
>sortBy(function($users)
{
return $users->posts->count();
});

Eloquent User Where Clause with Entrust Library

I'm trying to select all users for a company. But only users who has "admin" role status (Entrust, etc.).
User::where('company_id', Auth::user()->company_id)->hasRole('admin')->get();
The above is throwing an error. Left a bit lost on how to run such a query. Where am I going wrong with this? Very little documentation on Entrust.
You can use plain Eloquent for this. The whereHas method would generate one query:
$users = User::where('company_id', Auth::user()->company_id)
->whereHas('roles', function($query) {
$query->where('name', 'admin');
})->get();
Or, you can just get the roles and then get all of that role's users. This would generate two queries, but ultimately achieve the same thing.
$users = Role::where('name', 'admin')
->first()
->users()
->where('company_id', Auth::user()->company_id)
->get();
Think you need to get all the users having the company_id first
$users = User::where('company_id', Auth::user()->company_id)->get();
Then loop through $users and check hasRole()
foreach ($users as $user) {
if($user->hasRole('admin')){
//user is admin
}
}
UPDATE
This might be a dirty solution but you can try to do a manual query
$admin = DB::table('role_user')
->join('users', 'users.id', '=', 'role_user.user_id')
->join('roles', 'roles.id', '=', 'role_user.role_id')
->where('roles.name', 'admin')->get();

Resources