mikebronner / laravel-model-caching

Eloquent model-caching made easy.
MIT License
2.24k stars 214 forks source link

Question: Circumstances for Relationship Invalidation #356

Closed zlanich closed 4 years ago

zlanich commented 4 years ago

This isn't exactly a feature request, but more a question and a request to add this clarity to the documentation. I'm a little bit nervous about how relationship invalidation works in this library. Would you be able to provide me with a quick summary of what conditions trigger relationship invalidation? I want to know for sure so I can manually invalidate cache whenever I'm doing something that this library can't pick up on.

It would probably be helpful to add this clarity to the documentation as well!

Thank you!

mikebronner commented 4 years ago

Hi @zlanich, any time a model is changed, it will trigger invalidation of its cached relationships. This is not recursive. There should be no need for you to do any invalidation of caches yourself.

zlanich commented 4 years ago

@mikebronner So in this m2m scenario, I'm wondering how invalidation works (if at all):

$venue = Venue::find(123);
$venue->events()->first()->update(['name' => 'Updated Event Name']);
// Does this invalidate $venue's cache?
// Or do I have to explicitly do something like $venue->touch(); to trigger invalidation of all its relationships?

$event = Event::find(123);
$event->venues()->first()->update(['name' => 'Updated Venue Name']);
// Does this invalidate $event's cache?
// Or do I have to explicitly do something like $event->touch(); to trigger invalidation of all its relationships?

Thank you!

mikebronner commented 4 years ago

@zlanich Do you have evidence that it is not working? It will only work if both models are being cached. If venues is not being cached, then events won't get invalidated, and visa-versa.

zlanich commented 4 years ago

@mikebronner I haven't implemented this yet, as I'm making sure the library behaves like I think it would be before trusting it to invalidate, so I don't have evidence that it isn't working yet. It makes sense that both models have to implement caching, but I'm wondering how deep this goes in terms of the models being aware of their relationships with each other.

In theory, wouldn't $event have to run something like $event->venues()->pluck('id') to get all that related venue ids that would need purged?

Or as another example, if we separately queried the models like so, would each of their related models' caches get invalidated?:

$venue = Venue::find(123);
$event = Event::find(123); // Assume $event is related to $venue
$event->update(['name' => 'Updated Event Name']);
// Does this invalidate $venue's cache? If not, then $venue->events()->all(); would return stale $event data.

I guess I'm just wondering how the lib goes about knowing "what" is related to "what", and which models' caches get invalidated.

P.S. I appreciate the quick responses. I'm actually working on this today, and I just spent a whole day upgrading our whole mobile app backend from 5.8 -> 7 just to attempt to use this lib!

mikebronner commented 4 years ago

It's done with cache tags, which are created when the queries are run. It invalidates based on the models involved, so no introspection into models and relationships necessary. Good luck with the implementation. Let me know if you run into any issues. Closing this for now.

legreco commented 1 year ago

Hello, i have the same question but in my case the related model has a expires_at column that i use in a hasone ofMany relationship. My requirements are A client can have multiple sessions but only 1 active session at the time in my client model public function activeSession() { return $this->hasOne(Session::class)->ofMany([ 'expires_at'=>'max' ],function ($query) { $query->where('expires_at', '>', now()); }); } As both model are cached, everything run smoothly without querying the database when for each request i check $client->activeSession()->exists() My concern is when expiration condition is met in my relationnship, i want the query retrieving the associated active session be invalidated automaticaly. How to do that?