Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create dynamic Laravel accessor

I have a Product model and also an Attribute model. The relationship between Product and Attribute is many to many. On my Product model I am trying to create a dynamic accessor. I am familiar with Laravel's accessors and mutators feature as documented here. The problem I am having is that I do not want to create an accessor every time I create a product attribute.

For example, A product may have a color attribute which could be setup like so:

/**
 * Get the product's color.
 *
 * @param  string  $value
 * @return string
 */
public function getColorAttribute($value)
{
    foreach ($this->productAttributes as $attribute) {
        if ($attribute->code === 'color') {
            return $attribute->pivot->value;
        }
    }

    return null;
}

The product's color could then be accessed like so $product->color. If I where to add a size attribute to the product I would need to setup another accessor on the Product model so I could access that like so $product->size.

Is there a way I can setup a single "dynamic" accessor to handle all of my attributes when accessed as a property?

Do I need to override Laravel's accessor functionality with my own?

like image 708
Denis Priebe Avatar asked Nov 22 '17 16:11

Denis Priebe


2 Answers

Yes, you can add your own piece of logic into the getAttribute() function of the Eloquent Model class (override it in your model), but in my opinion, it's not a good practice.

Maybe you can have a function:

public function getProductAttr($name)
{
    foreach ($this->productAttributes as $attribute) {
        if ($attribute->code === $name) {
            return $attribute->pivot->value;
        }
    }

    return null;
}

And call it like this:

$model->getProductAttr('color');
like image 142
Laraleg Avatar answered Nov 17 '22 09:11

Laraleg


Override Magic method - __get() method.

Try this.

public function __get($key)
{
    foreach ($this->productAttributes as $attribute) {
        if ($attribute->code === $key) {
            return $attribute->pivot->value;
        }
    }

    return parent::__get($key);
}
like image 5
Abid Raza Avatar answered Nov 17 '22 08:11

Abid Raza