使用accepts_nested_attributes_for创建新记录或更新现有记录 [英] Use accepts_nested_attributes_for to create new records or update existing

查看:72
本文介绍了使用accepts_nested_attributes_for创建新记录或更新现有记录的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

阅读大更新以获取最新信息.

Read the big update for the latest information.

大家好,

我在Rails应用程序中有一个多对多关系,其中涉及三个表:一个用户表,一个兴趣表和一个联接user_interests表,该表也具有评级值,因此用户可以对每个表进行评级兴趣范围为1-10.

I've got a many-to-many relationship in a rails app that involves three tables: a user table, an interests table, and a join user_interests table that also has a rating value so a user can rate each of their interests on a 1-10 scale.

我基本上是在寻找一种新用户创建的评分方式,这些用户可以在以后注册并同时编辑其任何个人资料信息时对其进行评分.

I am basically looking for a way for a new user to create their rating when they sign up and edit them at a future date along with any of their profile information at the same time.

我尝试遵循此问题

I tried to follow this question Rails nested form with has_many :through, how to edit attributes of join model? but the problem I'm having is trying to incorporate a select list into the mix and having multiple interests to rate for the user.

型号代码:

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哈希中传递一个利率.我也被铁轨抛出了异常

The problem I'm running into is that only one interest rating is being passed in the params hash when I want to have multiple. Also I am getting an exception thrown by rails

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

我错过或弄错了哪些微小的细节导致了问题?

What tiny detail did I miss or get wrong that is causing the problem?

我找到了一种强制执行此方法的方法,但是它需要在chrome开发人员工具中手动编辑HTML,我的表单元素的:name属性生成为user[user_interests_attributes][rating],但是如果将其更改为user[user_interests_attributes][][rating],它将更新记录时可以工作.但是,我无法手动指定与表单对象绑定的表单元素的:name.那么,我该怎么做才能证明正在通过多种利率评级,而不仅仅是Rails认为的一种利率评级?

I found a way to force this to work but it requires manually editing the HTML in chrome developer tools, the :name attribute of my form elements are being generated as user[user_interests_attributes][rating] but if I change it to user[user_interests_attributes][][rating] it will work when I update a record. However I can't manually specify the :name of a form element that is tied to a form object. So what can I do to show that multiple interest ratings are being passed instead of just one that rails thinks?

大更新:

大家好,我得到了一个半功能版本,并做了一些细微的改动:

Hey guys, I got a semi functional version going with some slight changes:

查看代码:

<% 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 %>

控制器代码:

def new
  @user = User.new
  Interest.all.each { |int| @user.user_interests.build({ :interest_id => int.id }) }
end

def edit
  @user = @current_user
  Interest.unrated_by_user_id(@user.id).each { |int| @user.user_interests.build({ :interest_id => int.id }) }
end

现在,如果不存在任何评分,我现在可以编辑和更新或创建user_interests,但是在尝试创建新用户时出现错误,提示用户为空.另外,我无法访问表单中的任何兴趣属性来显示用户实际评分的兴趣.任何人都可以帮助解决这些警告吗?

Now I am able to edit and get my user_interests updated or created if no rating exists, but I get an error that user is empty when I try to create a new user. Also I am unable to access any of the interest attributes in the form to display the interest the user is actually rating. Can anyone help with those caveats?

推荐答案

您只需要@user.interests.build,因为它具有has_many关系. build_interest适用于存在has_one/belongs_to关系的情况.

You only need @user.interests.build because its a has_many relationship. build_interest is for when there is a has_one/belongs_to relationship.

使用fields_for :user_interests时,您要告诉用户模型,在创建/更新用户时,一个或多个user_interest对象的实例将位于参数哈希中.该表单不会创建或更新任何user_interests,而是会向其发送代表该表单引用用户的user_interest_attributes哈希数组,这些哈希表示用户的user_interests.这是一个user_interests评分值数组,当您以表格形式引用它们时,不存在user_interests,这就是您收到错误的原因.

When using fields_for :user_interests you're telling the User model that an instance of one or more user_interest objects will be in the parameters hash when the user is created/updated. The form is not creating or updating any user_interests but it is sending back an array of user_interest_attributes hashes that represent the user_interests for the user the form references. This is an array of user_interests rating values for which no user_interests exist as you reference them in the form which is the reason you get the error.

由于您要将范围传递给select表单帮助程序,因此您实际上并没有为表单提供任何兴趣来进行选择.该选择将为user_interests表中的rating列设置一个值,其值介于1到10之间.即使user_interests表中有一个rating列,也不存在要设置该排名的user_interest.

Since you are passing a range to the select form helper you aren't actually providing any interests to the form for selection. The select will set a value for the rating column in the user_interests table with a value between 1 and 10. No user_interest exists for the rating to be set on even if the user_interests table has a rating column.

传递:multiple => true会创建一个多重选择列表,但我认为这不是您想要的.我认为您希望页面上有很多项目可供用户添加利息等级.

passing :multiple => true in the options hash of the select tag will create a multiple select list but I don't think that is what you want. I think you want many items on a page the user can put an interest rating on.

如果您确实希望用户能够选择很多兴趣,这就是如何在has_many :through关系上将fields_for与accepts_nested_attributes_for一起使用:

If you do want a user to be able to select many interests this is how to use fields_for with accepts_nested_attributes_for on a has_many :through relationship:

<%= 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 %>

这篇关于使用accepts_nested_attributes_for创建新记录或更新现有记录的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