Digamos que tengo un modelo de rieles llamado Thing. 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 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 modelo en sí. 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 hay una razón real por la que el enrutamiento solo funciona en el controlador y ve las capas de la aplicación? Puedo pensar en muchos casos en los que el código del modelo puede necesitar tratar con URL (integración con sistemas externos, etc.).
fuente
Respuestas:
En los rieles 3, 4 y 5 puede usar:
p.ej
fuente
:host
opción en todas partes y configúrela una vez en los archivos de configuración de su entorno:Rails.application.routes.default_url_options[:host] = 'localhost:3000'
include Rails.application.routes.url_helpers
funciona para mí en Rails 4.1He encontrado la respuesta sobre cómo hacer esto yo mismo. Dentro del código del modelo, solo pon:
Para rieles <= 2:
Para rieles 3:
Esto mágicamente hace que
thing_path(self)
devuelva la URL de la cosa actual, oother_model_path(self.association_to_other_model)
devuelva alguna otra URL.fuente
include Rails.application.routes.url_helpers
También puede encontrar el siguiente enfoque más limpio que incluir todos los métodos:
fuente
undefined local variable or method 'url_helpers' for Event:Class
error ... :(undefined method url_helpers
. Que voy a hacerclass
, como se muestra en la respuesta. Si su clase de modelo ya se extiende, ¿< ApplicationRecord
esto no funcionará?Cualquier lógica que tenga que ver con lo que se muestra en la vista debe delegarse en un método auxiliar, ya que los métodos en el modelo son estrictamente para el manejo de datos.
Esto es lo que puedes hacer:
fuente
Realmente me gusta seguir una solución limpia.
Es de http://hawkins.io/2012/03/generating_urls_whenever_and_wherever_you_want/
fuente
Si bien puede haber una forma, tendería a mantener ese tipo de lógica fuera del Modelo. Estoy de acuerdo en que no debe poner eso en la vista ( mantenerlo delgado ), pero a menos que el modelo devuelva una url como un dato al controlador, el material de enrutamiento debe estar en el controlador.
fuente
(Editar: olvidar mi balbuceo anterior ...)
Ok, podría haber situaciones en las que irías al modelo o a alguna otra URL ... Pero realmente no creo que esto pertenezca al modelo, la vista (o tal vez el modelo) suena más apropiado.
Sobre las rutas, hasta donde yo sé, las rutas son para las acciones en los controladores (que usualmente usan "mágicamente" 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 mucha gente aquí hablando de rutas a modelos (hasta el punto en que estoy empezando a creerlo), pero como lo entiendo: las rutas van a los controladores. Por supuesto, muchos controladores son controladores para un modelo y a menudo se le llama
<modelname>sController
(por ejemplo, "UsersController" es el controlador del modelo "Usuario").Si se encuentra escribiendo cantidades desagradables de lógica en una vista, intente mover la lógica a un lugar más apropiado; la lógica de solicitud y comunicación interna probablemente pertenece al controlador, la lógica relacionada con los datos se puede colocar 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 pantalla se colocaría en un asistente.
fuente