ruby-on-rails - que - ruby on rails tutorial
NoMethodError al intentar invocar el método auxiliar desde el controlador Rails (13)
NoMethodError
un NoMethodError
cuando intento acceder a un método definido en uno de mis módulos auxiliares desde una de mis clases de controlador. La aplicación My Rails usa el método de la clase helper
con el símbolo :all
como se muestra a continuación:
class ApplicationController < ActionController::Base
helper :all
.
.
end
Tengo entendido que esto debería hacer que todas mis clases de controlador incluyan automáticamente todos los módulos auxiliares dentro del directorio de aplicaciones / ayudantes, por lo tanto, se mezclarán todos los métodos en los controladores. ¿Es esto correcto?
Si incluyo explícitamente el módulo auxiliar dentro del controlador, todo funciona correctamente.
Métodos de ayuda de los controladores
Una forma de llegar a sus métodos de ayuda es simplemente incluir su archivo de ayuda.
include LoginHelper
cool_login_helper_method(x,y,z)
Esto trae todos los métodos de ese módulo auxiliar al alcance de su controlador. Eso no siempre es bueno. Para mantener el alcance por separado, crea un objeto, infúndelo con los poderes de ese ayudante y utilízalo para llamar a los métodos:
login_helper = Object.new.extend(LoginHelper)
login_helper.cool_login_helper_method(x,y,z)
Ayudante: todo
helper :all
hace todos sus métodos de ayuda de todos sus módulos de ayuda disponibles para todas sus vistas , pero no hace nada para sus controladores. Esto se debe a que los métodos auxiliares están diseñados para su uso en vistas y, en general, no se debe acceder a ellos desde los controladores. En las versiones más nuevas de Rails, esta opción siempre está activada para cada controlador de manera predeterminada.
El controlador no puede acceder a los métodos de ayuda automáticamente. Debemos incluirlos en el controlador de la aplicación.
módulo ApplicationHelper
def hello_message
"Hello World"
end
fin
clase ApplicationController <ActionController :: Base
include ApplicationHelper
def message
hello_message
end
fin
El momento en que considero que esto es más necesario es para escribir el flash o las comprobaciones de error personalizadas. Es bueno usar cosas como link_to helpers en el mensaje flash en algunas circunstancias. Utilizo la siguiente solución para obtener ayudantes de ActionView en el controlador. Tenga en cuenta que, como se mencionó anteriormente, esto rompe la separación MVC, por lo que si alguien tiene una mejor idea, ¡hágamelo saber!
Debajo de ApplicationController agrega esto:
class Something
include Singleton
include ActionView::Helpers::UrlHelper
end
y dentro de ApplicationController, agregue
def foo
Something.instance
end
y finalmente, en el controlador donde desea acceder al código auxiliar:
messages << "<li class=''error''>Your have an Error!<%= foo.link_to(''Fix This'', some_path) %></li>"
¡Espero que eso ayude de algún modo!
Hay dos formas de hacer esto: crear un módulo o usar la variable @template. Mira esto para más detalles http://www.shanison.com/?p=305
Los ayudantes deben usarse con plantillas, es decir. vistas, no en controladores. Es por eso que no puedes acceder al método. Si desea compartir un método entre dos controladores, tendría que definirlo en ApplicationController, por ejemplo. helper: all dice que cualquier método que defina en cualquier archivo auxiliar en el directorio app / helpers estará disponible para cualquier plantilla.
Para Rails 3, utiliza el método view_context
en tu controlador:
def foo
view_context.helper_method
...
Aquí hay un ejemplo: http://www.christopherirish.com/2011/10/13/no-view_context-in-rails-3-1-changes/
Para usar los métodos de ayuda ya incluidos en el motor de plantillas:
- Rails 2: usa la variable
@template
. - Rails 3: tiene el buen método de control
view_context
Ejemplo de uso de la llamada ''number_to_currency'' en un método de controlador:
# 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
Probablemente sea más limpio usar el método de helpers :
class FooController < ActionController::Base
def action
self.class.helpers.helper_method arg
end
end
Se puede acceder a cualquier ayuda utilizando la variable @template en el controlador.
@ template.my_super_helper
Si cambia su archivo application_controller.rb a este ...
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
include SessionsHelper
end
... entonces todos los ayudantes estarán disponibles para todos los controladores.
Si solo tiene ApplicationHelper dentro de su carpeta app/helpers
de la que tiene que cargar en su controlador, include ApplicationHelper
. Por defecto, Rails solo carga el módulo auxiliar que tiene el mismo nombre que su controlador. (por ejemplo, ArticlesController cargará ArticlesHelper). Si tiene muchos modelos (por ejemplo, artículos, publicaciones, categorías), debe cargar cada uno en su controlador. los documentos
Ayudante
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
Controlador de ejemplo
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 necesita compartir un método entre un controlador y helper / view, puede simplemente definirlo a través de ''helper_method'' en la parte superior del controlador:
class ApplicationController < ActionController::Base
helper_method :my_shared_method
...
def my_shared_method
#do stuff
end
end
Espero que ayude
helper :all
hace que todos los helpers (sí, todos) estén disponibles en las vistas, no los incluye en el controlador.
Si desea compartir algún código entre el helper y el controlador, que no es muy deseable porque el helper es el código UI y el controlador es, bueno, el código del controlador, puede incluir el helper en el controlador o crear un módulo separado e incluirlo en el controlador y el ayudante también.