Skip to content

Commit

Permalink
[5.4] Add fresh method on Eloquent\Collection. (#19616)
Browse files Browse the repository at this point in the history
* Add fresh method on Eloquent/Collection.

* Rewrite completely the method to avoid multiple database calls.
Add full tests for Model::fresh() and Collection::fresh() methods.

* Update tests for php5.6 and Carbon v1.20.0
  • Loading branch information
mathieutu authored and taylorotwell committed Jun 17, 2017
1 parent c29b004 commit ff65fc9
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 1 deletion.
23 changes: 22 additions & 1 deletion src/Illuminate/Database/Eloquent/Collection.php
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ public function merge($items)
* Run a map over each of the items.
*
* @param callable $callback
* @return \Illuminate\Support\Collection
* @return \Illuminate\Support\Collection|static
*/
public function map(callable $callback)
{
Expand All @@ -138,6 +138,27 @@ public function map(callable $callback)
}) ? $result->toBase() : $result;
}

/**
* Reload a fresh model instance from the database for all the entities.
*
* @param array|string $with
* @return static
*/
public function fresh($with = [])
{
$model = $this->first();

$freshModels = $model->newQueryWithoutScopes()
->with(is_string($with) ? func_get_args() : $with)
->whereIn($model->getKeyName(), $this->modelKeys())
->get()
->getDictionary();

return $this->map(function ($model) use ($freshModels) {
return $model->exists ? $freshModels[$model->getKey()] : null;
});
}

/**
* Diff the collection with the given items.
*
Expand Down
42 changes: 42 additions & 0 deletions tests/Database/DatabaseEloquentIntegrationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -1069,6 +1069,48 @@ public function testIsAfterRetrievingTheSameModel()
$this->assertTrue($saved->is($retrieved));
}

public function testFreshMethodOnModel()
{
$now = \Carbon\Carbon::now();
\Carbon\Carbon::setTestNow($now);

$storedUser1 = EloquentTestUser::create(['id' => 1, 'email' => 'taylorotwell@gmail.com']);
$storedUser1->newQuery()->update(['email' => 'dev@mathieutu.ovh', 'name' => 'Mathieu TUDISCO']);
$freshStoredUser1 = $storedUser1->fresh();

$storedUser2 = EloquentTestUser::create(['id' => 2, 'email' => 'taylorotwell@gmail.com']);
$storedUser2->newQuery()->update(['email' => 'dev@mathieutu.ovh']);
$freshStoredUser2 = $storedUser2->fresh();

$notStoredUser = new EloquentTestUser(['id' => 3, 'email' => 'taylorotwell@gmail.com']);
$freshNotStoredUser = $notStoredUser->fresh();

$this->assertEquals(['id' => 1, 'email' => 'taylorotwell@gmail.com', 'created_at' => $now, 'updated_at' => $now], $storedUser1->toArray());
$this->assertEquals(['id' => 1, 'name' => 'Mathieu TUDISCO', 'email' => 'dev@mathieutu.ovh', 'created_at' => $now, 'updated_at' => $now], $freshStoredUser1->toArray());
$this->assertInstanceOf(EloquentTestUser::class, $storedUser1);

$this->assertEquals(['id' => 2, 'email' => 'taylorotwell@gmail.com', 'created_at' => $now, 'updated_at' => $now], $storedUser2->toArray());
$this->assertEquals(['id' => 2, 'name' => null, 'email' => 'dev@mathieutu.ovh', 'created_at' => $now, 'updated_at' => $now], $freshStoredUser2->toArray());
$this->assertInstanceOf(EloquentTestUser::class, $storedUser2);

$this->assertEquals(['id' => 3, 'email' => 'taylorotwell@gmail.com'], $notStoredUser->toArray());
$this->assertEquals(null, $freshNotStoredUser);
}

public function testFreshMethodOnCollection()
{
EloquentTestUser::create(['id' => 1, 'email' => 'taylorotwell@gmail.com']);
EloquentTestUser::create(['id' => 2, 'email' => 'taylorotwell@gmail.com']);

$users = EloquentTestUser::all()
->add(new EloquentTestUser(['id' => 3, 'email' => 'taylorotwell@gmail.com']));

EloquentTestUser::find(1)->update(['name' => 'Mathieu TUDISCO']);
EloquentTestUser::find(2)->update(['email' => 'dev@mathieutu.ovh']);

$this->assertEquals($users->map->fresh(), $users->fresh());
}

/**
* Helpers...
*/
Expand Down

0 comments on commit ff65fc9

Please sign in to comment.