Just migrated to 4.1 to take advantage of this powerful feature. everything seems to work correctly when retrieving individual 'morphedByXxxx' relations, however when trying to retrieve all models that a particular tag belongs to -- i get an error or no results.
$tag = Tag::find(45); //Tag model name = 'awesome'
//returns an Illuminate\Database\Eloquent\Collection of zero length
$tag->taggable;
//returns Illuminate\Database\Eloquent\Relations\MorphToMany Builder class
$tag->taggable();
//returns a populated Collection of Video models
$tag->videos()->get();
//returns a populated Collection of Post models
$tag->posts()->get();
My Tag Model class loooks like this:
class Tag extends Eloquent
{
protected $table = 'tags';
public $timestamps = true;
public function taggable()
{
//none of these seem to function as expected,
//both return an instance of MorphToMany
//return $this->morphedByMany('Tag', 'taggable');
return $this->morphToMany('Tag', 'taggable');
//this throws an error about missing argument 1
//return $this->morphToMany();
}
public function posts()
{
return $this->morphedByMany('Post', 'taggable');
}
public function videos()
{
return $this->morphedByMany('Video', 'taggable');
}
}
And the Post and Video models look like this:
class Post extends Eloquent
{
protected $table = 'posts';
public $timestamps = true;
public function tags()
{
return $this->morphToMany('Tag', 'taggable');
}
}
I am able to add/remove Tags to Posts and Videos as well as retrieve the related Posts, and Videos for any Tag -- however -- what is the proper way to retrieve all Models having the Tag name 'awesome'?
Was able to figure it out, would love to hear comments on this implementation.
in Tag.php
public function taggable()
{
return $this->morphToMany('Tag', 'taggable', 'taggables', 'tag_id')->orWhereRaw('taggables.taggable_type IS NOT NULL');
}
in calling code:
$allItemsHavingThisTag = $tag->taggable()
->with('videos')
->with('posts')
->get();
I just used this on Laravel 5.2 (not sure if it is a good strategy though):
Tag model:
public function related()
{
return $this->hasMany(Taggable::class, 'tag_id');
}
Taggable model:
public function model()
{
return $this->belongsTo( $this->taggable_type, 'taggable_id');
}
To retrieve all the inverse relations (all the entities attached to the requested tag):
@foreach ($tag->related as $related)
{{ $related->model }}
@endforeach
... sadly this technique doesn't offer eager load functionalities and feels like a hack. At least it makes it simple to check the related model class and show the desired model attributes without much fear to look for the right attributes on the right model.
I posted a similar question in this other thread as I am looking for relations not known in advance.
来源:https://stackoverflow.com/questions/18669070/laravel-4-1-proper-way-to-retrieve-all-morphedby-relations