我正在使用我继承的rails网站,并尝试对某些次优模型行为进行故障排除。我有用户,歌曲和songs_download,每个都是自己的模型。
以下是用户模型中的相关行:
has_and_belongs_to_many :downloaded_songs, :class_name => 'Song', :join_table => :song_downloads
来自歌曲模型:
has_and_belongs_to_many :downloaded_users, :class_name => 'User', :join_table => :song_downloads
来自song_downloads模型:
belongs_to :user
belongs_to :song
以下是用户下载歌曲时(在歌曲控制器中)创建新的song_download记录的代码:
SongDownload.create( :song_id => @song.id,
:user_id => current_user.id,
:download_date => Date.today )
我遇到的问题是,一旦用户下载了一首歌曲,如果我尝试从交互式控制台调用下载的用户,请输入以下内容:
Song.find(<some id>).downloaded_users
我找回了用户的完整记录,但返回的对象中的id是SongDownload的主键,而不是用户的主键。所有其他字段都是准确的,但ID不是。
我没有想出这个建模方案,在我看来:has_and_belongs_to_many
可能更适合使用没有明确建模的SongDownload对象,但如果我可以帮助它,我宁愿不彻底改造代码库。在给定当前建模方案的情况下,有没有办法找回正确的用户ID?
非常感谢您的时间和考虑!
贾斯汀
答案 0 :(得分:5)
已经并且属于关系正在被逐步淘汰,有许多人:通过关系。
从好处来看,您不需要更改任何底层结构,只需更改歌曲和用户模型中的关系声明。
class Song < ActiveRecord::Base
has_many :song_downloads
has_many :users, :through => :song_downloads
...
end
class User < ActiveRecord::Base
has_many :song_downloads
has_many :songs, :through => :song_downloads
...
end
现在
Song.find(<some id>).users
返回通过song_downloads表连接到所选歌曲的User对象数组。
答案 1 :(得分:1)
当连接表的列数多于两个外键时,建议使用has_many:through。
class User < ActiveRecord::Base
has_many :song_downloads
has_many :downloaded_songs,
:through => :song_downloads,
:source => :song
end
class Song < ActiveRecord::Base
has_many :song_downloads
has_many :downloaded_users,
:through => :song_downloads,
:source => :user
end
现在,您可以获得已下载特定歌曲的用户列表,如下所示:
Song.find(1).downloaded_users