Retrieve grouped relation with Eloquent ORM - laravel

I have a relationship which looks like this:
User
- id
Menu
- id
- appetizer_id
- main_course_id
- dessert_id
User_Menu
- user_id
- menu_id
and corresponding models:
class User
{
public function menus()
{
return $this->belongsToMany('App\Models\Menu', 'user_menu', 'user_id', 'menu_id');
}
}
class Menu
{
public function dessert()
{
return $this->belongsTo('App\Models\Dessert', 'dessert_id');
}
}
In other words there are users and menus with a many to many relationship. Now I would like to retrieve all the distinct desserts for a given user. I've tried using group by, but it does not allow me to select and group by a single column, because the pivot columns are always included in the query:
$desserts = User::find(1)->menus()
->select('dessert_id')
->groupBy('dessert_id')
->with('dessert')
->get();
throws the following error:
'User_Menu.user_id' isn't in GROUP BY

$desserts = User::join('User_Menu', 'User.id', '=', 'User_Menu.user_id')
->join('Menu', 'User_Menu.menu_id', '=','Menu.id')
->get();

Related

Laravel: Get all projects and check if user has liked them

I want to get all projects, and foreach project I want to get a property for example is_liked which indicates that if the current_user (I've his Id) has liked this project or not.
User Model
class User extends Model
{
public function projects()
{
return $this->hasMany(Project::class);
}
public function favorite_projects()
{
return $this->belongsToMany(Project::class, 'favorite_projects', 'user_id', 'project_id')->withTimestamps();
}
}
Project Model
class Project extends Model
{
public function user()
{
return $this->belongsTo(User::class);
}
}
User Table
- id
- name
Project Table
- id
- user_id
- title
favorite_projects table
- user_id
- project_id
What is the best way to get this done ? the data I want to get is something like this:
[
{
"id": 1,
"user_id": 3,
"title": "my title",
"is_liked": true
}
]
Note: the current_user->id might or might not be same as the project->user_id.
$projects = DB::table('projects')
->join('favorite_projects', 'favorite_projects.project_id', '=', 'projects.id')
->select('projects.*', 'favorite_projects.*')
->where('projects.user_id', Auth::id())
->get();
This join statement allows you to join 2 tables together and for each project that is being favorited by the user, you will see the favorite record attached with the record.
Perform a dd($projects) after that SQL query and see what the result is like, and then for each result, you set $project['is_liked'] accordingly.

Laravel 5.2 Eloquent ORM to get data from 3 tables

I have the following tables. users, user_details and client_teams. Each user has one details and each user can have many teams. schema for users:
id, name, email,parent_user_id
user_details:
id, user_id, client_team_id
client_teams:
id, user_id, team_name,status
In user_model i have the following relations:
public function userDetails(){
return $this->belongsTo('App\Models\UserDetails','id','user_id');
}
public function clientTeamList(){
return $this->hasMany('App\Models\ClientTeams','user_id','id');
}
In user_details model i have the following relation:
public function clientMemberTeam(){
return $this->belongsTo('App\Models\ClientTeams','client_team_id');
}
I want to be show the list of users who have a specific team ID and created by a specific user. The query that i am using is this:
$userCollections=Users::where([
['users.status','!=','DELETE'],
['users.parent_user_id',$clientId],
['users.id','!=',$loginUser->id]
])
->with([
'userDetails'=>function($query) {
$query->where('client_team_id',1);
}
]);
This is giving me all records for this user, Whereas i want to match by client_team_id and user_id
You need to use whereHas and orWhereHas methods to put "where" conditions on your has queries.
Please look into https://laravel.com/docs/8.x/eloquent-relationships
$userCollections = Users::where([['users.status', '!=', 'DELETE'],
['users.parent_user_id', $clientId],['users.id', '!=', $loginUser->id]
])
->whereHas('userDetails' => function ($query) {
$query->where('client_team_id', 1);
})->get();

Get only one column from relation

I have found this: Get Specific Columns Using “With()” Function in Laravel Eloquent
but nothing from there did not help.
I have users table, columns: id , name , supplier_id. Table suppliers with columns: id, name.
When I call relation from Model or use eager constraints, relation is empty. When I comment(remove) constraint select(['id']) - results are present, but with all users fields.
$query = Supplier::with(['test_staff_id_only' => function ($query) {
//$query->where('id',8); // works only for testing https://laravel.com/docs/6.x/eloquent-relationships#constraining-eager-loads
// option 1
$query->select(['id']); // not working , no results in // "test_staff_id_only": []
// option 2
//$query->raw('select id from users'); // results with all fields from users table
}])->first();
return $query;
In Supplier model:
public function test_staff_id_only(){
return $this->hasMany(User::class,'supplier_id','id')
//option 3 - if enabled, no results in this relation
->select(['id']);// also tried: ->selectRaw('users.id as uid from users') and ->select('users.id')
}
How can I select only id from users?
in you relation remove select(['id'])
public function test_staff_id_only(){
return $this->hasMany(User::class,'supplier_id','id');
}
now in your code:
$query = Supplier::with(['test_staff_id_only:id,supplier_id'])->first();
There's a pretty simple answer actually. Define your relationship as:
public function users(){
return $this->hasMany(User::class, 'supplier_id', 'id');
}
Now, if you call Supplier::with('users')->get(), you'll get a list of all suppliers with their users, which is close, but a bit bloated. To limit the columns returned in the relationship, use the : modifier:
$suppliersWithUserIds = Supplier::with('users:id')->get();
Now, you will have a list of Supplier models, and each $supplier->users value will only contain the ID.

Laravel many to many relationship with pivot table

if I try the following the page is loading endless:
$user_departments = User::find(1)->departments();
There are the following tables:
- users
- user_department
- departments
The pivot table user_department has got this two foreign keys:
- department_id
- user_id
In my user model:
public function departments()
{
return $this->belongsToMany('App\Department', 'user_department', 'user_id', 'department_id')->withTimestamps();
}
In my department model:
public function users()
{
return $this->belongsToMany('App\User', 'user_department', 'department_id', 'user_id')->withTimestamps();
}
By the way: The following code is working:
$user->departments()->syncWithoutDetaching($department->id);
But I can't get the departments of the user without breaking my page.
Any ideas?
When fetching the departments of a user. You should actually get() the results. With $user->departments() you are getting the query builder which isn't a collection of results.
Alternatively of using the get() method ($user->departments()->get()) You could use a shortcut: $user->departments.
Use below syntax to get user departments :
$user->departments;
to insert :
$user->departments()->attach($department->id);
to remove :
$user->departments()->detach($department->id);
and for sync :
$arr=array(13,25,12);
$user->departments()->sync($arr);

How to get user's menu that has active modules in Laravel 4 with Eloquent?

I have tables to store user's menu like below:
Table: modules
id
name
status (will have values: active / inactive)
Table: menus
id
module_id
link
Table: menu_user
user_id
menu_id
join
Table: users
id
name
password
The relationship will be like:
[users]-<menu_user>-[menus]-[modules]
Modules has many Menus; and relationship between Users and Menus is many to many.
I only can get user's menu:
$data = User::with('menus')->where('id', 2);
Any how with Eloquent way that I want to have the users's menu where the modules has active status?
Another approach would be to come from the User end and use a nested relationship to the module, eg.
User::where('users.id', 1)
->with(array('menus.module' => function($query) {
$query->where('modules.status', '=', 'active');
})
)->get();
This is dependent on the following in the Models:
User
public function menus()
{
return $this->belongsToMany('Menu');
}
Menu
public function module(){
return $this->belongsTo('Module');
}
Module
public function menu(){
return $this->hasMany('Menu');
}
Glen

Resources