我对rails非常陌生。我试图找出在两个模型之间创建关系的最有效方法:
这就是我在想的事情。它有意义吗?
class User < ActiveRecord::Base
has_many :songs #songs this user has favorited
end
class Song < ActiveRecord::Base
belongs_to :user #the user whom submitted this song
end
我对这种方法的关注是,我不确定对数据库中每首歌进行查询的效率,只是为了弄清楚特定用户拥有哪些歌曲。有没有不同的方式我应该考虑这个?
顺便说一下,有没有一种方法可以调用属性,而不是它的模型名称。因此,即使模型仍然是“歌曲”,我也可以说User.find(1).songs[0]
User.find(1).favorites[0]
而不是{{1}}。
答案 0 :(得分:7)
用户和歌曲模型之间需要2个独立的关系。也就是说,您需要一个“所有者”关系和一个“最喜欢”的关系。 “所有者”关系可以是一个简单的has_many / belongs_to,就像现在一样。 “最喜欢的”关系是多对多关系,需要一个连接表,用作habtm
表或具有has_many through
关系的第一类模型,如here所述。
通常推荐的方法是使用has_many through
,因为它可以让您更好地控制:
class User
has_many :songs # these are songs 'owned' by the user
has_many :user_favorite_songs
has_many :favorite_songs, :through => :user_favorite_songs # these are the favorites
end
class Song
belongs_to :user
has_many :user_favorite_songs
end
class UserFavoriteSong
belongs_to :user
belongs_to :favorite_song, :class_name => 'Song', :foreign_key => :song_id
end
答案 1 :(得分:2)
这看起来很好。
Rails协会试图最有效 - 不要过早地优化。
您可以为关联名称添加别名:
class User < ActiveRecord::Base
has_many :favorites, class_name: 'Song'
end
无论如何,您可能希望查看:inverse_of
关联选项。
答案 2 :(得分:1)
我没有测试过这段代码,但你需要这样的东西。
class User < ActiveRecord::Base
has_and_belongs_to_many :favorites, :class_name => "Song" #user's favorited songs
end
class Song < ActiveRecord::Base
belongs_to :user #the user who submitted the song
has_and_belongs_to_many :user, :as => :favorite
end
由于多个用户可以收藏一首歌,因此您需要一个“加入表”
CreateUsersFavorites < ActiveRecord::Migration
def up
create_table :users_favorites do |t|
t.references :user
t.references :favorite
end
create_index :users_favorites, :user_id
create_index :users_favorites, :favorite_id
end
def down
drop_table :users_favorites
end
end
此外,我强烈建议您查看rails guide for active record relationships。