Comment puis-je cache une méthode avec Ruby/Rails?
J'ai un coûteux (temps) demande externe à un autre service web que je dois faire, et je voudrais de les mettre en cache. J'ai donc tenté d'utiliser cette l'idiome, en mettant le texte suivant dans le contrôleur de l'application:
def get_listings
cache(:get_listings!)
end
def get_listings!
return Hpricot.XML(open(xml_feed))
end
Quand je l'appelle get_listings!
dans mon contrôleur, tout est cool, mais quand je l'appelle get_listings
Rails se plaint qu'aucun bloc n'a été donnée. Et quand je le regarde que la méthode que je vois qu'il n'a en effet s'attendre à un bloc, et en outre, il semble que la méthode est à utiliser uniquement dans le point de vue? Je devine donc que, bien qu'il n'était pas déclaré, que l'exemple est juste pseudocode.
Donc ma question est, comment puis-je cache quelque chose de ce genre? J'ai essayé diverses autres façons, mais ne pouvait pas le comprendre. Merci!
Vous devez vous connecter pour publier un commentaire.
Comme nruth suggère, de Rails intégrés dans la banque de cache est probablement ce que vous voulez.
Essayer:
fetch() récupère la valeur mise en cache de la clé spécifiée, ou écrit le résultat du bloc dans le cache si elle n'existe pas.
Par défaut, les Rails cache utilise le stockage de fichiers, mais dans un environnement de production, memcached est l'option préférée.
Voir la section 2 de http://guides.rubyonrails.org/caching_with_rails.html pour plus de détails.
une approche de code pourrait ressembler à quelque chose comme ceci:
qui va mettre en cache le résultat sur une demande de base (nouveau contrôleur d'instance par requête), si vous pouvez, comme pour regarder le " memoize aides de l'api de l'option.
Si vous voulez partager à travers les demandes de ne pas enregistrer les données sur la classe les objets de votre application ne sera pas thread-safe, sauf si vous êtes bon à la programmation simultanée & assurez-vous que le fils n'interfèrent pas les uns avec les autres données d'accès à la variable partagée.
Les "rails de chemin" pour mémoire entre les demandes de est le Les Rails.cache magasin. Memcached est utilisé beaucoup, mais vous pourriez trouver le fichier ou mémoire stocke les adapter à vos besoins. Cela dépend vraiment de la façon dont vous déployez et si vous voulez donner la priorité au cache, le temps de réponse de stockage (RAM), ou l'utilisation d'une solution hébergée par exemple, un heroku addon.
Vous pouvez utiliser le cache_method gem:
Dans votre code:
Vous remarquerez peut-être que je me suis débarrassé de
get_listings!
. Si vous avez besoin d'une manière d'actualiser les données manuellement, je suggère:Voici une autre curiosité: la
Vous pouvez également utiliser cachethod gem (https://github.com/reneklacan/cachethod)
Puis c'est mortel simple à cache méthode du résultat
Il prend également en charge l'argument de mise en mémoire cache
Il a été suggéré
cache_method
gem, même si elle est assez lourde. Si vous devez appeler la méthode sans argument, la solution est très simple:alors vous pouvez l'utiliser dans n'importe quelle classe:
Noter que ce sera également le cache de néant, qui est la seule raison de l'utiliser au lieu de
@cached_value ||=
D'autres réponses sont excellentes, mais si vous voulez une simple roulés à la main approche, vous pouvez le faire. Définir une méthode comme ci-dessous dans votre classe...
Par la suite, pour chaque méthode que vous souhaitez mettre en cache, vous pouvez mettre à envelopper le corps de la méthode dans quelque chose comme cela...
Une chose que ce n'est mieux que la méthode la plus simple énumérés ci-dessus, c'est qu'il cache un néant. Il a de la commodité qu'il ne nécessite pas la création de la duplication des méthodes. Probablement le joyau de l'approche est plus propre, cependant.
La fin de la partie, mais au cas où quelqu'un arrive ici à la recherche.
- Je utiliser pour réaliser ce petit module autour d'un projet à l'autre, je trouve ça pratique et suffisamment extensible, sans l'ajout d'un supplément de gem. Il utilise le
Rails.cache
backend, alors utilisez-le seulement si vous en possédez un.Puis dans un initialiseur:
Et puis, dans un modèle:
À ce stade, il ne fonctionne qu'avec les modèles, mais peut facilement être généralisé.