Je reçois une NoMethodError
lorsque j'essaie d'accéder à une méthode définie dans l'un de mes modules d'assistance à partir de l'une de mes classes de contrôleur. L'application My Rails utilise la méthode de classe helper
avec le symbole :all
comme indiqué ci-dessous:
class ApplicationController < ActionController::Base
helper :all
.
.
end
D'après ce que je comprends, cela devrait obliger toutes mes classes de contrôleur à inclure automatiquement tous les modules d'assistance dans le répertoire app/helpers, et donc à mélanger toutes les méthodes dans les contrôleurs. Est-ce correct?
Si j’ai explicitement include
le module auxiliaire de l’automate, tout fonctionne correctement.
helper :all
rend toutes les aides (oui, toutes) disponibles dans les vues, il ne les inclut pas dans le contrôleur.
Si vous souhaitez partager du code entre l’assistant et le contrôleur, ce qui n’est pas très souhaitable car l’assistant est un code d’interface utilisateur et le contrôleur est un code de contrôleur, vous pouvez inclure l’assistant dans le contrôleur ou créer un module séparé et l’inclure dans le contrôleur et l'aide également.
Pour utiliser les méthodes d'assistance déjà incluses dans le moteur de modèle:
@template
. view_context
Exemple d'utilisation de l'appel 'number_to_currency' dans une méthode de contrôleur:
# Rails 3 sample
def controller_action
@price = view_context.number_to_currency( 42.0 )
end
# Rails 2 sample
def controller_action
@price = @template.number_to_currency( 42.0 )
end
si vous avez besoin de partager une méthode entre un contrôleur et helper/view, vous pouvez simplement définir via 'helper_method' en haut du contrôleur:
class ApplicationController < ActionController::Base
helper_method :my_shared_method
...
def my_shared_method
#do stuff
end
end
j'espère que cela pourra aider
Une façon d'obtenir vos méthodes d'assistance consiste simplement à inclure votre fichier d'assistance.
include LoginHelper
cool_login_helper_method(x,y,z)
Cela met toutes les méthodes de ce module d'assistance à la portée de votre contrôleur. Ce n'est pas toujours une bonne chose. Pour que la portée reste séparée, créez un objet, insérez-lui les pouvoirs de cette aide et utilisez-le pour appeler les méthodes:
login_helper = Object.new.extend(LoginHelper)
login_helper.cool_login_helper_method(x,y,z)
helper :all
rend toutes vos méthodes d'assistance de tous vos modules d'assistance disponibles pour tous vos views , mais cela ne fait rien pour vos contrôleurs. En effet, les méthodes d'assistance sont conçues pour être utilisées dans les vues et ne doivent généralement pas être accessibles à partir de contrôleurs. Dans les nouvelles versions de Rails, cette option est toujours activée par défaut pour chaque contrôleur.
Pour Rails 3, utilisez la méthode view_context
dans votre contrôleur:
def foo
view_context.helper_method
...
Voici un exemple: http://www.christopherirish.com/2011/10/13/no-view_context-in-Rails-3-1-changes/
Il est probablement plus propre d’utiliser la méthode helpers :
class FooController < ActionController::Base
def action
self.class.helpers.helper_method arg
end
end
Le moment où je trouve que cela est le plus nécessaire est celui de l'écriture du flash ou des vérificateurs d'erreur personnalisés. Il est agréable d'utiliser des éléments tels que link_to helpers dans le message flash dans certaines circonstances. J'utilise la solution suivante pour obtenir des aides ActionView dans le contrôleur. Comme cela a été mentionné ci-dessus, cela brise la séparation MVC. Si quelqu'un d'autre a une meilleure idée, faites le moi savoir!
Sous ApplicationController, ajoutez ceci:
class Something
include Singleton
include ActionView::Helpers::UrlHelper
end
et à l'intérieur du ApplicationController, ajoutez
def foo
Something.instance
end
et enfin, dans le contrôleur où vous voulez accéder au code d'assistance:
messages << "<li class='error'>Your have an Error!<%= foo.link_to('Fix This', some_path) %></li>"
J'espère que cela contribue de quelque façon!
Tous les assistants sont accessibles à l’aide de la variable @template du contrôleur.
@ template.my_super_helper
Le contrôleur ne peut pas accéder automatiquement aux méthodes d'assistance. Nous devons les inclure dans le contrôleur de l'application.
module ApplicationHelper
def hello_message
"Hello World"
end
fin
classe ApplicationController <ActionController :: Base
include ApplicationHelper
def message
hello_message
end
fin
Les assistants doivent être utilisés avec des modèles, c.-à-d. vues, pas dans les contrôleurs. C'est pourquoi vous ne pouvez pas accéder à la méthode. Si vous souhaitez partager une méthode entre deux contrôleurs, vous devez la définir dans ApplicationController, par exemple. helper: all indique que toute méthode que vous définissez dans un fichier d'assistance du répertoire app/helpers sera disponible pour tous les modèles.
Il existe deux façons de procéder: créer un module ou utiliser la variable @template. Consultez cette page pour plus de détails http://www.shanison.com/?p=305
Si vous modifiez votre fichier application_controller.rb en ceci ...
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
include SessionsHelper
end
... alors tous les assistants seront disponibles pour tous les contrôleurs.
Si vous avez seulement ApplicationHelper dans votre dossier app/helpers
, vous devez le charger dans votre contrôleur avec include ApplicationHelper
. Par défaut, Rails charge uniquement le module d'assistance portant le même nom que votre contrôleur. (par exemple, ArticlesController chargera ArticlesHelper). Si vous avez plusieurs modèles (articles, publications, catégories, par exemple), vous devez les télécharger tous dans votre contrôleur. les docs
Assistant
module PostsHelper
def find_category(number)
return 'kayak-#{number}'
end
def find_other_sport(number)
"basketball" #specifying 'return' is optional in Ruby
end
end
module ApplicationHelper
def check_this_sentence
'hello world'
end
end
Exemple de contrôleur
class ArticlesController < ApplicationController
include ApplicationHelper
include PostsHelper
#...and so on...
def show#Rails 4.1.5
#here I'm using the helper from PostsHelper to use in a Breadcrumb for the view
add_breadcrumb find_other_sport(@articles.type_activite), articles_path, :title => "Back to the Index"
#add_breadcrumb is from a gem ...
respond_with(@articles)
end
end