web-dev-qa-db-fra.com

Comment mélanger et appeler link_to depuis le contrôleur dans Rails?

Cela semble être une question noob, mais la réponse simple m'échappe. Je dois appeler link_to dans une méthode ActionController pour cracher un lien HTML. ActionView::Helpers::UrlHelper.link_to appels url_for, mais cela appelle la version du module AV au lieu du contrôleur. J'ai réussi à contraindre cela à faire ce que je voulais en mettant

  #FIXME there must be a better way to mixin link_to
  alias_method :self_url_for, :url_for
  include ActionView::Helpers::UrlHelper
  alias_method :url_for, :self_url_for

dans le contrôleur. Mais, je ne sais toujours pas pourquoi cela fonctionne exactement. Quelqu'un pourrait-il expliquer la portée de la méthode et la dissimulation qui se produit ici? Quelle est la meilleure façon de mélanger link_to (ou en général, pour n'inclure que certaines méthodes d'un module) afin que je puisse l'appeler dans le contrôleur (générer une chaîne flash avec un lien est le cas d'utilisation.)

S'il vous plaît, pas de cours sur MVC - si quelque chose, link_to doit se trouver dans un module distinct de url_for. À en juger par la quantité de bruit à ce sujet, beaucoup de gens se heurtent à cet accroc apparemment trivial et finissent par perdre une heure à le faire "à la manière de Rails" alors que ce qui est vraiment recherché est un hack d'une minute pour faire fonctionner mon application maintenant. Existe-t-il une "méthode Rails" pour le faire avec des aides peut-être? Ou une meilleure Ruby façon?

51
tribalvibes

Cela ne répond pas vraiment à votre question mais il existe un moyen plus simple

Pour Rails 5 , utilisez le proxy helpers

helpers.link_to '...', '...'

Pour Rails 3 et 4 , puisque vous utilisez l'aide d'un contrôleur, vous pouvez utiliser le view_context

# in the controller code
view_context.link_to '...', '...'

# instead of using your mixin code 
link_to '...', '...'

Pour Rails 2 , puisque vous utilisez l'aide d'un contrôleur, vous pouvez réellement accéder à la variable membre @template de le contrôleur, le @template est la vue et a déjà le UrlHelper mélangé dans

# in the controller code
@template.link_to '...', '...'

# instead of using your mixin code 
link_to '...', '...'

si vous devez utiliser l'URLhelper à partir d'un code autre que le contrôleur, votre solution est probablement la voie à suivre

60
house9

Compatible avec Rails 3,4 et 5:

view_context.link_to
114
Yacine Zalouani

Vous pouvez le faire comme ceci:

ActionController.helpers.link_to("Click Me!", awesome_path)

Mais vraiment, un meilleur endroit pour générer ce lien pourrait être dans un module d'assistance où UrlHelper et d'autres aides liées à la vue sont déjà inclus.

[mise à jour]

Cette approche est obsolète et ne fonctionne plus.

1
brentmc79

J'ai toujours eu des problèmes avec mes propres méthodes d'assistance qui utilisent des méthodes d'assistance intégrées dans un contrôleur avec ActionController.helper.my_method.

Évidemment, utiliser render_to_string pour chaque flash fonctionnerait, mais je ne veux pas créer autant de petits partiels pour chaque flash.

Ma solution a été de créer un petit assistant pour que les contrôleurs exécutent le code en partie.

La méthode d'assistance dans le contrôleur:

def h(&block)
  render_to_string(:partial => 'helper', :locals => {:block => block})
end

Le partiel HAML (helper.html.haml):

= instance_eval &block 

La même chose fonctionnerait dans ERB (helper.html.erb):

<%= instance_eval &block %>

Utilisez-le comme ceci dans votre contrôleur pour appeler la fonction my_custom_helper_function qui est définie dans un assistant:

redirect_to url, :notice => h{my_custom_helper_function}
0
Sascha Konietzke