NoMethodError lors de la tentative d’invocation d’une méthode d’assistance à partir du contrôleur Rails

NoMethodError une NoMethodError lorsque j’essaie d’accéder à une méthode définie dans l’un de mes modules d’aide d’une de mes classes de contrôleur. Mon application Rails utilise la méthode de la classe helper avec le symbole :all comme indiqué ci-dessous:

 class ApplicationController < ActionController::Base helper :all . . end 

Je crois comprendre que cela devrait faire en sorte que toutes mes classes de contrôleurs incluent automatiquement tous les modules d’aide dans le répertoire app / helpers, mélangeant ainsi toutes les méthodes aux contrôleurs. Est-ce correct?

Si j’inclus explicitement le module d’assistance dans le contrôleur, tout fonctionne correctement.

helper :all les assistants (oui, tous) sont disponibles dans les vues, il ne les inclut pas dans le contrôleur.

Si vous souhaitez partager du code entre assistant et contrôleur, ce qui n’est pas très souhaitable car l’aide est du code UI et que le contrôleur est, eh bien, le code du contrôleur, vous pouvez soit inclure l’assistant dans le contrôleur, soit créer un module le contrôleur et l’assistant également.

Pour utiliser les méthodes d’assistance déjà incluses dans le moteur de template:

  • Rails 2: utilisez la variable @template .
  • Rails 3: a la belle méthode du contrôleur view_context

Exemple d’utilisation de l’appel de ‘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 une aide / vue, 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

Méthodes d’aide des contrôleurs

Un moyen d’obtenir vos méthodes d’assistance consiste simplement à inclure votre fichier d’aide.

 include LoginHelper cool_login_helper_method(x,y,z) 

Cela amène toutes les méthodes de ce module d’assistance dans la scope de votre contrôleur. Ce n’est pas toujours une bonne chose. Pour conserver la scope distincte, créez un object, associez-le aux puissances de cet assistant et utilisez-le pour appeler les méthodes:

 login_helper = Object.new.extend(LoginHelper) login_helper.cool_login_helper_method(x,y,z) 

Aide: tout

helper :all vos méthodes d’assistance de tous vos modules d’aide sont disponibles pour toutes vos vues , 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 devraient généralement pas être accessibles à partir des contrôleurs. Dans les nouvelles versions de Rails, cette option est toujours activée pour chaque contrôleur par défaut.

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/

Le moment où je trouve que cela est le plus nécessaire est pour l’écriture du flash ou des vérificateurs d’erreur personnalisés. C’est bien d’utiliser des choses comme link_to helpers dans le message flash dans certaines circonstances. J’utilise la solution suivante pour transférer les assistants ActionView dans le contrôleur. Sachez que comme mentionné ci-dessus, cela rompt la séparation MVC, donc 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 dans ApplicationController, ajoutez

 def foo Something.instance end 

et enfin, dans le contrôleur où vous voulez accéder au code d’aide:

 messages < < "
  • Your have an Error!< %= foo.link_to('Fix This', some_path) %>"
  • J’espère que cela consortingbue de quelque façon!

    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 

    Tout assistant peut être accédé à 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 d’application.

    module ApplicationHelper

      def hello_message "Hello World" end 

    fin

    class ApplicationController

      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: tout dit que toute méthode que vous définissez dans un fichier d’aide dans le répertoire app / helpers sera disponible pour n’importe quel modèle.

    Il y a deux manières de faire ceci: soit créer un module, soit utiliser la variable @template. Découvrez ceci pour plus de détails http://www.shanison.com/?p=305

    Si vous avez uniquement 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 beaucoup de modèles (par exemple, Articles, Messages, Catégories), vous devez les télécharger 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 

    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.