Skip to content

Commit 244d8c9

Browse files
committed
Fix invalidating of cache on BelongsToMany relationship
1 parent 3893f11 commit 244d8c9

File tree

7 files changed

+157
-42
lines changed

7 files changed

+157
-42
lines changed

CHANGELOG.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,17 @@ All notable changes to this project will be documented in this file.
44
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
55
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
66

7+
## [0.4.23] - 18 May 2019
8+
### Added
9+
- tests for lazy-loading the following relationships:
10+
- BelongsTo
11+
- BelongsToMany
12+
- HasMany
13+
- HasOne
14+
15+
### Fixed
16+
- BelongsToMany relationship cache not being automatically invalidated.
17+
718
## [0.4.22] - 17 May 2019
819
### Fixed
920
- issue introduce in previous release related to cache cooldown and prefixes.

src/CacheKey.php

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
<?php namespace GeneaLabs\LaravelModelCaching;
22

33
use GeneaLabs\LaravelModelCaching\Traits\CachePrefixing;
4-
use Illuminate\Database\Eloquent\Model;
5-
use Illuminate\Database\Query\Builder;
64
use Illuminate\Support\Arr;
75
use Illuminate\Support\Collection;
86
use Illuminate\Database\Query\Expression;

src/CacheTags.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
use GeneaLabs\LaravelModelCaching\Traits\CachePrefixing;
44
use Illuminate\Database\Eloquent\Model;
55
use Illuminate\Database\Eloquent\Relations\Relation;
6-
use Illuminate\Database\Query\Builder;
76
use Illuminate\Support\Str;
87

98
class CacheTags

src/Traits/Caching.php

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,20 +168,28 @@ protected function checkCooldownAndRemoveIfExpired(Model $instance)
168168
$instance->flushCache();
169169
}
170170

171-
protected function checkCooldownAndFlushAfterPersisting(Model $instance)
171+
protected function checkCooldownAndFlushAfterPersisting(Model $instance, string $relationship = "")
172172
{
173173
[$cacheCooldown, $invalidatedAt] = $instance->getModelCacheCooldown($instance);
174174

175175
if (! $cacheCooldown) {
176176
$instance->flushCache();
177177

178+
if ($relationship) {
179+
$instance->$relationship()->getModel()->flushCache();
180+
}
181+
178182
return;
179183
}
180184

181185
$this->setCacheCooldownSavedAtTimestamp($instance);
182186

183187
if ((new Carbon)->now()->diffInSeconds($invalidatedAt) >= $cacheCooldown) {
184188
$instance->flushCache();
189+
190+
if ($relationship) {
191+
$instance->$relationship()->getModel()->flushCache();
192+
}
185193
}
186194
}
187195

src/Traits/ModelCaching.php

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -46,16 +46,16 @@ public static function bootCachable()
4646
// $instance->checkCooldownAndFlushAfterPersisting($instance);
4747
// });
4848

