ruby on rails - links - Ver helper link_to en clase de modelo
rails link_to params (5)
Hay algunas razones por las que puede necesitar link_to en un modelo. Sí, @andy, es una violación de MVC, pero eso no significa que deba obtener puntos por no responder la pregunta.
@schwabsauce, es más fácil que eso. La primera línea no es estrictamente necesaria si lo haces en un inicializador o algo así. Lo mismo funciona para .isaitize y .raw y una gran cantidad de otras increíbles funciones.
ActionView::Base.send(:include, Rails.application.routes.url_helpers)
ActionController::Base.helpers.link_to(whatever)
Si desea usar autopaths, puede que tenga que hacer esto dentro de su link_to:
Rails.application.routes.url_helpers.page_path(@page)
Usando Rails 3, ¿hay alguna manera de usar link_to helper, o cualquier ayuda para ese asunto, dentro del modelo?
Lo tengo para trabajar con las siguientes inclusiones:
include ActionView::Helpers::UrlHelper
include ActionController::UrlFor
include Rails.application.routes.url_helpers
cattr_accessor :controller
def controller; self.class.controller; end
def request; controller.request; end
Luego en mi controlador llené el atributo (crear un controlador desde cero requiere una gran cantidad de datos en los argumentos hash).
Lead.controller = self
No sin hackers.
Si cree que necesita link_to
en un modelo, es probable que esté violando algún principio de la arquitectura Model-View-Controller .
Un modelo debe ser un lugar para la lógica de datos y de negocios, pero generar enlaces es casi seguro un trabajo para el controlador o la vista (o, Rails específicamente, en una clase de ayuda).
Tenga mucho cuidado siguiendo los consejos descritos en la publicación de Chuck si está haciendo esto en Rails 3.2.1. Parecería que ese enfoque no es una manera segura de incluir el link_to helper en las clases que no son de vista en Rails 3.2.1. Hay una manera más segura (que funciona para nosotros en cualquier caso) que se detalla a continuación.
Cuando utilizamos el enfoque en la publicación de Chuck en una de nuestras clases, terminó teniendo consecuencias muy preocupantes y difíciles de depurar. Terminó causando efectos secundarios / errores que solo aparecieron en circunstancias muy específicas (y raras).
El problema, por lo que podemos decir, es que esta línea:
ActionView::Base.send(:include, Rails.application.routes.url_helpers)
ActionView::Base
está diciendo a ActionView::Base
que incluya Rails.application.routes.url_helpers
, que ActionView::Base
aparentemente ya hace por sí mismo. url_helpers
incluir el url_helpers
por segunda vez, parece causar la reinicialización del estado de las rutas (@_rutas en las clases que han incluido el módulo ActionDispatch :: Routing :: UrlFor).
Esto lleva a excepciones aparentemente inexplicables de "método indefinido" url_for ''for nil: NilClass "en las vistas que intentan llamar, directa o indirectamente, al método ActionView::Base
después de que ActionView::Base
ha incluido url_helpers
segunda vez.
La solución que funcionó para nosotros fue en vez de decirle a ActionView::Base
que incluyera url_helpers
nuevamente, solo incluya el módulo UrlHelper
usted mismo donde sea que lo necesite.
Luego, cuando necesite usar link_to y tener acceso a la ruta, simplemente puede hacer esto (suponiendo que login_path es válido para su aplicación):
include ActionView::Helpers::UrlHelper
...
link = link_to(''here'', Rails.application.routes.url_helpers.login_path)
Nos tomó un tiempo muy largo y un montón de arañazos en la cabeza para rastrear los errores causados por el doble-incluir y solo quería advertir a los demás a tener cuidado al ajustar el comportamiento de las clases base de Rails.
link_to helper, violación MVC
Lo que dijo Andy,
si está generando HTML en el modelo, probablemente necesite echar un vistazo a lo que está haciendo y por qué.
Ayudantes de URL
Las URL, por otro lado, a menudo son útiles fuera del código controlador de vista, en todo tipo de clases de servicio / formulario / api / ..., por ejemplo, incluso en modelos si es necesario.
Sí, Rails.application.routes.url_helpers es un módulo, pero eso no significa que debas incluirlo donde sea o que cosas divertidas comiencen a suceder como lo expresó Gary:
https://www.destroyallsoftware.com/blog/2011/one-base-class-to-rule-them-all
Lo que puedes hacer es:
delegate :url_helpers, :to => ''Rails.application.routes''
y luego usar, por ejemplo
url_helpers.home_url