Reputation: 339
I have a product which is imageable
Product.php
public function imageable()
{
return $this->morphTo('imageable');
}
And a vehicle that this morphs to
public function products()
{
return $this->morphMany('App\Product', 'imageable');
}
I can call it fine with $product->imageable->model
for example, if I want to get the vehicle model.
But how would I do this in a query, specifically like this:
$products = \App\Product::where('imageable_type', 'App\Vehicle')
And
$products->where($products->imageable->make, 'Ford')
That line above is pseudocode but its the principle I'm trying to achieve, is this even possible? I essentially want to be able to filter through the vehicles by Make, but that detail resides in the imageable model for the product.
Edit, after changing my query to:
if($make = request('make')){
$products->where('imageable_type', 'App\Vehicle')
->whereHas('imageable', function($query) {
$query->where('make', request('make'));
});
}
as suggested below I get the following error:
`SQLSTATE[42S22]: Column not found: 1054 Unknown column 'make' in
'where clause' (SQL: select * from `products` where
(`products`.`user_id` != 3 and `products`.`status` = 0) and `category`
= Cars and `imageable_type` = App\Vehicle and exists (select * from
`products` as `laravel_reserved_0` where `laravel_reserved_0`.`id` =
`laravel_reserved_0`.`imageable_id` and `make` = Tesla))`
When passing make as a request parameter
Thanks
Upvotes: 0
Views: 1944
Reputation: 716
try this:
\App\Product::where('imageable_type', App\Vehicle::class)
->whereHas('imageable', function($query) {
$query->where('make', 'Ford');
})->get();
in Product model add the name
for morphTo
relation:
public function imageable()
{
return $this->morphTo('imageable');
}
I think it will not work with you because there is a bug when the relation is morpTo
maybe you should do it in another way depends in what is your need:
Ex: 1
// in this way you will get all Vehicle made by ford and eager load the products, then you make some process to get all products.
$vehicles = \App\Vehicle::with('products')->where('make', 'Ford')->get();
foreach($vehicles as $vehicle) {
// I put the condition because maybe there are some vehicles without products
$productName = $vehicle->products->count() ? $vehicle->products->first()->name : '';
}
Ex: 2
\App\Product::leftJoin('vehicles', function(JoinClause $join)
{
$join->on('products.imageable_id', '=', 'vehicles.id')
->on('products.imageable_type', '=', \DB::raw("'App\\Vehicle'"));
})
->where('vehicles.make', 'Ford')
->where('products.imageable_type', App\Vehicle::class)
->get()
Upvotes: 2