Вложенная форма Rails 3 не создается - PullRequest
0 голосов
/ 02 июня 2011

Модели, с которыми я работаю, выглядят так:

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 или выражений.Как будто нет ничего доступного.Но, если вы видите мой контроллер, я сделал ComplexAssertion.new, который я бы хотел создать зависимые объекты автоматически;Я предполагаю, что я не прав?

Я отлаживаю через RubyMine, и когда я оцениваю ComplexAssertion.new, я вижу только 5 атрибутов, пять из которых определены только для этого объекта, но не из реляционных объектов.Что я делаю неправильно?

РЕДАКТИРОВАТЬ Похоже, если я сделаю следующее:

@complex_assertion = ComplexAssertion.new
@complex_assertion.expression_groups.build
@complex_assertion.expressions.build

И измените мою форму для использования:

<%= f.fields_for :expressions do |e| %>

вместо eg.fields_for , он показывает формы.

Это НЕ дает мне правильное вложение.Я думал, что смогу сделать:

@complex_assertion.expression_groups.expressions.build

, но он говорит мне, что выражения - это неопределенный метод.

1 Ответ

1 голос
/ 02 июня 2011

Да, вы должны явно создать экземпляр связанных объектов.Это не сделано для вас.

@complex_assertion.expression_groups.expressions.build

Не будет работать, поскольку expression_groups - это массив, а не отдельная группа выражений.Итак, после создания групп выражений выполните следующие действия:

@complex_assertion.expressions_groups.each do |group|
  group.expressions.build
end

Также вы можете заменить 2-ю строку на следующую, а также создать несколько выражений

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.Таким образом, мы используем это, чтобы сообщить второму fields_for, где найти нужные ему объекты модели выражения.Это означает, что eg.object указывает на объект модели expression_group.

Я надеюсь, что это помогает и имеет смысл.Кроме того, я ничего не проверял и только указываю на то, что выглядит неуместно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...