17

Is there any possible way to lazy load a custom attribute on a Laravel model without loading it every time by using the appends property? I am looking for something akin to way that you can lazy load Eloquent relationships.

For instance, given this accessor method on a model:

public function getFooAttribute(){
    return 'bar';
}

I would love to be able to do something like this:

$model = MyModel::all();
$model->loadAttribute('foo');

This question is not the same thing as Add a custom attribute to a Laravel / Eloquent model on load? because that wants to load a custom attribute on every model load - I am looking to lazy load the attribute only when specified.

I suppose I could assign a property to the model instance with the same name as the custom attribute, but this has the performance downside of calling the accessor method twice, might have unintended side effects if that accessor affects class properties, and just feels dirty.

$model = MyModel::all();
$model->foo = $model->foo;

Does anyone have a better way of handling this?

2 Answers 2

32

Is this for serialization? You could use the append() method on the Model instance:

$model = MyModel::all();
$model->append('foo');

The append method can also take an array as a parameter.

Sign up to request clarification or add additional context in comments.

5 Comments

Hey thanks, this is exactly what I was looking for! I'm glad Laravel has a native way to handle this. I think they only mention appends in the docs (and not the singular append) which is why I had never heard of this one.
There is a lot of cool methods I didn't know about. Diving into the Model code is very instructive and I highly recommend it to you to find great tools :)
This doesn't work as described. The append() method belongs to the Model class, but when you call MyModel::all() you're getting back a Collection object, which does not contain the append() method. You'd have to write: $model->each(function($instance) { $instance->append('foo'); });
Everytime I find my answer answered on stack, I try to find the answer in documentation too, so I get better skills in going through the documentation. For this matter I found the answer here laravel.com/api/8.x/Illuminate/Database/Eloquent/…
@Soulriser, the append method is available on the eloquent collection instance, which is what the all() returns. It is similar to the ` makeVisible()` or ` makeHidden()` method.
0

Something like this should work...

public function loadAttribute($name) {
    $method = sprintf('get%sAttribute', ucwords($name));
    $this->attributes[$name] = $this->$method();
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.