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).