通过 has_many :through with :conditions 保存连接属性
我有一个如下所示的 Artist 模型:
# 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
检索 features_songs 效果非常好。这里的问题是我无法向艺术家添加新的featured_song,因为由于某种原因“featured”属性设置为“nil”。
这就是我正在尝试的:
ruby-1.9.2-p180 :004 > a = Artist.first
ruby-1.9.2-p180 :005 > a.featured_songs.create(:title => "Title", :user => User.first)
实际结果是:
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]
知道我做错了什么吗?如何在不直接访问连接的情况下正确设置连接属性?
谢谢你!
编辑: 为了使我的问题更清楚:
从艺术家的实例中,我无法通过
featured_songs
关系创建新的精选歌曲保存似乎正在设置所有歌曲属性,除了(最重要的)
featured
由于某种原因,
featured
属性被设置为nil
,这才是真正的问题
I have an Artist model that looks like this:
# 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
Retrieving the featured_songs works perfectly. The issue here is I'm unable to add a new featured_song to an artist because for some reason the 'featured' attribute is set to 'nil'.
This is what I'm attempting:
ruby-1.9.2-p180 :004 > a = Artist.first
ruby-1.9.2-p180 :005 > a.featured_songs.create(:title => "Title", :user => User.first)
The actual result of that is:
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
Notice the: ["featured", nil]
Any idea what i'm doing wrong? How can i properly set attributes on my join without accessing it directly?
thank you!
EDIT:
To make my issue more clear:
From an instance of artist i am unable to create new featured songs through the
featured_songs
relationshipSaves appear to be setting all of the song attributes EXCEPT for (the most important one)
featured
The
featured
attribute is being set tonil
for some reason and this is the real issue here.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我在阅读后找到了可行的解决方案:
https://github.com/rails/ Rails/issues/5178#issuecomment-4181551
技巧是创建一个包含条件的新一阶 has_many 关联,然后运行 has_many :通过那个。
所以,就你而言,它将是:
I found the working solution after reading this:
https://github.com/rails/rails/issues/5178#issuecomment-4181551
The trick is to create a new first-order has_many association that contains the condition, and then run the has_many :through on that.
So, in your case, it would be:
编辑:更新:releases_attributes 以反映 has_many 关系。
杰德尔的回答是正确的。这是由
accepts_nested_attributes_for
解决的问题。has_many
仅描述一种查询记录的机制,而不是更新或创建记录。您列出的属性被更新的原因是因为它们是歌曲对象的一部分。您尝试更新的字段是特色字段,它是
releases
连接表的一部分。accepts_nested_attributes_for
是解决更新嵌套关系问题的工具。如果您想在创建歌曲对象期间添加特色属性(如您在示例中所做的那样),那么您需要将其添加为 Song 类的嵌套属性的一部分。您的
create
将如下所示:注意添加了 _attributes。如果您使用嵌套表单,这正是 Rails 在视图中执行的操作。请参阅 ActiveRecord 源文件 nested_attributes.rb证明。
如果您确实想要一种更简洁的方法来实现此目的,您可以添加一个
Song#create_featured
方法,该方法会将:releases_attributes
哈希合并到#create< 的选项中/代码>。
EDIT: Updated :releases_attributes to reflect has_many relationship.
jaydel's answer is along the right lines. This is a problem solved by
accepts_nested_attributes_for
.has_many
only describes a mechanism to query records, not to update or create them.The reason the attributes you listed are being updated is because they are part of the song object. The field you're trying to update is the featured field, which is part of your
releases
join table.accepts_nested_attributes_for
is the tool to solve the problem of updating nested relationships. If you want to add the featured attribute during creation of a song object (as you do in your example), then you need to add that as part of the nested attributes for the Song class.Your
create
would then look something like this:Note the addition of _attributes. This is exactly what Rails would do in the views if you were using nested forms. See the ActiveRecord source file nested_attributes.rb for proof.
If you really wanted a cleaner way to accomplish this, you could add a
Song#create_featured
method that would merge the:releases_attributes
hash into the options to#create
.允许通过关联保存的关键是为关联模型上的字段提供 attr_accessible 。
在这种情况下,在发布模型上添加行:
The key to allow save through association is to provide attr_accessible to fields on association model.
In this case, add line on Release model: