2010-03-05 12 views
37

¿Alguien sabe por qué me sale"método no definido" cuando se llama método de ayuda del controlador de rieles

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

cuando llamo mi_metodo ("cadena") desde el interior de mi subclase ApplicationController? Mi controlador parece

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

y mi ayudante

module ApplicationHelper 
    def my_method(string) 
    return string 
    end 
end 

y, finalmente, 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 
+0

posible duplicado de [NoMethodError al intentar invocar el método auxiliar desde el controlador Rails] (http://stackoverflow.com/questions/453762/nomethoderror-when-trying-to-invoke-helper-method-from-rails-controller) –

Respuesta

58

No se puede llamar a los ayudantes de los controladores. Su mejor opción es crear el método en ApplicationController si necesita ser utilizado en múltiples controladores.

EDIT: para ser claros, creo que mucha confusión (corríjame si me equivoco) se deriva de la llamada helper :all. helper :all realmente solo incluye todos sus ayudantes para usar debajo de cualquier controlador en el lado de la vista. En versiones mucho más antiguas de Rails, el espacio de nombres de los ayudantes determinaba qué vistas de los controladores podían usar los ayudantes.

Espero que esto ayude.

+0

Buena información. De hecho, terminé creando un módulo para mi método, como se promociona en el siguiente hilo, ya que el método es bastante genérico (convierte una cadena para que sea seguro para la url) y no debe ser específico para los controladores: http://stackoverflow.com/ preguntas/128450/mejores prácticas para reutilizar-código-entre-controladores-en-ruby-on-rails/130821 # 130821 –

+0

Esta es una buena respuesta, pero la ampliaría un poco más. helper_method cuando se utiliza en el controlador agrega un método que existe _en el controlador_ al ayudante correspondiente. es decirmétodo en Application Controller se agrega a ApplicationHelper. Esto no funciona de la otra manera. – engineerDave

7

Quizás estoy equivocado, pero ¿no son los ayudantes solo para las vistas? Por lo general, si necesita una función en un controlador, la pone en ApplicationController ya que cada función está disponible en sus clases de niños.

+0

Hm, eso apesta. Desearía poder usar métodos tanto en controladores como en vistas. Oh bien. –

+0

Puedes, tipo de ... Tu llamada 'helper_method' te está dando acceso a esos métodos en tus vistas. – theIV

3

Por lo que yo sé, helper :all hace que los ayudantes disponibles en las vistas ...

21

Incluir en el archivo ApplicationHelper application_controller.rb así:

class ApplicationController < ActionController::Base 
    protect_from_forgery  
    include ApplicationHelper 
end 

De esta manera todos los métodos definidos en application_helper El archivo .rb estará disponible en el controlador.

También puede incluir asistentes individuales en controladores individuales.

+0

Wow, esto está funcionando si alguien quiere usar el método ApplicationHelper en otros controladores o ver simplemente agregar esto 'include ApplicationHelper'. –

33

view_context es su amigo, http://apidock.com/rails/AbstractController/Rendering/view_context

si usted métodos quiero compartirla entre el controlador y la vista en la que tiene más opciones:

+0

¡Fantástico! No sabia sobre eso. Creo que esta es la respuesta correcta. –

+0

La definición de los métodos en un módulo compartido es una buena forma de hacerlo ... ya que los ayudantes se incluyen automáticamente en las vistas de Rails. –

+0

Debe marcarse tiene la respuesta correcta porque esto trae la solución al problema. Pero una pequeña explicación como @theIV también podría ayudar. :-) –

0

que tenían el mismo problema ...

se puede hackear/bodge alrededor de ella, puesto que la lógica en un modelo, o hacer una clase especialmente para ella. Los modelos son accesibles para los controladores, a diferencia de esos molestos métodos de ayuda.

Aquí está mi "trapo".rb" modelo

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

Aquí es parte de mi "rags_controller.rb" controlador

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

Esto dio un catattack en el terminal, después de que hace clic en "actualizar".

Dada una instancia , se pueden llamar los métodos en el modelo. Reemplazar catattack con algunos códigos. (Este es el mejor que tengo hasta ahora)

: helper all only opens helpers up to views.

Esto muestra cómo hacer una clase y llamarla. http://railscasts.com/episodes/101-refactoring-out-helper-object?autoplay=true

4

los ayudantes son para vistas, pero agregar una línea de código para incluir ese archivo auxiliar en ApplicationController.rb puede encargarse de su problema. en su caso, inserte la siguiente línea en ApplicationController.rb:

include ApplicationHelper 
6

Según lo dicho por gamecreature en this post:

  • En Rails 2 utilizar la variable de @template.
  • en Rails 3 utilizan el método controlador view_context
3

Pruebe añadiendo module_function(*instance_methods) en sus módulos auxiliares, después de lo cual se le puede llamar directamente a esos métodos en el propio módulo.

0

Pruebe lo siguiente para acceder a la función de ayuda directamente de los controladores view_context.helper_name

0

aunque no es una buena práctica para llamar ayudantes en el controlador desde ayudantes están destinados a ser utilizados en vistas la mejor manera de utilizar los ayudantes en el controlador es para hacer un método de ayuda en application_controller y llamarlos al controlador,
pero incluso si es necesario llamar al ayudante en un controlador
a continuación, sólo incluirá el ayudante en el controlador

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

y llamar a los métodos de ayuda directamente al controlador

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 

controlador

class ControllerName < ApplicationController 
include OffersHelper 

def new 
    generate_qr_code('Example Text') 
end 
end 

esperanza que esto ayude!

Cuestiones relacionadas