web-dev-qa-db-fra.com

"méthode non définie" lors de l'appel de la méthode d'assistance depuis le contrôleur dans Rails

Est-ce que quelqu'un sait pourquoi je reçois

undefined method `my_method' for #<MyController:0x1043a7410>

quand j'appelle my_method ("chaîne") à partir de ma sous-classe ApplicationController? Mon contrôleur ressemble à

class MyController < ApplicationController
  def show
    @value = my_method(params[:string])
  end
end

et mon assistant

module ApplicationHelper
  def my_method(string)
    return string
  end
end

et enfin, ApplicationController

class ApplicationController < ActionController::Base
  after_filter :set_content_type
  helper :all
  helper_method :current_user_session, :current_user
  filter_parameter_logging :password
  protect_from_forgery # See ActionController::RequestForgeryProtection for details
40
Chad Johnson

Vous ne pouvez pas appeler des assistants depuis les contrôleurs. Votre meilleur choix est de créer la méthode dans ApplicationController si elle doit être utilisée dans plusieurs contrôleurs.

EDIT: pour être clair, je pense que beaucoup de confusion (corrigez-moi si je me trompe) provient de l'appel helper :all. helper :all inclut vraiment tous vos assistants pour une utilisation sous n’importe quel contrôleur du côté vue. Dans les versions beaucoup plus anciennes de Rails, la structure de noms des assistants déterminait quelles vues des contrôleurs pouvaient utiliser les assistants.

J'espère que ça aide. 

61
theIV

view_context est votre ami, http://apidock.com/Rails/AbstractController/Rendering/view_context

si vous voulez partager des méthodes entre le contrôleur et la vue, vous avez d'autres options:

33
Viktor Trón

Incluez ApplicationHelper dans le fichier application_controller.rb comme ceci:

class ApplicationController < ActionController::Base
  protect_from_forgery       
  include ApplicationHelper  
end

De cette manière, toutes les méthodes définies dans le fichier application_helper.rb seront disponibles dans le contrôleur.

Vous pouvez également inclure des aides individuelles dans des contrôleurs individuels.

24
Bilal Ahmed

Peut-être que je me trompe, mais les assistants ne sont-ils pas juste pour des vues? Généralement, si vous avez besoin d'une fonction dans un contrôleur, vous la placez dans ApplicationController, car chaque fonction présente dans ses classes d'enfant.

7
stex

Comme dit par gamecreature in ce post :

  • Dans Rails 2, utilisez la variable @template.
  • Dans Rails 3, utilisez la méthode du contrôleur view_context
6
chech

les helpers sont destinés aux vues, mais l'ajout d'une ligne de code pour inclure ce fichier d'assistance dans ApplicationController.rb peut résoudre votre problème. dans votre cas, insérez la ligne suivante dans ApplicationController.rb: 

include ApplicationHelper
4
btaek

Essayez d’ajouter module_function(*instance_methods) dans vos modules auxiliaires, après quoi vous pourrez directement appeler ces méthodes sur le module lui-même.

3
Minqi Pan

Autant que je sache, helper :all rend les aides disponibles dans les vues ...

3
Ju Nogueira

bien que ce ne soit pas une bonne pratique d'appeler des assistants dans le contrôleur, car les assistants sont destinés à être utilisés avec des vues le meilleur moyen d'utiliser les aides dans le contrôleur est de créer une méthode d'assistance dans application_controller et de l'appeler vers le contrôleur,
mais même s'il est nécessaire d'appeler l'aide dans un contrôleur 
alors il suffit d'inclure l'aide dans le contrôleur

class ControllerName < ApplicationController
  include HelperName
  ...callback statements..

et appelez les méthodes d'assistance directement au contrôleur 

 module OffersHelper
  def generate_qr_code(text)
    require 'barby'
    require 'barby/barcode'
    require 'barby/barcode/qr_code'
    require 'barby/outputter/png_outputter'
    barcode = Barby::QrCode.new(text, level: :q, size: 5)
    base64_output = Base64.encode64(barcode.to_png({ xdim: 5 }))
    "data:image/png;base64,#{base64_output}"
  end

Manette

class ControllerName < ApplicationController
include OffersHelper

def new
  generate_qr_code('Example Text')
end
end

j'espère que cela t'aides !

1
sudhir Vishwakarma

Essayez ceci pour accéder à la fonction d'assistance directement à partir de vos contrôleurs view_context.helper_name

0
Felipe M Andrada

J'ai eu le même problème...

vous pouvez bidouiller/modifier cette logique dans un modèle ou créer une classe spécialement pour elle. Les modèles sont accessibles aux contrôleurs, contrairement à ces méthodes d'assistance fastidieuses.

Voici mon modèle "rag.rb"

class Rag < ActiveRecord::Base
  belongs_to :report
  def miaow()
    cat = "catattack"
  end  
end

Voici une partie de mon contrôleur "rags_controller.rb"

def update
  @rag = Rag.find(params[:id])
  puts @rag.miaow()
  ...

Cela a donné une attaque sur le terminal, après avoir cliqué sur "mettre à jour". 

Étant donné une instanciation, les méthodes du modèle peuvent être appelées. Remplacez catattack par des codes. (C'est le meilleur que j'ai jusqu'à présent)

: helper ouvre uniquement les aides aux vues.

Cela montre comment faire une classe et l'appeler . http://railscasts.com/episodes/101-refactoring-out-helper-object?autoplay=true

0
xxjjnn