mikebronner / laravel-model-caching

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

Wrong database name for cache prefix while flushing a model #236

Closed jesperbjerke closed 5 years ago

jesperbjerke commented 5 years ago

I'm having an issue with the flushing. It seems like it uses the wrong database name, but the correct connection name. It gets the right prefix while fetching, but during flush it doesn't.

I have the same setup as described in this issue: #132

I see that in the trait CachePrefixing and method getDatabaseName $this->query->connection->getDatabaseName(); is used, but in getConnectionName $this->model->getConnection()->getName(); is used.

Changing $this->query->connection->getDatabaseName(); to $this->model->getConnection()->getDatabaseName(); fixes the issue for me. But I'm not sure if there's some special reason the database name is coming from the query instead of the model?

Might also be me doing something wrong that makes the query not having the correct database name, but not sure what in this case.

Environment

mikebronner commented 5 years ago

@jesperbjerke Can you provide the Eloquent query and the model that you are using? Thanks!

jesperbjerke commented 5 years ago

Hm, not sure what query you want? I forgot to write in the description above that I'm testing with creating a new model vs fetching. Fetching works fine and uses the proper prefix, but since the flushCache method flushes the wrong prefix, I keep getting stale data.

Here's an example of how I'm creating a new model, no strange stuff:

$model = new Post();
$model->fill($data);
$model->save();

Here's an example model:

<?php

namespace App\Models\Tenant;

use GeneaLabs\LaravelModelCaching\Traits\Cachable;
use Illuminate\Database\Eloquent\Builder;
use Spatie\MediaLibrary\HasMedia\HasMedia;
use Spatie\MediaLibrary\HasMedia\HasMediaTrait;

class Post extends \App\Models\BaseModel implements HasMedia
{

    use HasMediaTrait, Cachable;

    protected $connection = 'tenant';

    protected $hidden = [
        'media'
    ];

    public function group()
    {
        return $this->belongsTo('App\Models\Tenant\Group');
    }

    public function postMeta()
    {
        return $this->hasMany('App\Models\Tenant\PostMeta');
    }

}

The tenant connection is set dynamically in a middleware.

mikebronner commented 5 years ago

@jesperbjerke Are you using this with Hyn/multi-tenant?

jesperbjerke commented 5 years ago

Nope! Custom implementation.

A middleware calls this method basically first thing that happens:

public static function setTenant($Tenant)
    {
        if(is_int($Tenant)){
            $Tenant = self::findTenant($Tenant);
        }

        if($Tenant instanceof Tenant) {
            self::$Tenant = $Tenant;

            config(['database.connections.tenant' => \App\Database\Config::getConfig($Tenant->db_name)]);
        }
    }

And on all models I want to be dependent on a tenant, I set protected $connection = 'tenant';

mikebronner commented 5 years ago

Thanks, I will look into this.

jesperbjerke commented 5 years ago

Cool, thanks!

Do you know if there is some special reason $this->query->connection->getDatabaseName(); is used instead of $this->model->getConnection()->getDatabaseName(); ?