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