Ruby on rails 通过保存连接属性有很多:通过:条件

Ruby on rails 通过保存连接属性有很多:通过:条件,ruby-on-rails,activerecord,data-modeling,relationship,has-many-through,Ruby On Rails,Activerecord,Data Modeling,Relationship,Has Many Through,我有一个艺术家模型,看起来像这样: # app/models/artist.rb class Artist < ActiveRecord::Base # Relationships has_many :releases has_many :songs, :through => :releases has_many :featured_songs, :through => :releases, :

我有一个艺术家模型,看起来像这样:

# app/models/artist.rb
class Artist < ActiveRecord::Base
  # Relationships
  has_many  :releases
  has_many  :songs, :through => :releases
  has_many  :featured_songs,  :through => :releases,
                              :class_name => "Song",
                              :source => :song,
                              :conditions => { 'releases.featured', true }                         

end
a.songs.create(:title => 'Title', :user => User.first, :releases_attributes => [{ :id => 123, :featured => true}])
实际结果是:

ruby-1.9.2-p180 :004 > a = Artist.first
ruby-1.9.2-p180 :005 > a.featured_songs.create(:title => "Title", :user => User.first)
  User Load (0.9ms)  SELECT `users`.* FROM `users` LIMIT 1
  SQL (1.0ms)  BEGIN
  SQL (5.5ms)  INSERT INTO `songs` (`created_at`, `title`, `updated_at`, `user_id`) VALUES (?, ?, ?, ?)  [["created_at", Thu, 11 Aug 2011 18:30:34 UTC +00:00], ["title", "Title"], ["updated_at", Thu, 11 Aug 2011 18:30:34 UTC +00:00], ["user_id", 1]]
  SQL (1.2ms)  INSERT INTO `releases` (`album_id`, `artist_id`, `created_at`, `featured`, `song_id`, `updated_at`) VALUES (?, ?, ?, ?, ?, ?)  [["album_id", nil], ["artist_id", 1], ["created_at", Thu, 11 Aug 2011 18:30:34 UTC +00:00], ["featured", nil], ["song_id", 6], ["updated_at", Thu, 11 Aug 2011 18:30:34 UTC +00:00]]
   (0.1ms)  COMMIT
注意:
[“特色”,无]

知道我做错了什么吗?如何在不直接访问连接的情况下正确设置连接的属性

谢谢大家!

编辑: 为了让我的问题更加清楚:

  • 从艺人的实例来看,我无法通过
    特色歌曲
    关系创建新的特色歌曲

  • 保存似乎是设置除(最重要的一个)
    特色之外的所有歌曲属性

  • 由于某种原因,
    featured
    属性被设置为
    nil
    ,这才是真正的问题所在


您可以在模型中为使用接受嵌套属性。我会先看关于这个主题的文章,然后仔细阅读文章本身,寻找方法

编辑:

从下面的评论可以清楚地看出,我并不完全理解你的要求。我以为您想知道如何从模型创建和操作连接的对象。当我最近需要这样做时,我有两个模型:

class User < ActiveRecord::Base
  belongs_to :address

  accepts_nested_attributes_for :address
end

class Address < ActiveRecord::Base
  has_one :user
end

并且我的地址在我的用户上并保持不变。这就是你要找的吗?我要说的是,我并不完全清楚这转化为多对多关联的有效性,但我假设这是一样的。也许是因为一对一依赖于一列作为外键,但当它涉及到与实际联接表的更复杂的关联时,它就不起作用了?至少您可以进一步调查这种可能性…

编辑:更新:发布属性以反映多种关系

杰德尔的回答是正确的。这是一个通过
接受
的_嵌套的_属性_解决的问题
有很多
只描述了一种查询记录的机制,而不是更新或创建记录

您列出的属性被更新的原因是它们是歌曲对象的一部分。您试图更新的字段是特色字段,它是您的
releases
join表的一部分

接受_嵌套的_属性_for
是解决更新嵌套关系问题的工具。如果要在创建song对象的过程中添加featured属性(如示例中所示),则需要将其添加为song类的嵌套属性的一部分

class Song < ActiveRecord::Base
  has_many :releases
  has_many :artists, :through => :releases
  accepts_nested_attributes_for :releases
end
注意添加了_属性。这正是Rails在视图中使用嵌套表单时所做的。请参阅ActiveRecord源文件以获取证据


如果你真的想用一种更简洁的方法来实现这一点,你可以添加一个
Song#create#featured
方法,将
:释放属性
散列到
#create
选项中。允许通过关联进行保存的关键是提供关联模型上的字段可访问的属性

在这种情况下,在发布模型上添加行:

attr_accessible :song_id, :feature_id

在阅读了以下内容后,我找到了有效的解决方案:

诀窍是创建一个包含条件的新的一阶has\u many关联,然后在此基础上运行has\u many:through

因此,在您的情况下,它将是:

class Artist < ActiveRecord::Base
  # Relationships
  has_many  :releases
  has_many  :songs, :through => :releases

  has_many  :featured_releases, :class_name => "Release", :conditions => { :featured => true }
  has_many  :featured_songs, :through => :featured_releases, :source => :song
end
class-Artist:发行
有很多:特色发布,:class\u name=>“Release”,:conditions=>{:特色发布=>true}
有很多:精选歌曲,:通过=>:精选歌曲发行,:来源=>:song
结束

我没有提到接受嵌套集合。接受的\u嵌套的\u属性\u用于通过关联整体保存连接的对象。Create,在接受散列时接受表单中的参数,但如果您手动使用Create,则其工作方式相同。如果你有一些更深入的见解可以让我直截了当,请大家分享。我的意思是
接受。它不是关于
接受的\u嵌套的\u属性\u。作者写道,相关的
条件
语句没有执行。这是真的。另外,如果我们对
使用
accepted\u nested\u attributes\u,它将不会执行,因为它将调用相同的方法。因此,如果您知道答案,请回答问题。你的“单位”比我大,我们都同意,现在告诉我们正确的答案是什么…所以我现在正在做我自己的项目。model_1.model_2.build({…})相当于创建一个……我显然不明白这与他想要的有什么不同。你能指出这一点吗?不知何故,你知道我错了,我想知道的不仅仅是“你错了”。你肯定有理由认为/知道这是错的。晚些时候编辑你的第二条评论会更有帮助。谢谢你,我期待明天收到你的来信:我只想确认两件事:1-
接受\u嵌套的\u属性\u:releases
应该只放在歌曲模型中吗?换句话说,我实际使用的模型(艺术家)不接受嵌套属性(似乎有点奇怪?)2-我尝试了您提供的代码,得到了以下错误:
NoMethodError:undefined method'to_i'for:featured:Symbol
for#1-是。当您获取一个艺术家实例(您的
a
变量)并调用
.songs
时,您实际上得到了
Song
对象的
数组。试试a.songs.first.class,你会看到一首歌。实际上,
a.songs
返回一个
ActiveRelation
对象,但是Rails通过ruby的强大功能(即尝试
a.songs.class
)向您隐藏了这个事实。不要链接
create
,而是尝试仅使用标题和用户参数链接方法
build
。然后,您可以在控制台中玩游戏,在保存对象之前检查对象。对于#2-您可以发布堆栈跟踪吗?我可能有多种方法混合在一起
attr_accessible :song_id, :feature_id
class Artist < ActiveRecord::Base
  # Relationships
  has_many  :releases
  has_many  :songs, :through => :releases

  has_many  :featured_releases, :class_name => "Release", :conditions => { :featured => true }
  has_many  :featured_songs, :through => :featured_releases, :source => :song
end