10
votes

Dans Rails, une balayeuse ne s'appelle pas dans une configuration de modèle seulement

Je travaille sur une application Rails, où j'utilise la mise en cache de page pour stocker la sortie HTML statique. La mise en cache fonctionne bien. Je rencontre des difficultés à expirer les caches, cependant.

Je crois que mon problème est, en partie, parce que je n'utilise pas le cache de mon contrôleur. Toutes les actions nécessaires à cela sont traitées dans le modèle. Cela semble que cela devrait être faisable, mais toutes les références à une expiration de cache basée sur des modèles que je trouve semblent être obsolètes ou ne fonctionnent sinon pas.

dans mon fichier Environnement.rb , J'appelle xxx

et j'ai, dans le dossier / balayeurs, un fichier Linksweper: xxx

... Pourquoi ne peut-il pas supprimer la page mise en cache lorsque je mettez à jour le modèle? (processus: Utilisation de script / console, je sélectionne des éléments dans la base de données et sauve-les, mais leurs pages correspondantes sont disponibles. La suppression du cache), et j'appelle aussi la méthode spécifique du modèle de liaison qui invoquerait normalement la balayeuse. Ni travaille.

Si cela compte, le fichier mis en cache est un hachage MD5 sur une valeur clé dans la table des liens. La page mises en cache est stockée comme quelque chose comme /l/45ed4aade64d427...99919cba2bd90f.html.<

ici ) qu'il pourrait Soyez possible de simplement ajouter le balayeuse à config.active_record.observers dans Environnement.rb, mais cela ne semblait pas le faire (et je n'étais pas sûr si le Load_Path de l'application / balayeurs dans Environnement.RB a évité cela). < / p>

2 commentaires

@dgilpereze Le lien est mort.


Oui merci. Je viens de supprimer le commentaire. Plus de contexte: Mon commentaire était 8 ans + vieux, Rails 3 il y a longtemps EOL et les balayeurs ne sont plus une chose: D - Ce cas est probablement omniprésent dans le cas, je suis curieux de ce qui est le meilleur moyen de faire face à cela d'un perspective historique (supprimer des commentaires aussi briser l'histoire).


7 Réponses :


0
votes

J'ai été en mesure de le faire fonctionner, à l'aide d'ajouter xxx

à la méthode du modèle lui-même mettant à jour la base de données. Cela se sent un peu hacky, cependant, et j'aimerais savoir si quelqu'un peut expliquer pourquoi cela ne fonctionne pas avec la configuration de balayeuse normale et s'il y a un moyen plus élégant de gérer cela.

