mikebronner / laravel-model-caching

Eloquent model-caching made easy.
MIT License
2.25k stars 212 forks source link

Issue With BelongsToMany #280

Closed mikebronner closed 2 years ago

mikebronner commented 5 years ago

i'm having this issue as well, least i think they are related. i have the following model:

class products extends syncableBase
{
    protected $with=['attributes'];
    public function __construct()
    {
    }
    public function attributes()
    {
        return $this->belongsToMany('App\attributes',"productattributes","products_id","attribute_id")->withPivot(["isGroup","visibilityFormula"]);
    }
}

syncableBase overrides hasMany but not belongsTo and uses cacheable.

if i save an existing object (one acquired via get) there is no problems, if i save a new object without any relationships, no problems, the only problem is when i create a new object, save, sync the ids, and then save again (i don't think the separate saves are part of the issue, but if i don't do the first save it never does the sync, because there is no id for the product)

it seems the save should invalidate the cache, and given there were two saves that should doubly so

relevant part of that:

$itemsArr=[];
        $groupsArr=[];
        if(isset($input["item_attributes"]))
        {
            $itemsArr=$input["item_attributes"];
        }
        if(isset($input["group_attributes"]))
        {
            $groupsArr=$input["group_attributes"];
        }
        $ids=$itemsArr+$groupsArr;
        $obj->save();//seems laravel can't handle the sync if the object is new and doesn't have a pk, as it doesn't in the case of auto_incrementing primary keys, so i have to save, then it will have a key then i can sync and save again...
        $obj->attributes()->sync($ids);

so after doing this, i go to a list of products as follows:

$data = \App\products::orderBy('product_name', 'asc')->limit(100)->get();

and the product i just created isn't in the list, if i clear the cache it shows up, if i save the product i just created again (from the product edit screen) the product will show in the list also, don't let that limit bother you, you there are only 4 products in the database right now.

it's quite perplexing.

i don't THINK i'm using nova, here are my requires:

"require": {
        "php": "^7.1.3",
        "ckfinder/ckfinder-laravel-package": "v3.4.5.1",
        "fideloper/proxy": "^4.0",
        "genealabs/laravel-model-caching": "^0.6.1",
        "laravel/framework": "5.8.*",
        "laravel/tinker": "^1.0",
        "predis/predis": "^1.1",
        "watson/rememberable": "^3.0"
    },
    "require-dev": {
        "barryvdh/laravel-debugbar": "^3.2",
        "beyondcode/laravel-dump-server": "^1.0",
        "filp/whoops": "^2.0",
        "fzaninotto/faker": "^1.4",
        "mockery/mockery": "^1.0",
        "nunomaduro/collision": "^3.0",
        "phpunit/phpunit": "^7.5"
    },

so my problem MIGHT not be related to his or both of our problems may be unrelated to nova.

Originally posted by @tuseroni in https://github.com/GeneaLabs/laravel-model-caching/issues/278#issuecomment-520457213

mikebronner commented 5 years ago

@tuseroni Let's continue the discussion here.

tuseroni commented 5 years ago

i did find a workaround, might help anyone else having this problem, least til it's resolved: call $obj->flushCache() when saving, or override save on the model (or in my case "cacheableClass" which implements the caching on all models) to look kinda like the following:

use Cachable;
    public function save(array $options = [])
    {
        parent::save($options);
        $this->flushCache();
    }

if i call this the list shows up correctly, i don't know enough about how laravel handles caching, or how you are implementing caching to know what causes this, i'm looking over your code at the moment to see if i can spot (which was how i found the flushCache command which worked as a workaround so i didn't have to disable cache on the listing)

i'll tell you if i see something that stands out.

mikebronner commented 5 years ago

@tuseroni Sorry I didn't see this until now: if you are using this package, don't use any other caching packages. watson/rememberable is likely conflicting. Closing this for now. Let me know if that fixes it.

tuseroni commented 5 years ago

i'm not using watson/rememberable, i used it at one point which is why it's in my requires but the class doesn't implement it

mikebronner commented 5 years ago

@tuseroni Hmm, I'm not seeing anything that would cause this from what you describe above. Can you provide a public repo that reproduces the problem that I can test with?

tuseroni commented 5 years ago

i'll see what i can do, but i don't own the code i'm working with so i will have to find a way to reproduce it myself.

reasecret commented 4 years ago

I think I'm having this issue. I'm syncing some ids for my pivot table. When cache enabled, I can't see some relationship query results. Bu when disabled cache I can see results.

Jafo232 commented 4 years ago

I can confirm the same issues here. I have had to disable it on several models because of this.

mikebronner commented 4 years ago

@reasecret @Jafo232 Can you please provide your specific Eloquent queries, as well as the version of laravel-model-caching package you have installed, along with the version of Laravel. If at all possible, would love a PR with a failing test so I can figure out how to reproduce this.

LiamAird commented 3 years ago

@mikebronner Here's an example of it, since I also ran into the issue.

$company->tags()->sync($request->tags);

The "sync" method does not seem to invalidate the cache. Once the cache is manually flushed, all is good again.

Company is not cacheable, but tags model is. Company model

 public function tags()
    {
        return $this->belongsToMany(Tag::class)->withTimestamps();
    }

Tags model

 public function companies()
    {
        return $this->belongsToMany(Company::class);
    }
mikebronner commented 3 years ago

@LiamAird Thanks for the further clarification on this. I will look into it.

Bjornftw commented 2 years ago

Seems like we have this problem too. The sync() function is not working anymore. Saving relations with sync() is not working when we've enabled use Cachable;

d8vjork commented 2 years ago

What just @Bjornftw said.

@mikebronner I sent a PR fixing this (#433), I don't know the relation with this specific issue tho

ekandreas commented 2 years ago

This is fixed in v0.12.5

mikebronner commented 2 years ago

Closing this for as it was fixed in #433