我正在尝试找出为以下场景设置数据库和模型的最佳方法。
用户可以喜欢无限数量的歌曲。 一首歌可以被无数用户喜欢过一次。
我有这些表格: 歌曲,用户,喜欢等...遵循RoR惯例。
名为likes的表具有以下外键:user_id,song_id。还有一个名为“时间”的字段,用于在喜欢这首歌时保存时间戳。
我不确定如何做到这一点,我希望能够在我的控制器中使用这样的代码:
User.find(1).likes.all 这不应该从likes表返回,而是加入歌曲表并输出用户喜欢的所有歌曲。
在遵循惯例的Ruby on Rails中实现此目的的最佳实践是什么?
答案 0 :(得分:3)
除非您需要专门对likes
表数据采取行动,否则模型本身可能不是必需的。关系很简单:
class User < ActiveRecord::Base
has_and_belongs_to_many :songs
end
class Song < ActiveRecord::Base
has_and_belongs_to_many :users
end
这将加入当前不存在的song_users表。但是既然你想让它通过喜欢加入,你就可以改变每一个:
has_and_belongs_to_many :songs, :join_table => 'likes'
如果您希望能够调用User.find(1).likes并获取歌曲,请将用户的版本更改为:
class User < ActiveRecord::Base
has_and_belongs_to_many :likes, :join_table => 'likes', :class_name => 'Song'
end
您可以将歌曲版本更改为以下内容:
class Song < ActiveRecord::Base
has_and_belongs_to_many :liked_by, :join_table => 'likes', :class_name => 'User'
end
这将为您提供Song.find(1).liked_by.all并为您提供用户(如果您想使用第一个版本,可以将其保留给用户)
有关habtm关系的更多详细信息,请访问:http://apidock.com/rails/ActiveRecord/Associations/ClassMethods/has_and_belongs_to_many
如果您因任何原因想要在连接表上操作(您发现自己需要特定于连接的方法),可以通过以下方式包含模型:
class User < ActiveRecord::Base
has_many :songs, :through => :likes
has_many :likes
end
class Like < ActiveRecord::Base
belongs_to :user
belongs_to :song
end
class Song < ActiveRecord::Base
has_many :users, :through => :likes
has_many :likes
end
这样您就可以User.find(1).songs.all
,但User.find(1).likes.all
会为您提供加入数据