验证失败后未呈现的混淆,新操作

时间:2013-01-06 20:58:08

标签: ruby-on-rails ruby

所以我有以下代码:

def new 
    @all_areas = Area.all
    @area = Area.new
end

我在all_areas中传递的原因是表单中的下拉框需要它,使用mongoid和Area可以递归嵌入另一个区域。

我的表单包含以下代码:

 <% if @all_areas %>
        <%= f.label :parent_area %>
        <%= f.collection_select(:parent_area, @all_areas, :_id, :name, prompt: "Select a Parent...") %>
    <% end %>

但是,当我提交'无效值,即空白名称时,'新'页面不会呈现选择框以选择父级。

这里发生了什么?这是一个错误吗?

我的创建操作非常简单,如果验证失败,我只需执行以下操作:

else
     render 'new'

为什么@all_areas第二次没有传递给视图?我实际上通过将我的创建操作中的代码更改为以下内容来修复它:

else
    @all_areas = Area.all
    render 'new'

但这是相当令人惊讶的,除非我错过了什么?

1 个答案:

答案 0 :(得分:1)

这不是一个错误。行为的原因是create操作实际上与new操作完全分开,因此您在new中分配的实例变量不会被转移。 render 'new'只会呈现名为“new”的视图,但实际上并不会调用new操作。

当您向new发出GET请求时,会发生

/areas/new。当您createPOST时会发生/areas。因为它们是单独的请求,服务器不记得任何状态 - 实际上,您可以在不调用create的情况下调用new(例如,如果您使用命令行中的curl)。

基本上,您的方法是正确的,您需要在两个操作中设置@all_areas实例变量。您可能希望将其提取到单独的私有方法中以避免重复。