Laravel - Select relation columns - laravel

I am trying to write a query which selects columns from a model then selects one column from a relationship table.
Team Model
public function members(){
return $this->hasManyThrough('App\User', 'App\Membership', 'team_id', 'id', 'id', 'user_id');
}
Member(user) model
public function skills()
{
return $this->belongsToMany('App\Skill');
}
Function
Query i have attempted but had no luck:
$members = $this->team->members()
->select('id', 'name')
->with(['skills' => function ($query) {
$query->select('name');
}])
->get();
dump of query
When i dump the query it returns just the data for the id and name columns from the team table but the skills relation returns back empty when i want it to return the name from that table.
#relations: array:1 [▼
"skills" => Illuminate\Database\Eloquent\Collection {#1657 ▼
#items: []
}
]
How would do i grab the name column from the skills relation table within this query?

To select column in relation you can use this :
->with('members.skills:id,name')
If you're not passing id attribute inside the with, the relation can't work

You need to add the id to the fields returned from the skills table. Otherwise Eloquent has no way to link the skill to the correct team.
->with(['skills' => function ($query) {
$query->select('id', 'name');
}])

Related

How to select specific column from parent and child in laravel

Please see my code below.
Controller
$orders = Order::with('product:id,name')
->select([
'id',
'order_number',
'ordered_on',
'status',
'total'
])
->where('customer_id', session('customer_id'))
->orderBy('ordered_on', 'DESC')
->paginate(6);
dd($orders);
Order model
public function product()
{
return $this->belongsTo(Product::class);
}
The result above returns null when you check the product relationship data.
What I need
Select specific columns from Order model, then select specific columns from product relationship.
You need to add the foreign key that you are referencing:
->select([
'product_id'
...
])
...
When using this feature, you should always include the id column and any relevant foreign key columns in the list of columns you wish to retrieve.
Docs: https://laravel.com/docs/9.x/eloquent-relationships#eager-loading-specific-columns

How to query count on the pivot table in Laravel eloquent

I have two data tables in database. One is user table, other one is property table. User can save as many properties as they want. Also, one property can be save by multiple users. So there is a pivot table which has the property_id and user_id in it for a record. Now I want to query the popular properties. All properties that is saved by more than 100 users are popular properties. How would I do that? Something like I am doing
public function popularProperties(Request $request)
{
$id = $request->id;
return Property::where('saved'->count(),'>',100)->with([
'paymentPlan' => function ($query){
$query->select('property_id','all_in_one_go','down_payment','minimum_installment_per_month');
},
'city',
'propertyType' => function ($query){
$query->select('id','name');
},
'user' => function ($query){
$query->select('id','name','email');
},
'images' => function($query){
$query->select('imageable_id','url');
}
])->withCount('likes')->get();
}
The following code selects all property's with > 100 count. Inside the whereIn is a subquery that selects all property IDs that exist > 100 times. Note that you have to fill in the correct Table and column names
$propertys = Property::whereIn('id', function ($q){
$q->select('property_id')
->from('user_property')
->groupBy('property_id')
->havingRaw('COUNT(*) > 100');
})->get();

I want to change my laravel database query to model relationship query for search data from database

I am learning laravel Eloquent relationship, I successfully created a relationship between models for eq city belongsTo State and belongsTo country.
public function state(){
return $this->belongsTo(State::class,'state_id', 'sr_id');
}
public function country(){
return $this->belongsTo(Country::class,'country_id', 'sr_id');
}
this is my old search code, I want to know how we search data using model relationship method, how we call each columns from their following table.
$city = city::leftjoin('master_country','master_country.sr_id','=','master_city.country_id')
->leftjoin('master_state','master_state.sr_id','=','master_city.state_id')
->where('master_city.sr_status',0)
->where('master_city.sr_id','LIKE','%'.$query.'%')
->orWhere('master_city.sr_name','LIKE','%'.$query.'%')
->orWhere('master_city.city_tel_code','LIKE','%'.$query.'%')
->orWhere('master_country.sr_name','LIKE','%'.$query.'%')
->orWhere('master_state.sr_name','LIKE','%'.$query.'%')
->orderBy('master_city.sr_id')
->paginate(3,array('master_city.*','master_country.sr_name AS c_name','master_state.sr_name As s_name'));
so it would we like..
City::with('state','country')->where etc
You can have a look at Constraining Eager Loads
$cities = City::with(
[
'state' => function ($query) {
$query->where('state_column', 'some_value');
},
'country' => function ($query) {
$query->where('country_column', 'some_value');
}
]
)->get();
If you don't want to retrieve the relation data, you can use the whereHas() method:
City::whereHas('state', fn (Builder $builder) => $builder->where('state_column', 'some_value')));
Using arrow function is not required.
More documentation on this

Access column of target table after calling relationship - Laravel

I have three tables as follows
Base Table
users
id - integer
name - string
Target Table
roles
id - integer
name - string
Pivot Table
role_user
user_id - integer
role_id - integer
Many to many relationship is exist between users and roles table
If I want all the users with role_id of '1' so I can simply do this as
$result = User::whereHas('roles', function ($q){
$q->where('roles.id', 1);
});
but I also want the role name correspond to role_id '1' which is name column of roles table.
Is there any way I can append role name into $result collection.
I think you might want to use map(). The eager loading (with()) is very important though, to prevent the N+1 issue in your query. Without eager loading one additional query would be executed for each user in your result.
$result = App\User::query()
->with([
'roles' => function ($q) {
$q->whereId(1);
}
])
->whereHas('roles', function ($q) {
$q->whereId(1);
})
->get()
->map(function ($user) {
$user['name'] = $user->roles->first()->name;
return $user;
});
You can Eagerload the relationship to get the column you want:
User::whereHas('roles', function ($q){
$q->where('roles.id', 1);
})->with(['roles' => function ($q){
$q->select('name')->where('roles.id', 1);
}])->get();

Laravel Eloquent with() selecting specific column doesn't return results

Say I have 2 models, Category and POI where 1 Category can have many POIs.
$categoryDetails = Category::with([
'pois' => function ($query) {
$query->where('is_poi_enabled', true);
},
])->findOrFail($id);
The above query returns results from the specific Category as well as its POIs.
However, with the query below:
$query->select('id', 'name')->where('is_poi_enabled', true);
The POIs become empty in the collection.
Any idea why this is happening? When added a select clause to the Eloquent ORM?
While doing a select it's required to fetch the Relationship local or Primary key.
For an example POIs table contains category_id then it's required to select it
Try this:
$categoryDetails = Category::with([
'pois' => function ($query) {
$query->select(['id', 'category_id', 'is_poi_enabled'])
->where('is_poi_enabled', true);
},
])->findOrFail($id);
Good luck!

Resources