That would be hard to do and ambiguous because you would get a collection of mixed models.
Hi Rickshawhobo,
Thanks for your answer but the morphTo in a 1:n Polymorphic relation returns a collection of mixed models. I'm just looking for a way to do this in a n:n Polymorphic relation.
Thanks.
In a 1 to many, the morphTo returns the parent. Read the documentation again.
Retrieving The Owner Of A Polymorphic Relation
However, the true "polymorphic" magic is when you access the staff or order from the Photo model:
$photo = Photo::find(1);
$imageable = $photo->imageable;
The imageable relation on the Photo model will return either a Staff or Order instance, depending on which type of model owns the photo.
rickshawhobo said:
That would be hard to do and ambiguous because you would get a collection of mixed models.
If those models adhered to an interface then it wouldn't be any issue. I'm needing this same functionality where I need all the different models associated to that tag.
I'm confused because there's a github issue that seems to reference this exact functionality dating back to 2013, and Taylor said it was implemented, but I don't see any examples of it. Or maybe I misunderstood the original posters outcome.
I searched and searched and searched and could not find an answer to this question, but I do have a solution (which has it's own shortcomings).
For your example above add the following to your Tags class.....
protected $with = ['posts','videos'];
public function imageable ()
{
return collect ($this->getRelations())->collapse();
}
My thinks is as follows.........
protected $with = ['posts','videos'];
will eager load your relations so that
$tag = Tag::find(3);
will eager load all the relations for that model that has id=3. Normally they will only be loaded when you make the call to
$tag->posts;
then
return collect ($this->getRelations())->collapse();
will get all the related models (an 'array' of post collection and video collection), turn the array into a collection itself and then collapse the collection down to a single level collection of a mixture of Post models and Video models.
array
collection
Post
Post
Post
collection
Video
Video
becomes.....
collection
Post
Post
Post
Video
Video
So your call on the model would be
$tag = Tag::find(3);
$all = $tag->imageable(); // remember the method call"()"
Someone out there who is a lot smarter than me will no doubt be able to explain that this may cause extra SQL calls but for me it works and I hope this can help someone.
Thank you to pfbernardo for asking the question. "... to get all related models, the same way as I can with morphTo.' is what he wanted and I think this can give him that.
Hello ghkdev,
you found a very clever solution to this problem, thanks a lot for your hints.
I am also facing it and the best solution I found was yours. Still there is one more thing that I may use your help with: how would you paginate/simple paginate the query in this scenario? Do you even think this might be possible?
Best regards, Federico
I changed ghkdev's code little bit:
public function taggables()
{
$all[] = $this->posts;
$all[] = $this->videos;
return collect(array_collapse($all));
}
Avoiding $with property and getting related models manually, we can get related models when we run taggables() method. I may be wrong in some cases because I am not pro in Laravel world. Any corrections or better suggestions are strongly appreciated!
Sign in to participate in this thread!
The Laravel portal for problem solving, knowledge sharing and community building.
The community