How to add a where() statement to a morphTo()
Hi, I have setup a polymorphic relationship. In my Feature.php I have
/**
* Get the model to be featured
*/
public function featureable()
{
return $this->morphTo();
}
One of the models I can morph to is a post. What if I only want to grab the Post models that have a status of 'p'. I tried doing
return $this->morphTo()->where('status', 'p');
but it didn't return it correctly.
Damn so fast! This is perfect. Thanks!!
@michaloravec I might have been a bit too fast. I tried
return Section::first()->featured()->whereHasMorph(
'featureable',
[Listing::class],
function (Builder $query) {
$query->where('status', 'like', 'p');
}
)->get();
In my section.php I have
public function featured()
{
return $this->belongsToMany(Feature::class)->withPivot('order')->orderBy('order', 'ASC');
}
and in my feature.php I have
public function featureable()
{
return $this->morphTo();
}
but I get an error message
Argument 1 passed to App\Http\Controllers\Curated\CommunityController::App\Http\Controllers\Curated\{closure}() must be an instance of App\Http\Controllers\Curated\Builder, instance of Illuminate\Database\Eloquent\Builder given, called in /Users/chrisgrim/code/ei/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Concerns/QueriesRelationships.php on line 222
Remove Builder from that function
return Section::first()->featured()->whereHasMorph('featureable',
[Listing::class],
function ($query) {
$query->where('status', 'like', 'p');
})->get();
Or import proper class.
Everything is in the documentation...
Ahh ok I need to read up on builders more
@michaloravec Sorry to keep bothering you but I feel like I am learning and understanding it more. I did some more testing and see that only
Section::first()->featured()->whereHasMorph(
'featureable',
[Listing::class, Event::class],
function ($query) {
$query->where('status', 'like', 'p');
}
)->get();
works because it is a single section. However if I do
return $community->sections()->featured()->whereHasMorph(
'featureable',
[Listing::class, Event::class],
function ($query) {
$query->where('status', 'like', 'p');
}
)->get();
it doesn't work because I am grabbing multiple sections. I would need to do something like
$community->sections()->with('featured')
Which makes me think I need to at the whereHasMorph into my feature model and call it like
$community->sections()->with('featured.liveFeatured')
and then in my feature.php have
public function liveFeatured()
{
return $this->whereHasMorph(
'featureable',
[Listing::class, Event::class],
function ($query) {
$query->where('status', 'like', 'p');
}
);
}
but I am getting a Call to undefined method Illuminate\Database\Eloquent\Builder::addEagerConstraints()
liveFeatured is not a relationship, only relationships could be eager loaded.
Sorry @michaloravec I just figured it out
public function liveFeatured()
{
return $this->morphTo()->whereHasMorph(
'featureable',
[Listing::class, Event::class],
function ($query) {
$query->where('status', 'like', 'p');
}
);
}
Thanks again for all your help!
@michaloravec Again I spoke to soon. If I do
public function liveFeatured()
{
return $this->morphTo()->whereHasMorph(
'featureable',
[Listing::class, Event::class],
function ($query) {
$query->where('status', 'like', 'p');
}
);
and then
$sections = $community->sections()->with('featured.liveFeatured')->get();
it returns
{
"id": 1,
"user_id": 1,
"container_type": "App\Models\Curated\Community",
"container_id": 1,
"name": "Section1",
"order": 0,
"created_at": "2021-08-12T22:23:32.000000Z",
"updated_at": "2021-08-12T22:23:53.000000Z",
"featured": [
{
"id": 1,
"user_id": 1,
"type": "l",
"featureable_type": "App\Models\Curated\Listing",
"featureable_id": 1,
"created_at": "2021-08-12T22:26:00.000000Z",
"updated_at": "2021-08-12T22:26:00.000000Z",
"pivot": {
"section_id": 1,
"feature_id": 1,
"order": 0
},
"featureable": {
"id": 1,
"slug": "this-is-a-listing-1",
"name": "This is a listing",
"blurb": "swzszsxxs",
"community_id": 1,
"user_id": 1,
"largeImagePath": null,
"thumbImagePath": null,
"status": "d",
"order": 0,
"created_at": "2021-08-12T22:26:00.000000Z",
"updated_at": "2021-08-12T22:26:00.000000Z"
},
"live_featured": null
},
as you can see the featureable has a status of 'd' but it is still being returned.
Would this not work, like any other relation query??
$sections = $community->sections()->with(['featured.liveFeatured' => function ($q) {
$q->where('status', 'like', 'p'); // Is this your intention? Or
$q->where('status', 'p');
}])->get();
Hi @jaytee I actually just got it figured out. I was adding it to the wrong model. Instead of adding it to my featured model I had to add it to my sections model
//Section.php
public function publicFeatured()
{
return $this->belongsToMany(Feature::class)->withPivot('order')->orderBy('order', 'ASC')->whereHasMorph(
'featureable',
[Listing::class, Event::class],
function ($query) {
$query->where('status', 'like', 'p');
}
);
}
Please or to participate in this conversation.