49-
static::pivotAttached(function ($instance) {
50-
$instance->checkCooldownAndFlushAfterPersisting($instance);
49+
static::pivotAttached(function ($instance, $secondInstance, $relationship) {
50+
$instance->checkCooldownAndFlushAfterPersisting($instance, $relationship);
5151
});
5252

53-
static::pivotDetached(function ($instance) {
54-
$instance->checkCooldownAndFlushAfterPersisting($instance);
53+
static::pivotDetached(function ($instance, $secondInstance, $relationship) {
54+
$instance->checkCooldownAndFlushAfterPersisting($instance, $relationship);
5555
});
5656

57-
static::pivotUpdated(function ($instance) {
58-
$instance->checkCooldownAndFlushAfterPersisting($instance);
57+
static::pivotUpdated(function ($instance, $secondInstance, $relationship) {
58+
$instance->checkCooldownAndFlushAfterPersisting($instance, $relationship);
5959
});
6060
}
6161

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
<?php namespace GeneaLabs\LaravelModelCaching\Tests\Integration\CachedBuilder;
2+
3+
use GeneaLabs\LaravelModelCaching\Tests\Fixtures\Book;
4+
use GeneaLabs\LaravelModelCaching\Tests\Fixtures\Store;
5+
use GeneaLabs\LaravelModelCaching\Tests\Fixtures\UncachedBook;
6+
use GeneaLabs\LaravelModelCaching\Tests\IntegrationTestCase;
7+
8+
class BelongsToManyTest extends IntegrationTestCase
9+
{
10+
public function testLazyLoadingRelationship()
11+
{
12+
$bookId = (new Store)
13+
->disableModelCaching()
14+
->with("books")
15+
->first()
16+
->books
17+
->first()
18+
->id;
19+
$key = sha1("genealabs:laravel-model-caching:testing::memory::book-store:genealabslaravelmodelcachingcachedbelongstomany-book_store.book_id_=_{$bookId}");
20+
$tags = [
21+
'genealabs:laravel-model-caching:testing::memory::genealabslaravelmodelcachingtestsfixturesstore',
22+
];
23+
24+
$stores = (new Book)
25+
->find($bookId)
26+
->stores;
27+
$cachedStores = $this
28+
->cache()
29+
->tags($tags)
30+
->get($key)['value'];
31+
$uncachedBook = (new UncachedBook)
32+
->find($bookId);
33+
$uncachedStores = $uncachedBook->stores;
34+
35+
$this->assertEquals($uncachedStores->pluck("id"), $stores->pluck("id"));
36+
$this->assertEquals($uncachedStores->pluck("id"), $cachedStores->pluck("id"));
37+
$this->assertNotNull($cachedStores);
38+
$this->assertNotNull($uncachedStores);
39+
}
40+
41+
public function testInvalidatingCacheWhenAttaching()
42+
{
43+
$bookId = (new Store)
44+
->disableModelCaching()
45+
->with("books")
46+
->first()
47+
->books
48+
->first()
49+
->id;
50+
$key = sha1("genealabs:laravel-model-caching:testing::memory::book-store:genealabslaravelmodelcachingcachedbelongstomany-book_store.book_id_=_{$bookId}");
51+
$tags = [
52+
'genealabs:laravel-model-caching:testing::memory::genealabslaravelmodelcachingtestsfixturesstore',
53+
];
54+
$newStore = factory(Store::class)
55+
->create();
56+
$result = (new Book)
57+
->find($bookId)
58+
->stores;
59+
60+
(new Book)
61+
->find($bookId)
62+
->stores()
63+
->attach($newStore->id);
64+
$cachedResult = $this
65+
->cache()
66+
->tags($tags)
67+
->get($key)['value'];
68+
69+
$this->assertNotEmpty($result);
70+
$this->assertNull($cachedResult);
71+
}
72+
73+
public function testInvalidatingCacheWhenDetaching()
74+
{
75+
$bookId = (new Store)
76+
->disableModelCaching()
77+
->with("books")
78+
->first()
79+
->books
80+
->first()
81+
->id;
82+
$key = sha1("genealabs:laravel-model-caching:testing::memory::book-store:genealabslaravelmodelcachingcachedbelongstomany-book_store.book_id_=_{$bookId}");
83+
$tags = [
84+
'genealabs:laravel-model-caching:testing::memory::genealabslaravelmodelcachingtestsfixturesstore',
85+
];
86+
$result = (new Book)
87+
->find($bookId)
88+
->stores;
89+
90+
(new Book)
91+
->find($bookId)
92+
->stores()
93+
->detach($result->first()->id);
94+
$cachedResult = $this
95+
->cache()
96+
->tags($tags)
97+
->get($key)['value'];
98+
99+
$this->assertNotEmpty($result);
100+
$this->assertNull($cachedResult);
101+
}
102+
103+
public function testInvalidatingCacheWhenUpdating()
104+
{
105+
$bookId = (new Store)
106+
->disableModelCaching()
107+
->with("books")
108+
->first()
109+
->books
110+
->first()
111+
->id;
112+
$key = sha1("genealabs:laravel-model-caching:testing::memory::book-store:genealabslaravelmodelcachingcachedbelongstomany-book_store.book_id_=_{$bookId}");
113+
$tags = [
114+
'genealabs:laravel-model-caching:testing::memory::genealabslaravelmodelcachingtestsfixturesstore',
115+
];
116+
$result = (new Book)
117+
->find($bookId)
118+
->stores;
119+
120+
$store = $result->first();
121+
$store->address = "test address";
122+
$store->save();
123+
$cachedResult = $this
124+
->cache()
125+
->tags($tags)
126+
->get($key)['value'];
127+
128+
$this->assertNotEmpty($result);
129+
$this->assertNull($cachedResult);
130+
}
131+
}

tests/Integration/CachedBuilder/LazyLoadTest.php

Lines changed: 0 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
use GeneaLabs\LaravelModelCaching\Tests\Fixtures\Author;
44
use GeneaLabs\LaravelModelCaching\Tests\Fixtures\Book;
55
use GeneaLabs\LaravelModelCaching\Tests\Fixtures\Profile;
6-
use GeneaLabs\LaravelModelCaching\Tests\Fixtures\Store;
76
use GeneaLabs\LaravelModelCaching\Tests\Fixtures\UncachedAuthor;
87
use GeneaLabs\LaravelModelCaching\Tests\Fixtures\UncachedBook;
98
use GeneaLabs\LaravelModelCaching\Tests\Fixtures\UncachedProfile;
@@ -41,37 +40,6 @@ public function testBelongsToRelationship()
4140
$this->assertNotNull($uncachedResult);
4241
}
4342

44-
public function testBelongsToManyRelationship()
45-
{
46-
$bookId = (new Store)
47-
->disableModelCaching()
48-
->with("books")
49-
->first()
50-
->books
51-
->first()
52-
->id;
53-
$key = sha1("genealabs:laravel-model-caching:testing::memory::book-store:genealabslaravelmodelcachingcachedbelongstomany-book_store.book_id_=_{$bookId}");
54-
$tags = [
55-
'genealabs:laravel-model-caching:testing::memory::genealabslaravelmodelcachingtestsfixturesstore',
56-
];
57-
58-
$stores = (new Book)
59-
->find($bookId)
60-
->stores;
61-
$cachedStores = $this
62-
->cache()
63-
->tags($tags)
64-
->get($key)['value'];
65-
$uncachedBook = (new UncachedBook)
66-
->find($bookId);
67-
$uncachedStores = $uncachedBook->stores;
68-
69-
$this->assertEquals($uncachedStores->pluck("id"), $stores->pluck("id"));
70-
$this->assertEquals($uncachedStores->pluck("id"), $cachedStores->pluck("id"));
71-
$this->assertNotNull($cachedStores);
72-
$this->assertNotNull($uncachedStores);
73-
}
74-
7543
public function testHasManyRelationship()
7644
{
7745
$key = sha1("genealabs:laravel-model-caching:testing::memory::books:genealabslaravelmodelcachingtestsfixturesbook-books.author_id_=_1-books.author_id_notnull");

0 commit comments

Comments
 (0)