我正在使用的模型如下所示:
class ComplexAssertion < ActiveRecord::Base
has_many :expression_groups
has_many :expressions, :through => :expression_group
accepts_nested_attributes_for :expression_groups, :allow_destroy=>true
end
class ExpressionGroup < ActiveRecord::Base
belongs_to :complex_assertion
has_many :expressions
accepts_nested_attributes_for :expressions, :allow_destroy=>true
end
class Expression < ActiveRecord::Base
belongs_to :expression_group
end
我的表格如下:
<%= form_for(@complex_assertion) do |f| %>
<div id="mainAssertionGroup" style="border:1px; border-style:solid; width:1000px; padding:5px">
<div class="field">
<%= f.label :title %>: <%= f.text_field :title, :size=>'10' %>
<%= f.label :description %>: <%= f.text_field :description, :size=>'25' %>
<%= f.label :scope %>: <%= f.text_field :scope, :size=>'1' %>
Test
Category: <%= collection_select(:complex_assertion, :assertion_category_id, AssertionCategory.all, :id, :name, {:include_blank=>"UNCATEGORIZED"}) %>
</div>
<div id="initialGroup" style="border:1px; margin-left:10px; margin-top:10px; border-style:solid; width:850px;">
<div class="childGroup1" style="padding:5px;">
<%= f.fields_for :expression_groups do |eg| %>
<%= eg.fields_for :expressions do |e| %>
Type: <%= e.collection_select :assertion_type_id, AssertionType.all, :id, :name %>
Attribute: <%= e.collection_select :attribute_name, Attribute.find_by_sql("select distinct a.name from attributes a "), :name, :name %>
<%= e.label :operator_type_id %>
: <%= e.collection_select :operator_type_id, OperatorType.all, :id, :value %>
Value: <%= e.text_field :value, :size=>'1' %>
<% end %>
<div id="innerOperator">
<%= eg.collection_select :logical_operator_type_id, LogicalOperatorType.all, :id, :value %>
</div>
<% end %>
</div>
</div>
</div>
<div id="createComplex" align="center">
<%= f.submit :value=>'Submit' %>
</div>
<% end %>
我的控制器看起来像:
def new_complex_assertion
@complex_assertion = ComplexAssertion.new
end
当我加载页面时,我只加载表单的ComplexAssertion部分,而不会为ExpressionGroups或Expressions返回任何内容。好像什么都没有。但是,如果你看到我的控制器,我做了一个ComplexAssertion.new,我认为它会自动创建依赖对象;我想我错了?
我正在通过RubyMine进行调试,当我评估ComplexAssertion.new时,我只看到5个属性,这5个属性只为该对象定义,没有关系对象。我做错了什么?
编辑看起来如果我做以下操作:
@complex_assertion = ComplexAssertion.new
@complex_assertion.expression_groups.build
@complex_assertion.expressions.build
并将我的表格更改为使用:
<%= f.fields_for :expressions do |e| %>
它显示的不是的eg.fields_fo,而是形式。
这不会给我正确的嵌套。我想我应该能够做到:
@complex_assertion.expression_groups.expressions.build
但它告诉我表达式是一种未定义的方法。
是的,您必须显式实例化关联的对象。这不是为你做的。
@complex_assertion.expression_groups.expressions.build
将不起作用,因为expression_groups是一个数组,而不是单个表达式组。因此,在创建表达式_groups后,请执行以下操作:
@complex_assertion.expressions_groups.each do |group|
group.expressions.build
end
此外,您还可以将第二行替换为以下内容,以创建多个表达式
2.times do { group.expressions.build }
至于将fields_for与嵌套模型一起使用,请使表单中的代码看起来如下:
<%= f.fields_for :expression_groups, @complex_assertions.expression groups do |eg| %>
<%= eg.fields_for :expressions, eg.object.expressions do |e| %>
我将尝试解释发生了什么。:expressions_groups
告诉fields_for它将为哪类对象渲染字段,我添加的第二部分告诉fields_for在哪里找到要为其渲染字段的对象。如果我们传入一个数组(在本例中就是这样),它将自动在数组上迭代。在每次迭代中,它都会将我们正在处理的当前模型对象放入一个名为object
的变量中,该变量存储在fields_for返回的表单生成器实例中。因此,我们使用它来告诉第二个字段在哪里可以找到所需的表达式模型对象。这意味着eg.object
指向一个expression_group
模型对象。
我希望这会有所帮助,并且有意义。此外,我没有测试任何东西,只是指出了看起来不合适的地方。