【问题标题】:How to create double nested model with a twist in Rails 3?如何在 Rails 3 中创建带有扭曲的双嵌套模型?
【发布时间】:2013-05-05 09:23:35
【问题描述】:

我正在创建一个注册,其中有“Person”、“Child”和“Meal”模型。一个人可以有很多孩子,可以为自己注册很多餐点,也可以为孩子们注册很多餐点。

关键是餐点只属于人(没有必要将它们分配给孩子们),所以我有一个表单中的餐点创作部分,还有另一个孩子们的创作部分。

当我提交表单时,我在 Person 的控制器中收到 Can't mass-assign protected attributes: foods 错误。

问题是,我怎样才能在 Children fields_for 部分下创建 Meals 实例而不会出现此错误并且不会在 Meals 和 Children 之间建立连接?

这是我的 Person 模型

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

【问题讨论】:

  • 为什么不给孩子分餐?

标签: ruby-on-rails-3.2 nested-forms mass-assignment rails-models


【解决方案1】:

IMO 建模有点混乱。

Meal 模型,不同于常识,在您的情况下实际上是一种订单。考虑到这一点,我基本上可以理解逻辑了。

为了解决您的问题,我建议在 Meal(order) 模型中添加一个字段。该字段用于存储谁将吃这顿饭。名称可以是for_whomeater 或任何可以理解的名称。

该字段的默认值为0,表示这顿饭是给这个人自己的。(为什么不是这个人的id呢?因为你需要用这个字段搜索children的id,这个人的id已经存储在orderer中了)

当一个人点餐时,他会看到一个选项(收音机或选择),询问他这顿饭是给谁的。该选项将填充 ids 或他的孩子,以及他自己(作为 0)。

在处理表单时,如果选项值大于 0,则表示孩子的 id。然后你可以相应地处理它。

要显示孩子的餐点,只需使用孩子的 id 查询餐表即可。

【讨论】:

  • 其实问题不在于谁来吃这顿饭,因为从组织者的角度来看这无关紧要。而是因为质量分配错误,如果 Meal 模型实例位于 Child 的 fields_for 部分下,我将无法保存它。
  • @szabcsee,解决批量分配错误很容易,只需在模型中的 attr_accessible 中添加此字段即可。造型,你决定,我就是觉得有点不自然。
  • 如果您检查,它已经添加到那里。与此同时,我开始为孩子和人分配多态性。
  • @szabcsee,好像没有Child模型?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-03-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多