2013-10-23 18 views
28

ここでのララヴェルに関する理論的な質問。LaravelでキャッシュされたEloquentモデルをどうやって忘れてしまいますか?

だから私はやるだろう、キャッシングの例は次のとおりです。

Article::with('comments')->remember(5)->get(); 

理想的には私は記事のためにイベントをしたいのですが、そのモデルのインスタンスのIDは、(それがすでにキャッシュされています)されたときに更新します更新私はそのキーを忘れたがっている(たとえそのモデルインスタンスの代わりに忘れてしまったクエリの結果であっても)、そうすることは可能ですか?

これが合理的にきれいに実装できる方法がない場合は、

+0

理論的ではない、btw。 –

+0

これは答えられていませんが、現時点では、雄弁にキャッシュキーを使用することに関する文書がなかったためです。 –

答えて

59

私はOPと同じ質問に対する答えを探していましたが、解決策には本当に満足していませんでした。だから、私はこれを最近使って、フレームワークのソースコードを調べ始めたところ、という2番目のパラメータを受け取り、何らかの理由でsiteに記載されていないことがわかりました。 。

ここで良いことは、データベースビルダーがapp/config/cache.phpの下に設定された同じキャッシュドライバを使用していることです。ここに記載されているのと同じキャッシュシステム - Cacheと言ってください。あなたはremember()に分やキーを渡すのであれば、あなたはCache::forget()メソッドを使用してキャッシュをクリアするために同じキーを使用することができますし、実際には、あなたはかなりなどCache::get()Cache::add()Cache::put()、などのofficial siteに記載されているすべてのCache方法を、使用することができますしかし、あなたが何をやっているのか分からない限り、他の方法を使うことはお勧めしません。

あなたと他の人が私の意味を理解するための例です。

Article::with('comments')->remember(5, 'article_comments')->get();

今すぐ上記のクエリの結果がキャッシュされ、その後、(私は更新時に私の場合、私はそれを行う)いつでもそれをクリアするために使用することができますarticle_commentsキーに関連付けられます。

だから私はそれが覚えてどのくらいの時間に関係なく、そのキャッシュをクリアしたい場合。私はちょうどCache::forget('article_comments');を呼び出すことによってそれを行うことができ、それはちょうど期待どおりに動作するはずです。

希望の方全員:

+3

回答が良い、ありがとうございます。不明な点については、覚えておくべき最初の引数はキャッシュする分数です。 .com/api/source-class-Illuminate.Database.Query.Builder.html#881-893 – Makita

+1

リンクに問題がなく、ありがとうございます。 –

+0

この良い質問と有益な回答は、アップルがあります:) – antoniputra

12

私が行うには良い方法がthisのようだと思う。そして、

$value = Cache::remember('users', $minutes, function() 
{ 
    return DB::table('users')->get(); 
}); 

とモデルに

class UserObserver { 

    public function saving($model) 
    { 
     // 
    } 

    public function saved($model) 
    { 
     // forget from cache 
     Cache::forget('users'); 
    } 

} 

User::observe(new UserObserver); 
+0

DB :: table( 'users') - > get();これはEloquentモデルのインスタンスを取得しません、それは一般的なオブジェクトの配列としてクエリの結果を取得するだけでしょうか?私は直接DBクエリの権利ではなく、Eloquentモデルクエリの結果を返すことができると思いますか? –

+0

オブジェクトのEloquentコレクションをキャッシュする場合や、プロパティを格納して配列に変換する場合は、 'User :: whereSomething( 'something') - > get()'を使うべきだと思います。ユーザー:: whereSomething( '何か') - > get() - > toArray() ' –

0

を更新するイベントを検出するために、Model Observersを使用現在のところ簡単な方法はありません。しかし、これまで私が働いていたこの回避策が見つかりました。

まず、Illuminate\Database\Query\Builderを延長する必要があります。

<?php 

class ModifiedBuilder extends Illuminate\Database\Query\Builder { 
    protected $forgetRequested = false; 

    public function forget() 
    { 
     $this->forgetRequested = true; 
    } 

    public function getCached($columns = array('*')) 
    { 
     if (is_null($this->columns)) $this->columns = $columns; 

     list($key, $minutes) = $this->getCacheInfo(); 

     // If the query is requested ot be cached, we will cache it using a unique key 
     // for this database connection and query statement, including the bindings 
     // that are used on this query, providing great convenience when caching. 
     $cache = $this->connection->getCacheManager(); 

     $callback = $this->getCacheCallback($columns); 

     if($this->forgetRequested) { 
      $cache->forget($key); 
      $this->forgetRequested = false; 
     } 

     return $cache->remember($key, $minutes, $callback); 
    } 
} 

次に、Eloquent Modelを拡張する新しいクラスを作成する必要があります。

<?php 

class BaseModel extends Eloquent { 
    protected function newBaseQueryBuilder() { 
     $conn = $this->getConnection(); 

     $grammar = $conn->getQueryGrammar(); 

     return new ModifiedBuilder($conn, $grammar, $conn->getPostProcessor()); 
    } 
} 

は今の代わりに新しく BaseModelを作成延びて Eloquentモデルを拡張する、雄弁モデルを作成するとき。

今度はrememberいつものようにクエリ結果できます。あなたがキャッシュされた結果を破棄したいときにあなたがしなければならないすべてはあなたが以前に結果を覚えている場合は、キャッシュされた結果をクリアした後、モデルはそのための結果を覚えていきます

YourModel::forget()->get(); 

ある

YourModel::remember(10)->get(); 

時間の長さ。

これが役に立ちます。

+0

getCachedメソッドでは、$ key変数はどこで開始されますか? –

+0

'getCacheInfo()'関数で取得され、キーは['Illuminate/Database/Query/Builder.php'](https://github.com/laravel/framework/)の' generateCacheKey() '関数で生成されます。 blob/master/src/Illuminate/Database/Query/Builder.php)。 明らかにAPIに従って 'remember()'メソッドで独自のキーを設定できます。しかし、 'getCacheKey()'関数では無視されているようです。 – tharumax

+0

私が上で述べた方法は、単純なクエリとほとんどの関係ではうまく機能します。しかし、ピボットテーブルが存在する場合(多くの場合、多くの関係で期待通りに機能しません) – tharumax

0

私はデバッグモードをテストしていました。そこで、コンストラクタにapp.debugのテストを置くと、キーに関連付けられたキャッシュをクリアできることが分かりました。すべての機能のコードを複製する必要がありません。

class Events { 
    public function __construct() { 
     if (\Config::get('app.debug')) { 
      Cache::forget('events'); 
     } 
    } 

    public static function all() { 
     $events = \DB::table('events as e') 
      ->select('e.*') 
      ->where('enabled', 1) 
      ->remember(30, 'events') 
      ->get(); 

     return $events; 
    } 
} 
関連する問題