Search code examples
phplaravel-5eloquentrelationship

Laravel : Polymorphic Relations + Accessor


I have a Gallery table that uses Polymorphic Relations so I can add Images and Videos to my gallery list.

Within the Gallery table I have a galleryable_type column that is populated with either App\Video or App\Image.

Is there a way for me to use an accessor (docs here) to change the value of galleryable_type to either video or image so I can use that column in JS to decide what gallery item type I'm dealing with?

I tried the following:

/**
 * Get and convert the makeable type.
 *
 * @param  string  $value
 * @return string
 */
public function getMakeableTypeAttribute($value)
{
    return str_replace('app\\', '', strtolower($value));
}

But i end up with the following error:

FatalErrorException in Model.php line 838:
Class '' not found

I'm assuming that has to do with the accessor is being processed before the the polymorphic relationship but I'm not sure.

I can simply use the following in my controller:

foreach (Gallery::with('galleryable')->get() as &$gallery) {

    $gallery->galleryable_type = str_replace('app\\', '', strtolower($gallery->galleryable_type ));

}

But that seems like a dodgy way of doing things. Could a Laravel guru shed some light on the best way to tackle this problem?

Thanks!


Solution

  • Well I've found an interesting way to solve this issue.

    In your models (App\Video and App\Image) you have to add:

    protected $morphClass = 'video';  // 'image' for image class
    

    then in your register method in service provider class add:

    $aliasLoader = \Illuminate\Foundation\AliasLoader::getInstance();
    
    $aliasLoader->alias('video', \App\Video::class);
    $aliasLoader->alias('image', \App\Image::class);
    

    This will cause that you will write image, and video in galleryable_type in the database instead of class names.

    So now you can easily get to this values with:

    echo $model->galleryable_type;