renoki-co / laravel-eloquent-query-cache

Adding cache on your Laravel Eloquent queries' results is now a breeze.
Apache License 2.0
1.06k stars 118 forks source link

Cache Flushing on Update does not Work with Relationships #43

Closed DevynCJohnson closed 4 years ago

DevynCJohnson commented 4 years ago

When making data changes (inserts, updates, and deletes) from one model/table to another model/table via Eloquent Relationships, the protected static $flushCacheOnUpdate = true; feature does not seem to recognize that a change occurred. For instance, if I have a model/table called foo that has a function that edits a thingamajig and then edits the related thingamabobs in the model/table bar via a relationship in the foo model. When Laravel/Eloquent retrieves the data for me to view the listing of thingamabobs from bar (retrieving the data through the bar model), the data displayed is still the old data from the cache. If I comment-out use Rennokki\QueryCache\Traits\QueryCacheable; and use QueryCacheable; in the model bar, then making such edits in the foo model (via relationships) will properly display the edits pertaining to bar.

This issue appears to only be relevant to data changes via relationships. When using the bar model (i.e. use bar;) within the foo model, this issue does not occur. It is as if QueryCacheable does not recognize relationships properly.

I hope I clearly explained and described this issue. If not, feel free to ask for clarification.

DevynCJohnson commented 4 years ago

Also, just in case this information is needed, I am using the latest version of your amazing module on Laravel v7.14. I have not seen any changes nor differences in this issue with either MySQL nor MariaDB.

Jamie4224 commented 4 years ago

I have this same issue, I use the $touches property on a child model. When I create the child model, the updated_at on the parent model gets updated but the cache isn't flushed.

rennokki commented 4 years ago

@DevynCJohnson Can you give me a proper code example of what you're trying to achieve and it doesn't work out as expected?

Jamie4224 commented 4 years ago

I can at least give my problem, that is probably related to this.

RefereeResult ` <?php

namespace App\Models\Tournament\Challenge;

use App\Models\Team;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Rennokki\QueryCache\Traits\QueryCacheable;

class RefereeResult extends Model
{
use SoftDeletes;

use QueryCacheable;

public $cacheFor = 3600;

protected $touches = ['team'];

/**
 * Invalidate the cache automatically
 * upon update in the database.
 *
 * @var bool
 */
protected static $flushCacheOnUpdate = true;

/**
 * The attributes that aren't mass assignable.
 *
 * @var array
 */
protected $guarded = [];

public function team() {
    return $this->belongsTo(Team::class);
}
}`

Team

use QueryCacheable;

    public $cacheFor = 120;

    /**
     * Invalidate the cache automatically
     * upon update in the database.
     *
     * @var bool
     */
    protected static $flushCacheOnUpdate = true;

Now, the problem is that when I update a RefereeResult, the Team it is associated with should have it's cache invalidated. However when I create or update a RefereeResult associated with a Team, the Team cache is not invalidated, and when I request data through the relationship 'refereeResults' on the Team model, I get old data.

I do see that the updated_at property is updated on the team when something changes on an associated RefereeResult, but the cache is not invalidated.

DevynCJohnson commented 4 years ago

@rennokki , unfortunately, I cannot provide the actual code I have to demonstrate this issue due to the code being non-public intellectual property that is not mine to show. However, @Jamie4224 demonstrated the issue well (thank you @Jamie4224 ).

rennokki commented 4 years ago

@DevynCJohnson The problem with the touches is that it does not fire the updated event: https://stackoverflow.com/questions/54476084/fire-laravel-events-on-touch