ror rails form examples ruby-on-rails rails-routing helpermethods

ruby on rails - form - ¿Se pueden usar Rails Routing Helpers(es decir, mymodel_path(modelo)) en los modelos?



routes rails examples (6)

Digamos que tengo un modelo de rieles llamado Thing. Thing tiene un atributo url que puede configurarse opcionalmente como una URL en algún lugar de Internet. En el código de vista, necesito una lógica que haga lo siguiente:

<% if thing.url.blank? %> <%= link_to(''Text'', thing_path(thing)) %> <% else %> <%= link_to(''Text'', thing.url) %> <% end %>

Esta lógica condicional en la vista es fea. Por supuesto, podría construir una función auxiliar, que cambiaría la vista a esto:

<%= thing_link(''Text'', thing) %>

Eso resuelve el problema de verbosidad, pero realmente preferiría tener la funcionalidad en el propio modelo. En cuyo caso, el código de vista sería:

<%= link_to(''Text'', thing.link) %>

Esto, obviamente, requeriría un método de enlace en el modelo. Esto es lo que debería contener:

def link (self.url.blank?) ? thing_path(self) : self.url end

Hasta el punto de la pregunta, thing_path () es un método no definido dentro del código del modelo. Supongo que es posible "introducir" algunos métodos de ayuda en el modelo, pero ¿cómo? ¿Y hay una razón real por la que el enrutamiento solo funciona en el controlador y vea las capas de la aplicación? Puedo pensar en muchos casos en los que el código de modelo deba lidiar con las URL (integración con sistemas externos, etc.).


Cualquier lógica que tenga que ver con lo que se muestra en la vista debe delegarse a un método auxiliar, ya que los métodos en el modelo son estrictamente para el manejo de datos.

Esto es lo que podrías hacer:

# In the helper... def link_to_thing(text, thing) (thing.url?) ? link_to(text, thing_path(thing)) : link_to(text, thing.url) end # In the view... <%= link_to_thing("text", @thing) %>


En los carriles 3, 4 y 5 puedes usar:

Rails.application.routes.url_helpers

p.ej

Rails.application.routes.url_helpers.posts_path Rails.application.routes.url_helpers.posts_url(:host => "example.com")


He encontrado la respuesta con respecto a cómo hacer esto yo mismo. Dentro del código del modelo, simplemente ponga:

Para rieles <= 2:

include ActionController::UrlWriter

Para los carriles 3:

include Rails.application.routes.url_helpers

Esto mágicamente hace que thing_path(self) devuelva la URL de la cosa actual, u other_model_path(self.association_to_other_model) devuelva alguna otra URL.


Si bien podría haber una manera en la que tendería a mantener ese tipo de lógica fuera del Modelo. Estoy de acuerdo en que no debe poner eso en la vista ( manténgalo delgado ), pero a menos que el modelo esté devolviendo una URL como parte de los datos al controlador, el enrutamiento debe estar en el controlador.


También puede encontrar el siguiente enfoque más limpio que incluir todos los métodos:

class Thing delegate :url_helpers, to: ''Rails.application.routes'' def url url_helpers.thing_path(self) end end


(Edit: Olvide mi balbuceo anterior ...)

Ok, podría haber situaciones en las que iría al modelo oa alguna otra url ... Pero realmente no creo que esto pertenezca al modelo, la vista (o tal vez el modelo) suena más apropiada.

Acerca de las rutas, que yo sepa, las rutas son para las acciones en los controladores (que usualmente "mágicamente" usan una vista), no directamente a las vistas. El controlador debe manejar todas las solicitudes, la vista debe presentar los resultados y el modelo debe manejar los datos y entregarlos a la vista o al controlador. He escuchado a muchas personas aquí hablando sobre rutas a modelos (hasta el punto en que casi estoy empezando a creerlo), pero, según tengo entendido, las rutas van a los controladores. Por supuesto, muchos controladores son controladores para un modelo y, a menudo, se les llama <modelname>sController (por ejemplo, "UsersController" es el controlador del modelo "User").

Si se encuentra escribiendo cantidades desagradables de lógica en una vista, intente mover la lógica a algún lugar más apropiado; la lógica de comunicación interna y de solicitud probablemente pertenece al controlador, la lógica relacionada con los datos puede ubicarse en el modelo (pero no la lógica de visualización, que incluye etiquetas de enlace, etc.) y la lógica que está relacionada únicamente con la visualización se ubicaría en un ayudante.