Hi,
Eloquent does a few smart things with caching, so it doesn't fetches a fresh copy of a model all the time you reference it. However, if you do wish for such behavior you can make a call to the fresh() method.
I'm using Laravel 5.2 together with Behat. In several projects I was faced with the problem, that when I was trying to update a model or a resource within the test and then try to check to view to see if the changes actually took place, they seemingly never did. Note that all of this works as intended in the browser. It's just Behat that's acting up.
Let me give you an example. I have the following Scenario
Scenario: Editing profile
Given I am a User
And I visit the profile edit page
And I edit my profile
Then I should see my updated profile
So I edit my profile, hit submit and then I should see my changed profile, right? The problem is, that in the returned response none of the fields actually changed. It's still the same way it was before I tried to edit. I printed the response to the console and checked the Html manually. No changes at all. Here's what my controller is doing when I update the profile:
public function update()
{
$user = $this->users->currentUser();
$profile = $this->profiles->findByField('user_id', $user->id)[0];
$this->profiles->update(request()->input(), $profile->id);
return redirect()->route('users.own-profile');
}
Note: I'm using the repository pattern here but I've had the exact same problem in another project where I'm just using the facades directly in the controller.
Now here's what I noticed. Look at my code that returns the actual profile page (not the edit page):
public function showOwn()
{
$user = $this->users->currentUser();
return view('user.profile', ['user' => $user, 'ownProfile' => true]);
}
$this->users->currentUser() simply calls auth()->user() in the background. Now the interesting thing is, that the user profile is actually a separate model which I'm accessing through $user->profile inside the views. When I do var_dump($user->profile->toArray()) in the above function, I can see that it actually still is the old, not-updated profile. HOWEVER when I do this
var_dump(UserProfile::where('user_id', $user->id)->first()->toArray());
I actually get the updated profile. I'm not sure what exactly is happening but it looks like the relationship does not get refetched. I can actually make the test pass if I change the above function to
public function showOwn()
{
$user = $this->users->currentUser();
// fetching the profile by hand
$profile = $this->profiles->findByField('user_id', $user->id)[0];
// and then pass it to the view and use it directly instead of $user->profile
return view('user.profile', ['user' => $user, 'profile' => $profile, 'ownProfile' => true]);
}
Now naturally I don't want to be doing this throughout my code just to make my Behat tests pass. If anyone has had a similar problem and/or knows of a solution to this problem I would greatly appreciate it.
Regards Kai
Please or to participate in this conversation.