En utilisant Rails 3, y a-t-il un moyen d'utiliser link_to helper, ou n'importe quel assistant à l'intérieur du modèle?
Réponses
Trop de publicités?Il ya quelques raisons qui vous pouvez avoir besoin de link_to dans un modèle. Oui, @andy, c'est une violation de la MVC, mais cela ne signifie pas que vous devriez obtenir des points pour ne pas répondre à la question.
@schwabsauce, il est plus facile que cela. La première ligne n'est pas encore strictement nécessaire si vous le faites dans un initialiseur ou quelque chose. Même chose travaille .désinfecter et .raw et un tas d'autres impressionnant de fonctions.
ActionView::Base.send(:include, Rails.application.routes.url_helpers)
ActionController::Base.helpers.link_to(whatever)
Si vous souhaitez utiliser autopaths vous pourriez avoir à faire ce à l'intérieur de votre link_to:
Rails.application.routes.url_helpers.page_path(@page)
Soyez très prudent en suivant les conseils décrits dans le Mandrin de la poste si vous ne le faites pas dans les Rails 3.2.1 . Il semble comme si cette approche n'est pas une bonne façon de le faire, y compris la link_to aide dans le non-affichage de classes dans les Rails 3.2.1. Il y a un moyen plus sûr (qui travaille pour nous en tout cas) décrites ci-dessous.
Lorsque nous avons utilisé l'approche de Chuck poste dans l'une de nos classes, il a fini par avoir très troublant et difficile à déboguer les conséquences. Il a fini par causer des effets secondaires / bugs que seuls de très spécifique (et rare), les circonstances.
Le problème, aussi loin que nous pouvons dire, c'est que cette ligne:
ActionView::Base.send(:include, Rails.application.routes.url_helpers)
Dit ActionView::Base
d'inclure l' Rails.application.routes.url_helpers
qui ActionView::Base
apparemment déjà fait sur son propre. Avoir incluent l' url_helpers
un deuxième temps, semble provoquer une ré-initialisation de l'état des routes (@_routes dans les classes qui ont inclus la ActionDispatch::Routage::UrlFor module).
Cela conduit à apparemment aléatoire et inexpliquée "undefined method 'url_for' for nil:NilClass" exceptions dans des vues tenter d'appel, directement ou indirectement, la url_for méthode après l' ActionView::Base
a inclus l' url_helpers
la deuxième fois.
La solution qui a fonctionné pour nous a été lieu de raconter ActionView::Base
d'inclure l' url_helpers
de nouveau, il suffit d'inclure l' UrlHelper
module vous-même où vous pourriez en avoir besoin.
Puis, quand vous avez besoin d'utiliser link_to et d'avoir accès au chemin d'accès, vous pouvez simplement le faire (en supposant que login_path est valable pour votre application):
include ActionView::Helpers::UrlHelper
...
link = link_to('here', Rails.application.routes.url_helpers.login_path)
Il nous a fallu un temps très long et beaucoup de casse-tête pour traquer les bugs causés par le double inclure et je voulais juste avertir les autres d'être prudent lors de peaufiner le comportement des Rails classes de base.
Je travaille avec les inclusions suivantes:
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
Ensuite, dans mon contrôleur, j'ai renseigné l'attribut (la création d'un contrôleur à partir de zéro nécessite une quantité importante de données dans le hachage des arguments).
Lead.controller = self
link_to helper, MVC violation
Ce que Andy a dit,
si vous êtes à la génération de code HTML, dans le modèle, vous avez probablement besoin de prendre un grand temps d'observer ce que vous faites et pourquoi.
URL aides
Url d'autre part est souvent utile en dehors de la vue-contrôleur de code, dans tous les types de services/forme/api/... classes par exemple, même dans les modèles si vous devez.
Oui, Rails.application.les itinéraires.url_helpers est un module, mais cela ne signifie pas que vous devez simplement l'inclure et où de drôles de choses vont commencer à se produire en tant que Gary a dit:
https://www.destroyallsoftware.com/blog/2011/one-base-class-to-rule-them-all
Ce que vous pouvez faire est:
delegate :url_helpers, :to => 'Rails.application.routes'
et puis l'utilisation, par exemple
url_helpers.home_url
Pas sans piratage.
Si vous pensez avoir besoin de link_to
dans un modèle, vous enfreignez probablement certains principes de l' architecture Model-View-Controller .
Un modèle doit constituer un emplacement pour les données et la logique métier, mais la génération de liens est presque certainement un travail pour le contrôleur ou la vue (ou, en particulier pour Rails, dans une classe d'assistance).