Laravel 5.4 adding specific column in existing selected colum with with() - php

I'm having a problem with displaying results from my db using eloquent in laravel 5.4. I just want to specify a columns that I want to be in my results. So in my case the record is relation to another tables which I want also to specify a column that I need. Please check my eloquent:
return User::with(['images' => function($q){
$q->select('user_id as userId','image_name','url');
}])
->orderBy('id', 'asc')
->select(['id as userId','name','email'])
->paginate(10);
and here's my hasMany() relations in my model:
public function images(){
return $this->hasMany('Images', 'user_id', 'id');
}
The problem with this code the images are always null.
Any idea? Thanks in advance.

Give this a try:
return User::with(['images' => function($q){
$q->select('id', 'image_name','url');
}])
->orderBy('id', 'asc')
->select(['id','name','email'])
->paginate(10);
You need to select the relationship key for it to find results.

Related

how to use groupBy in hasMany relation in Laravel

I have 2 tables that are named Resort and booking. in the booking table, there is a field named amount. I want to join these tables using with hasMany relation and get sum of the amount field in the booking table using with groupBy. can you please help me to solve this problem?
Thanks in Advance
Laravel Eloquent has the own withSum() method for avoiding "groupBy()" method.
For your case you can use something like this (you can modify for your needs):
// resorts with bookings and their summary prices
$data = Resort::select([
'id',
'name',
'image',
])
// ->orderBy('some_field', 'ASC')
->with(['bookings' => function($query) {
return $query->select([
'id',
'booking_id',
'price',
]);
}])
->withSum('bookings', 'price')
// ->where('resorts.some_field', '<=', 123)
->get();
// ->toArray();
But don't forget to have appropriate relation defined in your parent (Resort) model:
public function bookings() {
return $this->hasMany(Booking::class, 'resort_id', 'id');
}
Also you need to have "resort_id" foreign key defined in child's (Booking) migration:
$table->unsignedTinyInteger('resort_id')->nullable();
$table->foreign('resort_id')->references('id')
->on('resorts'); // ->onUpdate('cascade')->onDelete('cascade');

Convert (User,Role,user_role) SQL Raw Query to Eloquent In Laravel

Respected sir,I have to fetch user role name from user_role pivot table.
I successfully done by this using Sql Raw Query.but i have to use Eloquent.
Please convert below raw sql code into Eloquent,Please help me
sir i am new in laravel.
$role = DB::table('users')
->join('user_roles', 'users.id', '=', 'user_roles.user_id')
->join('roles', 'roles.id', '=', 'user_roles.role_id')
->select('roles.name')->where('users.id', '=',$user->id)
->get();
you could try Laravel Eloquent's manyToMany relationship. It's the same exact setup as you have here with a pivot table.
Add this method to your User model
function roles {
return $this->belongsToMany('App\Role', 'user_roles', 'user_id', 'role_id');
}
In your controller you could use
$roles = User::with('roles:name')->where('id', $user->id)->get();
Do try this method, you dont have to change anything to you db just adjust your model and controller.
For more info here's the documentation

How to add a where clause when using "with" on an Eloquent query in Laravel

