How to conditionally override a value in an Eloquent model?

Viewed 311

I do:

Model::with('animal')->get()->each(function (&$item) {
    if (condition($item)) {
        $item->animal = 'Yop Override';
    }
})->toArray();

But I cannot override animal. Is there a way to do this?

My ugly alternative is:

array_map(function($item) {
    if (condition($item)) {
        $item['animal'] = 'Yop Override';
    }
    return $item;
}, Model::with('animal')->get()->toArray());
2 Answers

The reason why it's not working is because you are trying to overwrite a relation of the model which you cannot do by a simple assignation.

You could achieve what you want with the setRelation method:

Model::with('animal')
    ->get()
    ->each(function ($item) {
        if (true) {
            $item->setRelation('animal', 'Yop override');
        }
    })
    ->toArray();

If you want to use the map method, it would be the same thing but you would have to add a return at the end of the function.

Model::with('animal')
    ->get()
    ->map(function ($item) {
        if (true) {
            $item->setRelation('animal', 'Yop override');
        }

        return $item;
    })
    ->toArray();

In your example, you are using ->each(), you should be using ->map() and returning $item.

Secondly, you need a $key/$value inside function().

Thirdly, use the use when passing other data.

Model::with('animal')->get()->map(function ($model, $key) use (&$item) {
    if (condition($item)) {
        $item->animal = 'Yop Override';
    }
    return $item;
})->toArray();
Related