Skip to content
Advertisement

Laravel Eloquent setting a default value for a model relation?

I have two models:

class Product extends Eloquent {

    ...

    public function defaultPhoto()
    {
        return $this->belongsTo('Photo');
    }

    public function photos()
    {
        return $this->hasMany('Photo');
    }
}

class Photo extends Eloquent {

    ...

    public function getThumbAttribute() {
        return 'products/' . $this->uri . '/thumb.jpg';
    }

    public function getFullAttribute() {
        return 'products/' . $this->uri . '/full.jpg';
    }

    ...

}

This works fine, I can call $product->defaultPhoto->thumb and $product->defaultPhoto->full and get the path to the related image, and get all photos using $product->photos and looping through the values.

The problem arises when the product does not have a photo, I can’t seem to figure out a way to set a default value for such a scenario.

I have tried doing things such as

public function photos() 
{
    $photos = $this->hasMany('Photo');
    if ($photos->count() === 0) {
        $p = new Photo;
        $p->url = 'default';
        $photos->add($p);
    }

    return $photos;
}

I have also creating a completely new Collection to store the new Photo model in, but they both return the same error:

Call to undefined method IlluminateDatabaseEloquentCollection::getResults()

Has anyone done anything similar to this?

Thanks in advance!

Advertisement

Answer

You could create an accessor on the Product model that did the check for you. Works the same if you just wanted to define it as a method, also (good for if you want to abstract some of the Eloquent calls, use an interface for your Product in case you change it later, etc.)

/**
 * Create a custom thumbnail "column" accessor to retrieve this product's
 * photo, or a default if it does not have one.
 * 
 * @return string
 */
public function getThumbnailAttribute()
{
    $default = $this->defaultPhoto;

    return ( ! is_null($default))
        ? $default->thumb
        : '/products/default/thumb.jpg';
}

You might also want to look into Presenters. A bit overkill for some situations, but incredibly handy to have (and abstract things like this away from your models).

User contributions licensed under: CC BY-SA
4 People found this is helpful
Advertisement