I have a query built where I'm using "with" to include related models. However, I'm not sure how to filter those related models in a where clause.
return \App\Project::with("projectLeaders")->join('companies', 'company_id', '=', 'companies.id')
->join('project_status', 'project_status.id', '=', 'projects.status_id')
->select('companies.*', 'project_status.name AS statusName', 'projects.*');
Please note the with("projectLeaders") in the query. So, ProjectLeaders is a relation that brings objects of kind Employee, how can I filter in that query those "Employees" whose attribute "Lastname" is like "Smith" ?
You can implement where class both tables. Please check following code and comments.
return \App\Proyecto::with(["projectLeaders" => function($query){
$query->where() //if condition with inner table.
}])->join('empresas', 'id_empresa', '=', 'empresas.id')
->join('tipo_estado_proyecto', 'tipo_estado_proyecto.id', '=', 'proyectos.id_tipo_estado_proyecto')
->where() //if condition with main table column.
->select('empresas.*', 'tipo_estado_proyecto.nombre AS nombreEstadoProyecto', 'proyectos.*');
You can use Closure when accessing relation using with. Check below code for more details:
return \App\Project::with(["projectLeaders" => function($query){
$query->where('Lastname', 'Smith') //check lastname
}])->join('companies', 'company_id', '=', 'companies.id')
->join('project_status', 'project_status.id', '=', 'projects.status_id')
->select('companies.*', 'project_status.name AS statusName', 'projects.*');
You may use the where method on a query builder instance to add where clauses to the query. The most basic call to where requires three arguments. The first argument is the name of the column. The second argument is an operator, which can be any of the database's supported operators. Finally, the third argument is the value to evaluate against the column.
return \App\Project::with("projectLeaders")->join('companies', 'company_id', '=', 'companies.id')
->join('project_status', 'project_status.id', '=', 'projects.status_id')
->where('lastname','=','Smith')
->select('companies.*', 'project_status.name AS statusName', 'projects.*');
Don't forget to return results with a get();
The query you have written is correct. But after building the query you need to fetch the data from database.
METHOD ONE
So adding get() method to your query:
return App\Project::with('projectLeaders')
->leftJoin('companies', 'company_id', '=', 'companies.id')
->leftJoin('project_status', 'project_status.id', '=', 'projects.status_id')
->select('companies.*', 'project_status.name AS statusName', 'projects.*')
->get();
METHOD TWO (with pagination)
return App\Project::with('projectLeaders')
->leftJoin('companies', 'company_id', '=', 'companies.id')
->leftJoin('project_status', 'project_status.id', '=', 'projects.status_id')
->select('companies.*', 'project_status.name AS statusName', 'projects.*')
->paginate(3);

Laravel 5.4 Eloquent relationship query return null using ->first()

I hope anybody can help me with this.
I have the next eloquent query:
$chats = Solicitud::with(['reservation', 'detail.subDetails', 'conversation'=>function($q){
$q->orderBy('created_at', 'DESC')->groupBy('solicitud')->first();
}])
->whereIn('idSolicitud', $r)
->skip($inicio)
->take($elementos)
->orderByRaw("field(idSolicitud, ".implode(',' , $r->toArray()).")")
->get();
What I want is get the last conversation so I use ->first() to get the last. But this return conversation:[] without data, but when I change ->first() to ->get() return all the conversation I don't know what is wrong.

Laravel OrderBy Nested Collection

I'm using a Roles package (similar to entrust). I'm trying to sort my User::all() query on roles.id or roles.name
The following is all working
User::with('roles');
This returns a Collection, with a Roles relation that also is a collection.. Like this:
I'm trying to get all users, but ordered by their role ID.
I tried the following without success
maybe because 'roles' returns a collection? And not the first role?
return App\User::with(['roles' => function($query) {
$query->orderBy('roles.id', 'asc');
}])->get();
And this
return App\User::with('roles')->orderBy('roles.id','DESC')->get();
None of them are working. I'm stuck! Can someone point me in the right direction please?
You can take the help of joins like this:
App\User::join('roles', 'users.role_id', '=', 'roles.id')
->orderBy('roles.id', 'desc')
->get();
Hope this helps!
You can make accessor which contains role id or name that you want to sort by.
Assume that the accessor name is roleCode. Then App\User::all()->sortBy('roleCode') will work.
Here's the dirty trick using collections. There might be a better way to achieve this(using Paginator class, I guess). This solution is definitely a disaster for huge tables.
$roles = Role::with('users')->orderBy('id', 'DESC')->get();
$sortedByRoleId = collect();
$roles->each(function ($role) use($sorted) {
$sortedByRoleId->push($role->users);
});
$sortedByRoleId = $sortedByRoleId->flatten()->keyBy('id');
You can sort your relations by using the query builder:
notice the difference with your own example: I don't set roles.id but just id
$users = App\User::with(['roles' => function ($query) {
$query->orderBy('id', 'desc');
}])->get();
See the Official Laravel Docs on Constraining Eager Loading
f you want to order the result based on nested relation column, you must use a chain of joins:
$values = User::query()->leftJoin('model_has_roles', function ($join)
{
$join>on('model_has_roles.model_id', '=', 'users.id')
->where('model_has_roles.model_type', '=', 'app\Models\User');})
->leftJoin('roles', 'roles.id', '=', 'model_has_roles.role_id')
->orderBy('roles.id')->get();
please note that if you want to order by multiple columns you could add 'orderBy' clause as much as you want:
->orderBy('roles.name', 'DESC')->orderby('teams.roles', 'ASC') //... ext
check my answer here:
https://stackoverflow.com/a/61194625/10573560

Categories