Rails建模问题 - 关系和主键

时间:2009-11-05 22:55:45

标签: ruby-on-rails ruby database model

我正在使用我继承的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?

非常感谢您的时间和考虑!

贾斯汀

2 个答案:

答案 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