Как создать двойную вложенную модель с изюминкой в ​​Rails 3?

Я создаю регистрацию, где у меня есть модели "Персона", "Ребенок" и "Питание". Человек может иметь много детей и может зарегистрировать много блюд для себя, а также много блюд для детей.

Дело в том, что блюда принадлежат только человеку (нет смысла назначать их детям), поэтому у меня есть одна часть творения для питания в форме, а также другое творение под детьми.

Когда я отправляю форму, я получаю сообщение " Не удается массово назначить защищенные атрибуты: ошибка питания" в контроллере пользователя.

Вопрос в том, как я могу создать экземпляры Meals в разделе Children fields_for, не получая эту ошибку и не устанавливая связь между Meals и Children?

Вот моя модель Персона

class Person < ActiveRecord::Base

has_many :meals
has_many :registrations, :dependent => :destroy
has_many :programs, :through => :registrations
has_many :children

attr_accessible :email_address, :first_name, :home_country, :payment, :phone_number,   :price_category, :price_method, :reference_number, :second_name, :meals_attributes, :registrations_attributes, :children_attributes

validate :first_name, :second_name, :home_country, :email_address, :payment, :price_method, :presence => true

accepts_nested_attributes_for :meals, :allow_destroy => true, :reject_if => proc { |attributes| attributes['meal_type'].blank? }
accepts_nested_attributes_for :registrations, :allow_destroy => true
accepts_nested_attributes_for :children, :allow_destroy => true

Моя модель еды

class Meal < ActiveRecord::Base
 attr_accessible :food_type, :meal_date, :meal_type, :person_id, :meal_id

 validate :food_type, :meal_date, :meal_type, :presence => true

 belongs_to :person

end

Новая часть моего контроллера Person

def new
 @person = Person.new
 meal = @person.meals.build
 @meal_dates = ["2013-07-09","2013-07-10","2013-07-11","2013-07-12","2013-07-13","2013-07-14"]
 registration = @person.registrations.build
 child = @person.children.build
 @programs = Program.all

 respond_to do |format|
  format.html # new.html.erb
  format.json { render json: @person }
end

Это детская часть главной формы

<h2>Children</h2>
 <%= f.fields_for :children do |builder| %>
  <%= render "child_fields", :f => builder %>
 <% end %>
 <%= link_to_add_fields 'Add Children', f, :children %>

А ребенок поля с едой

 <fieldset>
  <div class="field">
   <%= f.label :name %><br />
   <%= f.text_field :name %>
  </div>
  <div class="field">
   <%= f.label :age %><br />
   <%= f.number_field :age %>
  </div>
  <div class="field">
   <%= f.label :language %><br />
   <%= f.text_field :language %>
  </div>
  <div class="field">
   <%= f.label :child_care %><br />
   <%= f.check_box :child_care %>
  </div>
  <h3>Child's meals</h3>
  <table>
  <tr>
  <th>Date</th>
  <th>Food type</th>
  <th>Meal type</th>
  </tr>
  <% @meal_dates.each do |meal_date| %>
    <%= f.fields_for :meals do |f3| %>
    <tr>
    <td><%= f3.text_field :meal_date, :value => meal_date %></td>
    <td><%= f3.hidden_field :food_type, :class => 'FoodType', :value => 'vegetarian'%></td>
    <td><%= f3.select(:meal_type, [['Lunch', 1], ['Three Meals', 3], ['None', nil]]) %></td>
    </tr>
    <% end %>
  <% end %>
  </table>

  <%= f.hidden_field :_destroy %>
  <%= link_to "remove", '#', class: "remove_fields" %>
  </fieldset>

Вы можете найти полный код в моем github: https://github.com/szabcsee/brk2013

1 ответ

В моделировании ИМО есть некоторая путаница.

Модель питания, отличающаяся от здравого смысла, на самом деле является своего рода порядком в вашем случае. Имея это в виду, я могу понять логику в принципе.

Для решения вашей проблемы предлагаю добавить поле в модель Meal(заказ). Поле для хранения, кто будет есть эту еду. Имя может быть for_whom, eater или как угодно понятно.

Значение этого поля по умолчанию равно 0, что означает, что эта еда предназначена для самого человека.(Почему не идентификатор этого человека? Потому что вам нужно искать идентификатор ребенка с помощью этого поля. Идентификатор этого человека уже сохранен в заказчике)

Когда человек заказывает еду, он видит вариант ("Радио" или "Выбор"), спрашивая его, для кого предназначена еда. Опция будет заполнена идентификаторами или его детьми, и им самим (как 0).

Если при обработке формы значение параметра больше 0, это будет означать идентификатор ребенка. Тогда вы можете справиться с этим соответственно.

Чтобы показать еду ребенка, просто запросите таблицу еды с идентификатором ребенка.

Другие вопросы по тегам