Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get data from polymorphic relations with namespaces

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?

like image 884
user1272333 Avatar asked Feb 20 '26 00:02

user1272333


1 Answers

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.

like image 194
andrewtweber Avatar answered Feb 21 '26 13:02

andrewtweber



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!