¿Se pueden utilizar Rails Routing Helpers (es decir, mymodel_path(model)) en modelos?

Resuelto Aaron Longwell asked hace 16 años • 0 respuestas

Digamos que tengo un modelo Rails llamado Cosa. La cosa tiene un atributo de URL que, opcionalmente, se puede establecer en 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 crear una función auxiliar que cambiaría la vista a esto:

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

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

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

Obviamente, esto 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 indefinido dentro del código del modelo. Supongo que es posible "incorporar" algunos métodos auxiliares al modelo, pero ¿cómo? ¿Y existe una razón real por la que el enrutamiento solo opera en el controlador y en las capas de visualización de la aplicación? Puedo pensar en muchos casos en los que el código modelo puede necesitar lidiar con URL (integración con sistemas externos, etc.).

Aaron Longwell avatar Dec 04 '08 23:12 Aaron Longwell
Aceptado

En Rails 3 y superiores:

Rails.application.routes.url_helpers

p.ej

Rails.application.routes.url_helpers.posts_path
Rails.application.routes.url_helpers.posts_url(:host => "example.com")
Paul Horsfall avatar Mar 28 '2011 07:03 Paul Horsfall

Encontré la respuesta sobre cómo hacer esto yo mismo. Dentro del código del modelo, simplemente ponga:

Para rieles <= 2:

include ActionController::UrlWriter

Para rieles 3:

include Rails.application.routes.url_helpers

Esto hace que mágicamente thing_path(self)se devuelva la URL del elemento actual o other_model_path(self.association_to_other_model)se devuelva alguna otra URL.

Aaron Longwell avatar Dec 04 '2008 16:12 Aaron Longwell