具有多个has_many / belongs_to关联的嵌套模型表单

时间:2013-02-28 02:41:01

标签: ruby-on-rails ruby-on-rails-3.2 nested-forms nested-attributes activemodel

我有三种模式:

class Rate < ActiveRecord::Base
  attr_accessible :user_id, :car_id, :rate

  belongs_to :user
  belongs_to :car
end

class User < ActiveRecord::Base
  attr_accessible :name

  has_many :rates
  accepts_nested_attributes_for :rates
end

class Car < ActiveRecord::Base
  attr_accessible :name

  has_many :rates
  accepts_nested_attributes_for :rates
end

一个控制器:

class UsersController < ResourceController
  def new
    # Assume user is loaded
    @user.rates.build
  end
end

我正在尝试构建一个嵌套表单,该表单将关联用户/汽车列表及其相关费率。

类似的东西:

<% form_for @user do |f| %>
  <%= @user.name %><br />
  <% Car.all.each do |car| %>
    <%= car.name %><br />
    <%= f.fields_for :rates do |r| %>
      <%= r.number_field :rate %>
    <% end %>
  <% end %>
<% end %>

问题在于我希望Rate模型存储数据如下:

USER_ID    CAR_ID    RATE
1          1         10
1          2         20
1          3         30
2          1         40
3          2         50

我无法弄清楚如何正确构建fields_for帮助程序,为user_idcar_id构建适当的参数。

类似的东西:

user[car=1][rate]
user[car=2][rate]

我已尝试使用fields_for这样明确表达:

<%= r.fields_for 'user[car][rate]' %>

但它仍然没有正确构建嵌套参数。 car参数未正确识别。

任何帮助将不胜感激!感谢。

编辑: 控制器动作必须在用户之下。为简洁起见,上面的示例已经缩短,但是其他与用户相关的属性可以通过表单获得,因此必须使用用户控制器。

解答: 我想出了办法。我added my own answer解释了它。

3 个答案:

答案 0 :(得分:1)

<% form_for @user do |f| %>
  <%= @user.name %><br />
   <%= f.fields_for :rates do |r| %>
      <% Car.all.each do |car| %>
      <%= car.name %><br />
      <%= r.number_field :rate %>
    <% end %>
  <% end %>
<% end %>

这可能是您的问题的解决方案。检查一下。

答案 1 :(得分:0)

表单将创建一个新的速率而不是新用户,因此该方法应该在RatesController而不是UsersController。

有了这个逻辑,问题似乎就解决了。您可以撰写field_for rate[user]field_for rate[car]

答案 2 :(得分:0)

我想我已经明白了。

在我的控制器中,我修改了构建方法,如下所示:

Car.all.each { |c| @user.rates.build(car_id: c.id) } if @user.rates.count == 0

然后,在我的模型中,我需要以下内容:

attr_accessible :rates_attributes

最后,fields_for块应该如下所示(记住,这是在@user表单对象f中):

<%= f.fields_for :rates do |r| %>
  <%= r.hidden_field :car_id %>
  <%= r.object.car.name %><br />
  <%= r.number_field :rate %>
<% end %>

这会正确构建params散列,并在提交表单时创建速率模型条目。

检查控制器中的现有用户费率将确保在表单中使用现有值并且不构建新的(我认为构建考虑了......?)。