I have a Laravel Livewire model which has two public properties:
- A string called $tab (which I used to switch between UI tabs)
- A Model called $myobject (with relationships).
Whenever I retrieve my $myobject model, I use the Cache::remember function to retrieve my model from my Redis cache if it’s in there – this all works perfectly in the Livewire model (mount) and in my Controllers.
However, if I change the $tab property on my Livewire model (either through an $emit, or wire:click, etc) this causes the $myobject model to be ‘rehydrated’ from the database (and not the cache), causing unnecessary database queries (as it’s already in the cache).
I can see this happening using using DebugBar:
8 statements were executed, 6 of which were duplicated, 2 unique.
...
select * from `model` where `models`.`id` = 1 limit 1
350μs
/vendor/laravel/framework/src/Illuminate/Queue/SerializesAndRestoresModelIdentifiers.php:108
...
I understand that Livewire is ‘stateless’ and hence needs to pass all public properties to/from the browser when anything changes… however is there a way of intercepting the rehydration, so that I can make my $myobject from the cache (I’m happy to write this function), rather than doing expensive DB queries to retrieve it and it’s relationships?
The SerializesAndRestoresModelIdentifiers.php
script seems to be the culprit in running the queries.
I’m not really sure why it’s having to do these queries, as isn’t all the data being returned from the browser?
2
Answers
Did you consider trying something like:
Tbh this is the way I’d go with and if you need to run mount and it works fine then I guess you could basically use:
This is just from top of my head 🙂
There is a little workaround/hack to achieve this. Any
public
property will be dehydrated and rehydrated everytime a request comes full circle. It has to do a query to be able to get the model, since Livewire is indeed stateless. However,protected
andprivate
properties are not hydrated. So, what you can do is the following:Hydrate
gets called right after hydrating the component, but before anything else. This allows you to reset your model field, before anything might have to access it. You’ll have to manually pass it to the view within the render method, as Livewire won’t pass it on automatically. This way, you can fetch it from cache instead of having Livewire query the database each time.