I have a comments table that have comments of articles, recipes and products. So its a polymorphic relation. I have two columns rel_id and rel_type in my comments table those are being used for this relation.
Now in my Comment.php I have following relation
public function rel()
{
$this->morphTo();
}
And in my other all classes I have following
public function comments()
{
return $this->morphMany('App\Models\Comment', 'rel');
}
When I try to get owner of comment and all its related data I found class not found error. For example
$comments = Comment::find(1);
echo $comments->rel_type //article
Now if I want to get data of article and when I try
$comments->rel
I found article class not found. I am using namespace App\Models\Article I have searched it out I found answer given here. When I try accepted answer, nothing happens, error remains same. When I try second answer of same question, I found
Relationship method must return an object of type Illuminate\Database\Eloquent\Relations\Relation
My ultimate goal is to get comment owner data like $comments->articles->id and so on. Please guide how can I do that?
I have a blog post about this:
http://andrew.cool/blog/61/Morph-relationships-with-namespaces
There are a couple things you need to do. First, for all of your models that have comments, add the $morphClass variable to the class, e.g.:
class Photo {
protected $morphClass = 'photo';
}
class Album {
protected $morphClass = 'album';
}
Second, on the Comment class, define an array called $rel_types on your Comment class. This will be basically the inverse of what you just did, it's a mapping from short name to full class name.
class Comment {
protected $rel_types = [
'album' => \App\Album::class,
'photo' => \App\Photo::class,
];
}
Finally, define an accessor for the rel_type column. This accessor will first retrieve the column from the database ("album", "photo", etc.) and then convert it to the full class name ("\App\Album", "\App\Photo", etc.)
/**
* @param string $type short name
* @return string full class name
*/
public function getRelTypeAttribute($type)
{
if ($type === null) {
return null;
}
$type = strtolower($type);
return array_get($this->rel_types, $type, $type);
}
Note: $morphClass is something Laravel actually defines, so it has to be named that. $rel_types can be named anything you want, I just based it off of the rel_type column you have.
To make this even better, add that getRelTypeAttribute method to a trait so that any model that morphs can reuse that trait and method.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With