75 votes

NoMethodError lorsqu'on essaie d'invoquer une méthode d'aide à partir d'un contrôleur Rails

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

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

Si j'ai bien compris, toutes mes classes de contrôleurs devraient automatiquement inclure tous les modules d'aide dans le répertoire app/helpers, et donc intégrer toutes les méthodes dans les contrôleurs. Est-ce correct ?

Si j'ai explicitement include le module d'aide dans le contrôleur, alors tout fonctionne correctement.

0 votes

Le contrôleur en question hérite-t-il d'ApplicationController ?

0 votes

Oui. J'obtiens le problème dans deux contrôleurs qui utilisent la méthode en question et les deux contrôleurs héritent de ApplicationController.

133voto

gamecreature Points 1454

Pour utiliser les méthodes d'aide déjà incluses dans le moteur de modèles :

  • Rails 2 : utiliser le @template variable.
  • Rails 3 : a la belle méthode de 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

3 votes

C'est la meilleure réponse du groupe - elle devrait figurer en tête de liste.

8 votes

Pour Rails 3. VOICI LA RÉPONSE.

0 votes

Aucune explication sur le mode d'utilisation view_context .

51voto

Honza Points 2771

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, eh bien, un code de contrôleur, vous pouvez soit inclure l'assistant dans le contrôleur, soit créer un module distinct et l'inclure dans le contrôleur et l'assistant également.

1 votes

Merci, cela a du sens. J'ai un peu de code que je veux partager entre deux contrôleurs. Je vais créer un nouveau module et l'inclure.

0 votes

C'est la meilleure approche en effet

2 votes

S'agit-il vraiment d'un partage entre deux contrôleurs ? Ou entre un contrôleur et une vue ? Je pense que c'est le dernier. Donc la méthode de gamecreature (@template, view_context) me semble correcte.

31voto

ben Points 291

Si vous avez besoin de partager une méthode entre un contrôleur et un helper/view, vous pouvez simplement la 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 vous aidera

2 votes

La ligne helper_method :my_shared_method fait no n'a pas besoin d'être au "sommet" il peut aller n'importe où, et je le préfère juste au-dessus de la définition ( def my_shared_method ).

29voto

Adrian Dunston Points 2115

Méthodes auxiliaires des contrôleurs

Une façon d'accéder à vos méthodes d'aide est simplement d'inclure votre fichier d'aide.

include LoginHelper
cool_login_helper_method(x,y,z)

Toutes les méthodes de ce module d'aide sont alors intégrées dans le contrôleur. Ce n'est pas toujours une bonne chose. Pour garder la portée séparée, créez un objet, imprégnez-le des pouvoirs de ce module d'aide, et utilisez-le pour appeler les méthodes :

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

Aide :tous

helper :all met toutes les méthodes d'aide de tous vos modules d'aide à la disposition de tous vos modules d'aide. vues mais il ne fait rien pour vos contrôleurs. En effet, les méthodes d'aide sont conçues pour être utilisées dans les vues et ne doivent généralement pas être accessibles depuis les contrôleurs. Dans les versions plus récentes de Rails, cette option est toujours activée par défaut pour chaque contrôleur.

7voto

B Seven Points 6496

Pour Rails 3, utilisez l'option 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/

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X