Question théorique sur Laravel ici.
Ainsi, l'exemple de la mise en cache que je ferais est:
Article::with('comments')->remember(5)->get();
Idéalement, j'aimerais avoir un événement pour les mises à jour d'article lorsque, lors de la mise à jour de l'ID d'une instance de ce modèle (déjà mis en cache), je souhaite oublier cette clé cette instance de modèle), il est possible de le faire?
Sinon, y a-t-il un moyen d'appliquer cela raisonnablement proprement?
Je pense qu'une bonne façon de faire est comme this :
$value = Cache::remember('users', $minutes, function()
{
return DB::table('users')->get();
});
puis utilisez Model Observers pour détecter l'événement de mise à jour du modèle.
class UserObserver {
public function saving($model)
{
//
}
public function saved($model)
{
// forget from cache
Cache::forget('users');
}
}
User::observe(new UserObserver);
Je testais pour le mode débogage. J'ai donc constaté que si vous mettez un test pour app.debug dans un constructeur, vous pouvez vider le cache associé à une clé. Vous évite de dupliquer le code pour chaque fonction.
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;
}
}
Actuellement, il n'y a pas de moyen facile. Cependant, j'ai trouvé cette solution de contournement, qui jusqu'à présent a fonctionné pour moi.
Vous devez d’abord étendre 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);
}
}
Ensuite, vous devez créer une nouvelle classe qui étend Eloquent Model.
<?php
class BaseModel extends Eloquent {
protected function newBaseQueryBuilder() {
$conn = $this->getConnection();
$grammar = $conn->getQueryGrammar();
return new ModifiedBuilder($conn, $grammar, $conn->getPostProcessor());
}
}
Maintenant, lors de la création de modèles Eloquent, au lieu d'étendre Eloquent
, les modèles étendent la nouvelle BaseModel
créée.
Vous pouvez maintenant utiliser le résultat de la requête remember
comme d'habitude.
YourModel::remember(10)->get();
Lorsque vous souhaitez supprimer le résultat mis en cache, il vous suffit de
YourModel::forget()->get();
Si vous vous souvenez du résultat précédemment, après avoir effacé le résultat mis en cache, le modèle continuera à mémoriser le résultat pendant cette période.
J'espère que cela t'aides.