Mark Karavan Mark Karavan - 1 month ago 5
PHP Question

Why isn't PHP/Laravel incrementing this value?

Unit testing with Laravel 5 and sqlite. I have a simple test where a

User
creates a
Post
.

/** @test */
public function it_should_increment_post_count_when_a_user_makes_a_post()
{
// Given
$u = User::first();
$count1 = $u->posts->count();
var_dump($count1);

// When
$p = new Post();
$p->title = 'My Title';
$p->content = 'This is the content';
$p->user_id = $u->id;
$p->save(); // This is definitely saving
$count2 = $u->posts->count();
var_dump($count2);

// Then
$this->assertEquals($count1+1, $count2);
}


The results are as follows:

root@7053bd7f558c:/var/www/laravel# phpunit
PHPUnit 5.5.7 by Sebastian Bergmann and contributors.

.....Fint(11)
int(11)
. 7 / 7 (100%)

Time: 1.98 seconds, Memory: 12.00MB

There was 1 failure:

1) BasicUserTest::it_should_increment_post_count_when_a_user_makes_a_post
Failed asserting that 11 matches expected 12.

/var/www/laravel/tests/BasicUserTest.php:96

FAILURES!
Tests: 7, Assertions: 11, Failures: 1.


It is certainly saving to the database (if I run this without
use DatabaseTransactions;
it increments every time). Is
$count1
a reference to
$u->posts->count()
somehow?

EDIT:
A similar variation yields a strange property:

/** @test */
public function it_should_increment_post_count_when_a_user_makes_a_post()
{
// Given
$p = new Post([
'title' => 'tha title',
'content' => 'tha content',
]);
$u_old = User::first();
var_dump($u_old->posts->count());

// When
$u_old->posts()->save($p);

// Then
$u_new = User::first();
$this->assertEquals($u_old->posts->count()+1, $u_new->posts->count());
}


This works, but if I comment out the line
var_dump($u_old->posts->count());
, it fails.

Answer

count keep the same value because the value is stored on the Eloquent model. This is a value kept in memory.

So, after insert, you need to make a new request. For example: <?php DB::table('name')->count(); ?>

Or may by just a real count: <?php $count2 = count($y->posts); ?>

(I don't remember if there is a tips to reload the counter value ...)

Comments