mikebronner / laravel-model-caching

Eloquent model-caching made easy.
MIT License
2.26k stars 217 forks source link

Multitenant cache - cache fetched for wrong tenant #212

Closed denitsa-md closed 5 years ago

denitsa-md commented 5 years ago

Describe the bug Tenant connection fetches the cache for a differnet tenant.

Eloquent Query

The query I'm executing for a /settings request:

return collect(Member::first()->only('name', 'alternative_name', 'abbreviation', 'ringgold_id', 'repository', 'website', 'vat'))
            ->merge(MemberSettingKey::all()->pluck('value', 'slug'));

Environment

Additional context We have a main connection and a tenant connection. The specific tenant database is set in a middleware on every request.

We just had an issue where fetching the settings of one tenant uses the cache of another. I'm attaching a zip of the cache that is created after the request made by the first tenant. Sending the same request for another tenant returns the data of the first.

data.zip

I can see that in the 7b->b4 folder there is a key that has the database name tenant:..... (which looks correct) 🤔

My MemberSettingKey model extends SettingKey which in turn extends BaseTenantModel. The Cachable trait is applied to the SettingKeyModel. The BaseTenantModel only contains this:

class BaseTenantModel extends BaseModel
{
    /**
     * Create a new Eloquent model instance.
     *
     * @param  array $attributes
     * @return void
     */
    public function __construct(array $attributes = [])
    {
        $this->connection = config('database.tenant');
        parent::__construct($attributes);
    }
}

Would you be so kind to help me with this? :)

P.S. I'm using CACHE_DRIVER=file

denitsa-md commented 5 years ago

I also dumped inside the ModelCaching::all() function on retreival.

The result of $key = $instance->makeCacheKey(); is genealabs:laravel-model-caching:main:librarymanager:appmodelsmembersettingkey (which is wrong so I'm not sure what's happening) 🤔

PokeGuys commented 5 years ago

I am having the same issue here. When I fetch the model it works well, everything is cached in a correct key-value, but if I try to perform any create / update, the tag will mess up and use the default connection name.

I think it is related to those three functions.

https://github.com/GeneaLabs/laravel-model-caching/blob/6997acbad5383f2182e31c8ed560adef80d778bd/src/Traits/Caching.php#L79-L92

It uses the default database connection to create a new $query when the $query object is not found instead of using the connection mentioned in the model.

https://github.com/GeneaLabs/laravel-model-caching/blob/6997acbad5383f2182e31c8ed560adef80d778bd/src/Traits/CachePrefixing.php#L15-L23

In my case, by changing $this->query->connection into $this->model->getConnection(), it seems the problem will be solved.

mikebronner commented 5 years ago

@denitsa-cm @PokeGuys Could you guys retest and re-open this issue if the problem is still occurring? Please test with latest release, 0.4.12 or higher. Thanks!

denitsa-md commented 5 years ago

@mikebronner This seems to have been resolved for me! (finally got around to testing it :) )

I had made a custom implementation to set separate cache folders inside the data directory for each tenant, so each one got their folder. But I think using the database keys is sufficient, so I have also removed that separation.