Cet extrait de code (à part les personnalisations que j'ai mis pour ma propre application) est venu de Ce post sur ruby-forum.com .


0 commentaires

11
votes

J'ai donc essayé de différentes approches, pour voir ce qui fonctionne, et ce qui ne fonctionne pas.

Encore une fois, pour résumer la situation: Mon objectif est d'expirer des pages cachées lors de la mise à jour d'un objet, mais pour les expirer sans s'appuyer sur une action du contrôleur. strong> Les balayeuses conventionnelles utilisent une ligne dans le contrôleur pour notifier à la balayeuse qu'elle doit fonctionner. Dans ce cas, je ne peux pas utiliser une ligne dans le contrôleur, car la mise à jour se produit dans le modèle. Les tutoriels balayeurs normaux ne fonctionnent pas, car ils présument que votre interaction principale avec l'objet de base de données est via le contrôleur. P>

Si, en lisant cela, vous voyez un moyen de resserrer mon code, s'il vous plaît commenter et Faites-moi savoir. P>

Premièrement, regardons les choses qui fonctionnent, au cas où vous êtes coincé sur cela, et avez besoin d'aide. P>

de toutes les choses que j'ai essayées , la seule chose qui semblait vraiment travailler était de déclarer une commande After_update dans l'observateur du modèle. Dans cette commande, j'ai utilisé la commande explicite pour l'action expire_page et inclus un chemin qui avait été déclaré dans Routes.rb. P>

SO. Cela fonctionne: p>

dans config / routes.rb: p> xxx pré>

in app / modèles / link_observer.rb: p>

def after_update(<model>) # where <model> is the name of the model you're observing
  ActionController::Base.expire_page(app.<model>_path(:id => <model>.id)) # where <model> is the name of the model you're observing
end


1 commentaires

Donc tout ce que j'avais au-delà de cela travaillait sur mon serveur de développement. Lorsque je l'ai essayé sur le serveur de production, cependant, il a cassé. J'ai essayé un certain nombre d'approches alternatives, mais aucun d'entre eux n'a vraiment travaillé. À la fin, alors, j'ai réécrit cette partie de l'application, il exécute donc l'expiration de la page à partir d'un contrôleur. Semble fonctionner pour le moment.



5
votes

juste une note: vous pouvez utiliser cache_sweper dans ApplicationController. XXX


2 commentaires

Merci pour cela. Je n'ai pas essayé, mais j'adorerais des commentaires de quelqu'un d'autre qui a essayé cette approche.


Cela fonctionne si je modifie MyModel via Controller (navigateur). Cependant, cela ne sera pas appelé si je modifie MyModel via la console, car cela contournez le contrôleur, la FaRe_update n'a donc jamais été enregistrée au modèle.



2
votes

J'ai eu ce travail. La seule légère différence dans ma configuration est que la balayeuse fait partie d'un moteur rails; qui explique de légères différences (chargement du fichier de balayeuse avec un besoin dans l'init du moteur au lieu de l'ajouter au chemin de charge dans Environnement.rb, etc.).

Ainsi, la balayeuse est chargée dans l'init.rb du moteur. Comme ceci: p> xxx pré>

Je l'ai appelé une balayeuse car elle "balaie" le cache, mais je suppose que c'est juste un observateur sur le modèle: p> xxx PRE>

Franchement, je n'aime pas avoir à coder le chemin dur, mais j'ai essayé d'ajouter: p> xxx pré>

puis à l'aide de la méthode du chemin, mais Cela n'a fonctionné que pour moi en développement. Cela n'a pas fonctionné dans la production, car mon serveur de production utilise une racine d'URL relative (à la place d'hôtes virtuels) et la méthode interne "page_cache_path" obtiendrait systématiquement le chemin du fichier de sorte qu'il ne pouvait pas expirer. P>

Comme il s'agit d'un observateur, j'ai ajouté à l'environnement.rb: p> xxx pré>

enfin le contrôleur qui utilise le cache (ne l'expire pas, cela se fait via le modèle Observateur): P>

class CachedCategoryCountsController < ApplicationController
  caches_page :index

  # GET /cached_category_counts.xml
  def index
    ...
  end
end


3 commentaires

Merci d'avoir travaillé sur ce problème. Je n'ai pas essayé le code, mais cela sonne comme si vous avez fait un travail approfondi sur le test. Si quelqu'un d'autre essaie cela et a des commentaires, s'il vous plaît laissez-le ici. Aimerait savoir comment cela fonctionne (positivement ou négativement) pour les autres.


Comment avez-vous créé un fichier init.rb et l'acheminez-le dans rails app?


Je reçois cette erreur méthode indéfinie `cache_weeper 'pour normalReservationsController: la classe avez-vous voulu dire? cache_store




3
votes

Je rencontrais le même problème lorsque j'essaie de faire une cache de fragment (rails 3). Impossible d'obtenir la balayeuse à observer, alors je me suis installé pour la solution pour en faire un observateur AR décrit ci-dessus et appelant ApplicationController.new.expire_fragment (...) .


0 commentaires

0
votes

Basé sur les réponses @Moiristo et @zoogiezork, je suppose que cela fonctionnerait (non testé). XXX


0 commentaires