2009-08-26 10 views
21

La possibilité d'avoir des messages flash (avis, erreur, avertissement, etc.) avec des liens intégrés est agréable du point de vue de l'interaction de l'utilisateur. Cependant, l'insertion d'une balise d'ancrage dans un message flash du contrôleur est sale.Quelle approche adoptez-vous pour incorporer des liens dans les messages instantanés?

Supposons qu'un message flash comme celui-ci est bon pour la facilité d'utilisation *:

Example Flash Message Notice with an Embedded Link http://img.skitch.com/20090826-xbsa4tb3sjq4fig9nmatakthx3.png (empruntée DailyMile.com)

Quelle tactique prendriez-vous entre le contrôleur et la vue d'employer quelque chose comme c'est propre?

Répondre

24

Je pensais juste que je partage, puisque la réponse trouvée que je cherchais ailleurs:

Travaux sur des rails 3,1

flash[:notice] = "Proceed to #{view_context.link_to('login page', login_path)}".html_safe 
+0

merci pour cela. impressionnant. – Dty

+0

merci de mettre à jour cette question avec une réponse rails 3.1! – jpwynn

+0

Faire ceci comme nouvelle réponse acceptée. C'est beaucoup plus clair que l'approche que je prenais auparavant. Je n'étais pas au courant de l'accesseur 'view_context'. –

1

Vous pouvez créer une méthode d'assistance pour restituer les partiels en fonction de la valeur transmise dans le message flash.

+0

Cela se sent presque comme trop de séparation. Où gérez-vous l'objet ou le chemin qui doit être lié sans s'appuyer sur des variables d'instance de type global dans les partiels? –

8

Glenn Gillen a une approche qu'il appelle Useful Flash Messages in Rails.

J'ai modifié ses extraits de code pour qu'ils soient un peu plus idiomatiques (pour moi au moins).

Le contrôleur remplit le flash comme ceci:

flash[:notice]  = "Your profile was updated. %s" 
flash[:notice_item] = ["Edit again?", edit_profile_path(@profile)] 

Vous pourriez alors des aides qui ont l'air quelque chose comme ceci:

def render_flash_messages(*keys) 
    messages = keys.collect do |key| 
    content_tag(:p, flash_message_with_item(key), :class => "flash #{key}") if flash[key] 
    end.join 
    content_tag(:div, messages, :id => "flash_messages") unless messages.blank? 
end 

def flash_message_with_item(key) 
    item = flash["#{key}_item".to_sym] 
    substitution = item.is_a?(Array) ? link_to(*item) : item 
    flash[key] % substitution 
end 

La vue ressemble simplement ceci:

<%= render_flash_messages(:error, :notice, :warning) %> 

La vue (via l'assistant flash_message_with_item) est responsable de la création de l'étiquette d'ancrage , mais le contrôleur gère ce qui va dans le message flash, y compris une ressource optionnelle pour d'autres actions.

+3

J'espérais des suggestions plus avisées, mais je vais suivre cette approche pour l'instant. –

1

Ceci est similaire à link_to() in Rails flash

# In your controller 
flash[:error] = render_to_string(:partial => "sessions/login_failed_message") 

# In sessions/_login_failed_message.html.erb 
Login failed. If you have forgotten your password, you can #{link_to('reset it', reset_path)}