这是我解决这个问题的方法。 (请注意,在接下来的内容中,我显然只包括最相关的行。)
在模型中可能有多个验证,甚至可能报告多个错误的方法。
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
根据您的设置,您可能需要也可能不需要将模型数据(例如 order)保存到会话中。我这样做是为了将数据传回原始控制器,从而能够再次在那里设置订单。
无论如何,为了显示实际的错误和闪烁消息,我执行了以下操作(在 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