2010-05-12 7 views
4

Nous avons un formulaire pour soumettre des notes pour un certain restaurant dans un de nos vues/restaurants/show.html.erb. S'il y a une erreur de validation, nous sommes redirigés vers views/restaurants/show.html.erb mais les messages de validation n'apparaissent pas. Nous avons compris que cela arrivait parce que nous perdions les messages en utilisant redirect_to (@restaurant) dans notre action de création de RatingController. Mais comment pouvons-nous revenir sans redirection?Messages de validation après redirection

Merci!

+0

Si ma réponse ne va pas au point s'il vous plaît poster un peu plus de détails – tommasop

+0

@ réponse fl00r est ce que vous cherchez! – klew

Répondre

0

Après ces précisions dans le commentaire, vous devez configurer votre

/app/views/layouts/application.html.erb

avec cette ligne

<%- flash.each do |name, msg| -%><%= content_tag :div, msg, :id => "flash_#{name}" %><%- end -%> 
2

Vous pouvez passer votre erreur sur le message flash

flash[:error] = @restaurant.errors 

Après l'avoir besoin d'afficher dans votre redirection

+0

Voulez-vous dire flash [: error] = @ rating.errors? Voilà ce que je mets dans le RatingsController créer une action: si @ rating.save ... autre flash [: error] = @ rating.errors format.html {redirect_to (@restaurant)} fin Et voici comment j'essaie de les imprimer dans views/restaurants/show.html.erb: <% form_for [@restaurant, Rating.new] do | f | %> <% = f.error_messages%> ... Mais rien ne s'affiche. Y a-t-il quelque chose qui ne va pas? (J'ai aussi essayé @ rating.errors). Je suis nouveau à ce sujet. Merci! – user339344

+0

Vous devez ajouter ceci à votre /app/views/layouts/application.html.erb <% - flash.each faire | nom, msg | -%><% = tag_table: div, msg,: id => "flash _ # {nom}"%><%- end -%>. De cette façon, tous vos messages flash seront correctement rendus – tommasop

+0

Cela peut provoquer un CookieErrorOverflow si le formulaire a des entrées – damoiser

1

Vous pouvez utiliser render au lieu de redirect_to

render :action => "show" 

ou un ensemble flash[:error], flash[:notice] à nouveau, car ils automatiquement remis à zéro

4

Voici comment je résolu ce problème. (Notez que dans ce qui suit, je ne vais évidemment inclure que les lignes les plus pertinentes.)

Dans le modèle, il peut y avoir plusieurs validations et même des méthodes pouvant potentiellement générer des rapports sur plusieurs erreurs. En plus

class Order < ActiveRecord::Base 
    validates :name, :phone, :email, :presence => true 
    def some_method(arg) 
    errors.add(:base, "An error message.") 
    errors.add(:base, "Another error message.") 
    end 
end 

, l'action du contrôleur peut définir des messages flash. Enfin, l'utilisateur peut avoir entré des données dans les champs de saisie, et nous voulons qu'il persiste à travers le redirect_to aussi.

class OrdersController < ApplicationController 
    def create 
    @order = Order.new(params[:order]) 
    respond_to do |format| 
     if @order.save 
     session.delete(:order) # Since it has just been saved. 
     else 
     session[:order] = params[:order] # Persisting the order data. 

     flash[:notice] = "Woohoo notice!" # You may have a few flash messages 
     flash[:alert] = "Woohoo alert!" # as long as they are unique, 
     flash[:foobar] = "Woohoo foobar!" # since flash works like a hash. 

     flash[:error] = @order.errors.to_a # <-- note this line 

     format.html { redirect_to some_path } 
     end 
    end 
    end 
end 

En fonction de votre configuration, vous pouvez ou ne pas avoir besoin d'enregistrer les données de modèle, tels que ordre, à la session. Je l'ai fait dans le but de transmettre les données au contrôleur d'origine, et ainsi être en mesure d'installer le ordre là encore. En tout cas, pour afficher l'erreur réelle et les messages flash, j'ai fait ce qui suit (en views/shared/_flash_messages.html.erb, mais vous pouvez le faire en application.html.erb ou partout ailleurs est logique pour votre application). Et cela grâce à cette ligne flash[:error] = @order.errors.to_a

<div id="flash_messages"> 
    <% flash.each do |key, value| 

    # examples of value: 
    # Woohoo notice! 
    # ["The server is on fire."] 
    # ["An error message.", "Another error message."] 
    # ["Name can't be blank", "Phone can't be blank", "Email can't be blank"] 

    if value.class == String # regular flash notices, alerts, etc. will be strings 
     value = [value] 
    end 

    value.each do |value| %> 
     <%= content_tag(:p, value, :class => "flash #{key}") unless value.empty? %> 
    <% end %> 
    <% end %> 
</div><!-- flash_messages --> 

Pour être clair, les messages flash réguliers tels que les avis, les alertes, etc.seront des chaînes, des erreurs seront cependant des tableaux depuis l'appel ci-dessus était errors.to_a

2

Voici comment je l'ai fait faire encore la redirection:

Juste avant vous redirigez sur les erreurs de validation dans vos erreurs magasin de contrôleur à clignoter comme suggéré par @shingara:

if @restaurant_rating.save 
    redirect_to @restaurant, :notice => "Successfully added rating to restaurant." 
else 
    flash[:error] = @restaurant_rating.errors 
    redirect_to @restaurant, :alert => "There were errors to add rating to restaurant. " 
end 

Ensuite, dans votre formulaire pour vous assignez des erreurs notation de retour pour l'objet de notation juste avant le rendu de la forme:

- flash[:error].messages.each {|error| @restaurant_rating.errors.add(error[0], error[1][0]) } if flash[:error] 
= simple_form_for @restaurant_rating do |f| 
    .... 
Questions connexes