68

In Laravel, after using attach() or detach() to add or remove something from a relation, the collection has not changed. So if I have a model whose relation contains [1, 2], after this:

$model->relation()->detach(1);
$model->relation()->attach(3);

it will still contain [1, 2]! How do I refresh it?

Legionar
  • 7,472
  • 2
  • 41
  • 70
Benubird
  • 18,551
  • 27
  • 90
  • 141

7 Answers7

144

You can easily tell laravel to load a relation with a single command:

$model->load('relation');

Will tell it to refresh the relation collection, and $model->relation will now show the correct values.

Also unloading a relation will be like this:

$model->unsetRelation('relation')
Amin Shojaei
  • 5,451
  • 2
  • 38
  • 46
Benubird
  • 18,551
  • 27
  • 90
  • 141
8

From Laravel 7.x you can use $model->refresh() for refreshing the model and it's relations.

Here the docs

Giuse Petroso
  • 557
  • 6
  • 7
7

either just unset it and let the system reload on demand.

unset($model->relation)

or

$model->unsetRelation('relation');

And let it be loaded on request.

Yevgeniy Afanasyev
  • 37,872
  • 26
  • 173
  • 191
5

Conclusion: three solutions in here

$model->load('relation');

unset($model->relation);

$freshCollection = $user->roles()->get();`
Yevgeniy Afanasyev
  • 37,872
  • 26
  • 173
  • 191
kevinYang
  • 111
  • 2
  • 1
4

It is possible to use Eloquent query builder:

$freshCollection = $user->roles()->get();
James Akwuh
  • 2,169
  • 1
  • 23
  • 25
3

If you want to force all your relations to reload on an as-needed basis and you're inside your model, you can use:

$this->relations = [];
Yevgeniy Afanasyev
  • 37,872
  • 26
  • 173
  • 191
Sabrina Leggett
  • 9,079
  • 7
  • 47
  • 50
  • this is not intuitive, does it mean that every time when my relation has no items it makes a DB request? – Yevgeniy Afanasyev Aug 13 '19 at 01:09
  • 1
    yes, when you do `$user->posts` it checks the `relations` property to see if the related collection has already been retrieved. If not it'll load it from the database. – Sabrina Leggett Aug 14 '19 at 02:58
1

$model->fresh() did the job for me. Wanted to replicate multiple levels of nested models then do a loop over them. Laravel was caching the previous relation and not the new "current" relation.

Liam Mitchell
  • 1,001
  • 13
  • 23