Rails: définissez une variable d'instance commune sur plusieurs actions de contrôleur
Comment doit-on avoir plusieurs différentes controller' ensemble des actions ordinaires de variable d'instance pour une utilisation dans les modèles mais après l'action s'exécute.
En d'autres mots, je veux que cela fonctionne dans mon application_controller.
class ApplicationController < ActionController::Base
after_filter :set_something_common
def set_something_common
# All controllers' actions have queried the DB and set @foo for me...
@bar = some_calculation_on(@foo)
# ... and all templates expect @bar to bet set.
end
end
Ce ne fonctionne pas parce que after_filter
s'exécute après le rendu. Des beaux. Mais quel est le bon modèle?
Encore une fois, il est important que set_something_common
s'exécute après l'action, car ces actes ne cas spécifique de choses; mais ils ont tous mis @foo
.
Aucun de mes idées semblent l'idéal:
- Appel
set_something_common()
vers le bas de chaque action qui le nécessite. - Refactoriser tous les contrôleurs " -code spécifique dans
case_specific_code()
et les forcer à exécuter dans l'ordre:before_filter :case_specific_code, :set_something_common
- Sous-classe
application_controller
et de redéfinir laindex
méthode.
Toute pensée? Merci.
Edit: Matthieu réponse qui m'a incité à préciser:
Plusieurs contrôleurs' index() tous faire de la pagination, chacun prend des paramètres @offset
et @limit
(via mondial before_filter
) pour afficher les données en tranches. Grand. Maintenant, je veux une méthode commune pour le calcul d'un Réparateur d'URL pour la "prochaine tranche" lien. J'ai été encouragé de voir que url_for()
génère une URL de retour à la même ressource, alors j'ai essayé:
def set_something_common # really called set_next_url, truth be told
@next_url = url_for(:offset => @offset + @limit, :limit => @limit)
end
Je vais essayer monkey patching Fixnum, afin que je puisse faire quelque chose comme @offset.next_url_for(self, @limit)
à partir du modèle, mais je ne suis pas sûr si cela va fonctionner. Venez pour penser à elle, si je vais modifier les modèles, alors je peut ainsi configurer une application helper. Je ne sais pas encore quelle solution est la meilleure.
Mise à jour: Accepté la réponse est "utiliser une aide."
Merci pour les mises à jour de tout le monde. J'ai appris ma leçon que les aides, comme les variables globales sont là pour une raison et ne pas être évité lorsqu'elles sont manifestement bénéfique et succincte.
source d'informationauteur JasonSmith
Vous devez vous connecter pour publier un commentaire.
Tout d'abord, vous ne voulez pas essayer d'insérer le code "entre" l'action d'un contrôleur et d'un modèle de rendu. Pourquoi? Parce que vous souhaitez que l'action du contrôleur pour avoir la liberté de choisir quelle sorte de réponse à donner. Il pourrait renvoyer du XML, JSON, en-têtes, une redirection, rien, etc. C'est pourquoi, une fois que les filtres sont exécutés après la réponse a été rendue.
Deuxièmement, vous ne voulez pas monkey patch
Fixnum
. Je veux dire, peut-être vous faire, mais je n'en ai pas. Pas souvent au moins, et pas à moins que je reçois certains totalement méchants sémantique des avantages, comme celui d'être en mesure de dire3.blind_mice
. Monkey patching pour un aléatoire de cas d'utilisation, comme cela semble être un entretien de maux de tête en bas de la route.Vous mentionnez refactoring tous les contrôleurs de " cas spécifique de code dans un avant de filtrer et de les exécuter de manière séquentielle. Ce qui amène à mon esprit...
@foo
est la même dans tous les cas? Si c'est le cas, alors on avant de filtre fonctionne très bien:Qui est tout à fait légitime approche. Mais si @foo changements de contrôleur de contrôleur de... eh bien, vous avez quelques options supplémentaires.
Vous pouvez séparer votre filtre avant en deux moitiés, et de personnaliser par le contrôleur.
Mais vous savez, si c'est un cas simple qui ne nécessite pas de base de données access ou accès au réseau, ou quelque chose comme ça... qui votre cas n'est pas... ne tuez pas vous-même. Et ne vous en faites pas. Le jeter dans un helper. C'est qu'ils sont là, pour vous aider. Vous êtes fondamentalement, tout simplement réorganiser certaines afficher les données dans une forme légèrement plus facile à utiliser de toute façon. Une aide est-ce que mon vote. Et vous pouvez juste le nom c'
next_url
. 🙂J'aurais une méthode sur
@foo
qui retourne un bar, de cette façon, vous pouvez utiliser@foo.bar
dans vos vues.<% @bar = @foo.bar %>
#si vous ne voulez vraiment pas à changer votre point de vue, mais vous n'avez pas entendu parler de moi 🙂Utilisation
<%= do_some_calculations(@foo) %>
à l'intérieur de vos modèles.C'est la voie droite.