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

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

嘿大家,

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

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

我试着用has_many来跟踪这个问题Rails嵌套表单:通过,如何编辑连接模型的属性? 但我遇到的问题是试图将选择列表合并到混合中并具有多个兴趣来为用户评分。

型号代码:

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  ... user fields  ... loop through ALL interests    interest.id %>    

我还在我的控制器@user.interests.build.build_interest的新/编辑操作中包含以下@user.interests.build.build_interest

我遇到的问题是,当我想拥有多个时,只有一个兴趣评级在params哈希中传递。 另外我得到了rails引发的exception

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

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

编辑:

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

大更新:

嘿伙计们,我有一个半function版本,稍有改动:

查看代码:

  

:rating %>

控制器代码:

 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,但是当我尝试创建新用户时,我收到用户为空的错误。 此外,我无法访问表单中的任何兴趣属性以显示用户实际评级的兴趣。 任何人都可以帮助解决这些警告吗?

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

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

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

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

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

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