使用accepts_nested_attributes_for创建新记录或更新现有记录

时间:2010-09-15 01:12:30

标签: ruby-on-rails nested-forms

阅读最新信息以获取最新信息。

嘿大家,

我在rails应用程序中有多对多的关系,涉及三个表:用户表,兴趣表和加入user_interests表,它还具有评级值,因此用户可以对每个表进行评级兴趣以1-10的比例。

我基本上在寻找一种方式让新用户在未来的日期注册和编辑他们的评级以及他们同时的任何个人资料信息。

我试图遵循这个问题Rails nested form with has_many :through, how to edit attributes of join model?,但我遇到的问题是尝试将选择列表合并到混合中,并有多种兴趣为用户评分。

型号代码:

user.rb
has_many :user_interests, :dependent => :destroy
has_many :interests, :through => :user_interests, :foreign_key => :user_id  
accepts_nested_attributes_for :user_interests

interest.rb
has_many :user_interests, :dependent => :destroy
has_many :users, :through => :user_interests, :foreign_key => :interest_id, :dependent => :destroy

user_interest.rb
belongs_to :user
belongs_to :interest

查看代码:

app/views/user/_form.html.erb
<%= form_for(@user) do |form| %>
  ... user fields
  <%= form.fields_for :user_interests do |ui_form| %>
    ... loop through ALL interests
    <% Interest.all.each do |interest| %>
      <%= ui_form.select :rating, options_for_select(1..10) %>
      <%= ui_form.hidden_field :interest_id, :value => interest.id %>
    <% end %>
  <% end %>
<% end %>

我还在控制器@user.interests.build.build_interest

中的新/编辑操作中包含以下内容

我遇到的问题是,当我想拥有多个时,只有一个兴趣评级在params哈希中传递。此外,我收到rails抛出的异常

Interest(#2172840620) expected, got Array(#2148226700)

导致问题的是我错过了什么细节或错误?

编辑:

我找到了一种方法可以强制执行此操作但是需要在chrome开发人员工具中手动编辑HTML,我的表单元素的:name属性生成为user[user_interests_attributes][rating]但是如果我将其更改为{{1当我更新记录时它会起作用。但是,我无法手动指定:绑定到表单对象的表单元素的名称。那么我该怎样做才能证明多个利息评级正在传递而不仅仅是铁路公司认为的一个?

BIG Update:

嘿伙计们,我有一个半功能版本会有一些细微的变化:

查看代码:

user[user_interests_attributes][][rating]

控制器代码:

<% form.fields_for :user_interests do |ui_form| %>
<p>
    <%= ui_form.select :rating, options_for_select(1..5), :selected => :rating %>
    <%= ui_form.label :interest_title %>
    <%= ui_form.hidden_field :interest_id %>
</p>
<% end %>

现在我可以编辑并在没有评级的情况下更新或创建我的user_interests,但是当我尝试创建新用户时,我收到用户为空的错误。此外,我无法访问表单中的任何兴趣属性以显示用户实际评级的兴趣。任何人都可以帮助解决这些警告吗?

1 个答案:

答案 0 :(得分:3)

你只需要@user.interests.build,因为它有一个has_many关系。 build_interest用于存在has_one / belongs_to关系。

使用fields_for :user_interests时,您告诉用户模型在创建/更新用户时,一个或多个user_interest对象的实例将位于参数哈希中。表单不是创建或更新任何user_interests,而是发回一个user_interest_attributes哈希数组,表示表单引用的用户的user_interests。这是一个user_interests评级值数组,当您在表单中引用它们时,没有user_interests存在,这是您收到错误的原因。

由于您将范围传递给select表单助手,因此您实际上并未对表单提供任何兴趣以供选择。 select将为user_interests表中的rating列设置一个值,其值介于1和10之间。即使user_interests表具有rating列,也不存在要设置的rating_interest。

在select标记的options散列中传递:multiple => true将创建一个多选列表,但我不认为这是你想要的。我想你想要一个页面上的许多项目,用户可以对其进行评级。

如果您确实希望用户能够选择多种兴趣,那么这就是如何在has_many :through关系中使用fields_for和accepts_nested_attributes_for:

<%= form_for(@user) do |f| %>
  <% f.fields_for :interest_ids  do |interest| %>
    <ul>
      <% Interest.all.each do |choice,i| %>
      <li class="selection">
        <%= interest.check_box [], { :checked => f.object.user_interest_ids.include?(choice.id) }, choice.id, ''  %>
        <%= interest.label [], choice.name %>
      </li>
    <% end %>
    </ul>
  <% end %>
<% end %>