重定向后的验证消息

时间:2010-05-12 13:45:01

标签: ruby-on-rails validation redirect

我们有一个表单,可以在我们的views / restaurants / show.html.erb中的某个餐厅提交评分。如果存在验证错误,我们会将其重定向回views / restaurants / show.html.erb,但不会显示验证消息。我们发现这是因为我们在RatingController创建操作中使用redirect_to(@restaurant)丢失了消息。但是如果没有重定向我们怎么能回来呢?

谢谢!

5 个答案:

答案 0 :(得分:4)

以下是我解决这个问题的方法。 (请注意,在下文中,我显然只包括最相关的行。)

在模型中可能存在多个验证,甚至可能报告多个错误的方法。

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

同样,控制器动作可以设置闪光消息。最后,用户可能已在输入字段中输入数据,我们希望它也能在redirect_to中持续存在。

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

根据您的设置,您可能需要也可能不需要将模型数据(例如订单)保存到会话中。我这样做的目的是将数据传回原始控制器,从而能够再次设置订单

在任何情况下,为了显示实际的错误和Flash消息,我执行了以下操作(在views/shared/_flash_messages.html.erb中,但您可以在application.html.erb或其他任何对您的应用有意义的地方执行此操作)。这要归功于该行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 -->

要明确的是,常规Flash消息(如通知,警报等)将成为字符串,但由于上述调用为errors.to_a

,因此错误将成为数组

答案 1 :(得分:2)

您可以在Flash消息上传递错误

flash[:error] = @restaurant.errors

您需要在重定向中显示它

答案 2 :(得分:2)

以下是我如何继续进行重定向:

就在您将控制器存储错误中的验证错误重定向到@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

然后在您的评级表单中,您在呈现表单之前为评级对象分配错误:

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

答案 3 :(得分:1)

您可以使用render代替redirect_to

render :action => "show"

或再次设置flash[:error]flash[:notice],因为它们会自动重置

答案 4 :(得分:0)

在评论中做出澄清后,您需要设置

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

这一行

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