Home > Back-end >  How to refresh all relations of a newly created model in Laravel?
How to refresh all relations of a newly created model in Laravel?

Time:01-28

I have two models with a 1:1 relationship named User and UserProfile respectively.

class User extends Model
{
    protected $with = ['profile'];

    public function profile(): HasOne
    {
        return $this->hasOne(UserProfile::class);
    }
}
class UserProfile extends Model
{
    protected $touches = ['user'];

    public function user(): BelongsTo
    {
        return $this->belongsTo(User::class);
    }
}

After I create new records with these models and associate them, I should call the refresh() method (according to Laravel's Docs) in order to reload the model and all of it's relations. But somehow this doesn't work.

$user = new User($userData);
$profile = new UserProfile($profileData);

$user->save();

$user->profile()->save($profile);

$user->refresh();

$user->relationLoaded('profile'); // <-- This will be false

// $user = User::find($user->id); // <-- This will work
// $user->load('profile');        // <-- This will work

return response()->json(['data' => $user], 201);

Because the profile relation is not loaded, it will not be serialized and therefore it won't appear in JSON response.

I want to know if I'm doing anything wrong or is it a bug?

CodePudding user response:

Imo, it is the expected behaviour. If you check your code, you are never loading the profile relationship in your $user object so it explains why:

$user->relationLoaded('profile'); // false

If you access the relationship as a property (after you update the profile) it will just then fetch the relationship:

$profileImage = $user->profile; // not null

The same should happen if you already have the relationship loaded:

$user = new User($userData);
$user->save();
$currentProfile = $user->profile; // null

$profile = new UserProfile($profileData);
$user->profile()->save($profile);

$user->refresh();

$currentProfile = $user->profile; // not null

From the docs:

The save and saveMany methods will persist the given model instances, but will not add the newly persisted models to any in-memory relationships that are already loaded onto the parent model. If you plan on accessing the relationship after using the save or saveMany methods, you may wish to use the refresh method to reload the model and its relationships: (...)

CodePudding user response:

Laravel Doc's forgot to mention that the relationship must be previously loaded for that trick.

$trick = $post->comments;
$post->comments()->save($comment);
$post->refresh();

The save method not load nothing. You could use load method after save.

$user->profile()->save($profile);
$user->load('profile');
  •  Tags:  
  • Related