如何在会话或flash中传递表单错误? [Rails 2.3.5]

时间:2010-04-04 02:23:37

标签: ruby-on-rails forms session rails-flash

我有一个表单的创建操作可能会产生错误(即缺少名字),然后重定向。

问题是,当重定向发生时,这些表单错误会丢失。 如何在会话中传递这些表单错误以原始形式显示(仍应使用之前的详细信息填写,如原始error_messages行为中所示)?

谢谢!


代码:

def create
  @contact = Contact.new(params[:contact])
  if @contact.save
    flash[:notice] = "Sent."
  else
    flash[:notice] = "Error."
  end
end

2 个答案:

答案 0 :(得分:5)

Rails中的约定是呈现原始操作的视图而不是重定向。所以你的代码看起来像这样:

def create
  @contact = Contact.new(params[:contact])
  if @contact.save
    flash[:notice] = 'Sent.'
    redirect_to @contact
  else
    flash.now[:notice] = 'Error.'
    render :new
  end
end

如果需要为new操作执行任何其他设置,请将公共代码提取到私有方法中,并在before_filter中为new和{{create调用它1}}。

答案 1 :(得分:3)

这是一个棘手的问题,我自己遇到了麻烦。我要问的第一个问题是,为什么在发现错误时需要重定向?由于复杂性和可用性问题,迫使您在出现错误时呈现操作是Rails框架设计者的有意识决定。

这是一个大问题,因此在您的操作中,您使用params创建模型实例,对象验证失败,您决定重定向到另一个操作。在重定向到另一个操作之前,您必须将模型实例的当前状态保存到会话,然后重定向到操作:foo。在行动中:foo您必须重新尝试更新属性并通过实例变量将错误传递给视图。这里的问题是你在控制器中耦合动作是一件坏事(一个动作依赖于另一个动作)。还有许多其他问题我可以永远打字,但是如果你只需要为一个资源做这个,那么我就是这样做的:

配置/ routes.rb中

map.resources :things, :member => { :create_with_errors => :get }

things_controller.rb

def new
  @thing = Thing.new
end

def create
  @thing = Thing.create(params[:thing])
  if @thing.save
    redirect_to things_path
  else
    session[:thing] = @thing
    redirect_to create_errors_thing_path(@thing)
  end
end

def create_with_errors
  @thing = session[:thing]
  @errors = @thing.errors
  render :action => :new
end

应用程序/视图/东西/ new.html.erb

<% if defined?(@errors) %>
<% #do something with @errors to display the errors %>
<% end %>

<!-- render the form stuff -->

我知道你在想什么......这很可怕。相信我,我已经做了很多尝试来解决这个问题,我已经意识到,rails开发人员选择的机制是处理错误的最佳和最简单的方法。