Disons que j'ai un modèle Rails appelé Thing. La chose a un attribut url qui peut éventuellement être défini sur une URL quelque part sur Internet. Dans le code d'affichage, j'ai besoin d'une logique qui effectue les opérations suivantes:
<% if thing.url.blank? %>
<%= link_to('Text', thing_path(thing)) %>
<% else %>
<%= link_to('Text', thing.url) %>
<% end %>
Cette logique conditionnelle dans la vue est moche. Bien sûr, je pourrais créer une fonction d'aide, qui changerait la vue en ceci:
<%= thing_link('Text', thing) %>
Cela résout le problème de verbosité, mais je préférerais vraiment avoir la fonctionnalité dans le modèle lui-même. Dans ce cas, le code d'affichage serait:
<%= link_to('Text', thing.link) %>
Cela nécessiterait évidemment une méthode de liaison sur le modèle. Voici ce qu'il devrait contenir:
def link
(self.url.blank?) ? thing_path(self) : self.url
end
Au point de la question, thing_path () est une méthode non définie dans le code du modèle. Je suppose qu'il est possible de "tirer" certaines méthodes d'aide dans le modèle, mais comment? Et y a-t-il une vraie raison pour laquelle le routage ne fonctionne qu'au niveau du contrôleur et des couches d'affichage de l'application? Je peux penser à de nombreux cas où le code du modèle peut avoir besoin de gérer les URL (intégration avec des systèmes externes, etc.).
la source
Réponses:
Dans Rails 3, 4 et 5, vous pouvez utiliser:
par exemple
la source
:host
option partout et définissez-la une fois dans vos fichiers de configuration d'environnement:Rails.application.routes.default_url_options[:host] = 'localhost:3000'
include Rails.application.routes.url_helpers
fonctionne pour moi dans Rails 4.1J'ai trouvé la réponse concernant la façon de procéder moi-même. Dans le code du modèle, mettez simplement:
Pour les rails <= 2:
Pour Rails 3:
Cela fait comme par magie
thing_path(self)
renvoyer l'URL de la chose actuelle, ouother_model_path(self.association_to_other_model)
renvoyer une autre URL.la source
include Rails.application.routes.url_helpers
Vous pouvez également trouver l'approche suivante plus propre que d'inclure toutes les méthodes:
la source
undefined local variable or method 'url_helpers' for Event:Class
erreur ... :(undefined method url_helpers
. Qu'est-ce que je vais faire?class
, comme indiqué dans la réponse. Si votre classe Model s'étend déjà,< ApplicationRecord
cela ne fonctionnera pas?Toute logique liée à ce qui est affiché dans la vue doit être déléguée à une méthode d'assistance, car les méthodes du modèle sont strictement destinées à la gestion des données.
Voici ce que vous pourriez faire:
la source
J'aime vraiment suivre une solution propre.
C'est de http://hawkins.io/2012/03/generating_urls_whenever_and_wherever_you_want/
la source
Bien qu'il puisse y avoir un moyen, j'aurais tendance à garder ce type de logique hors du modèle. Je suis d'accord que vous ne devriez pas mettre cela dans la vue ( gardez-le maigre ) mais à moins que le modèle ne renvoie une URL en tant que donnée au contrôleur, les éléments de routage devraient être dans le contrôleur.
la source
(Edit: Oubliez mon babillage précédent ...)
Ok, il pourrait y avoir des situations où vous iriez soit au modèle, soit à une autre URL ... Mais je ne pense pas vraiment que cela appartienne au modèle, la vue (ou peut-être le modèle) semble plus appropriée.
À propos des itinéraires, pour autant que je sache, les itinéraires sont destinés aux actions des contrôleurs (qui utilisent généralement "par magie" une vue), pas directement aux vues. Le contrôleur doit gérer toutes les demandes, la vue doit présenter les résultats et le modèle doit gérer les données et les servir à la vue ou au contrôleur. J'ai entendu beaucoup de gens ici parler de routes vers des modèles (au point que je commence presque à le croire), mais si je comprends bien: les routes vont aux contrôleurs. Bien sûr, de nombreux contrôleurs sont des contrôleurs pour un modèle et sont souvent appelés
<modelname>sController
(par exemple, "UsersController" est le contrôleur du modèle "User").Si vous vous retrouvez en train d'écrire des quantités désagréables de logique dans une vue, essayez de déplacer la logique dans un endroit plus approprié; la logique de demande et de communication interne appartient probablement au contrôleur, la logique liée aux données peut être placée dans le modèle (mais pas la logique d'affichage, qui inclut les étiquettes de lien, etc.) et la logique qui est purement liée à l'affichage serait placée dans une aide.
la source