我想知道什么是最好的方式来建模关系,其中一个对象正好与另一个类的n个对象相关联。我想将has_one关系扩展到n的特定值。ActiveRecord has_n关联
例如,TopFiveMoviesList将属于用户并具有恰好五个电影。我会想象底层的sql表会有像movie_id_1,movie_id_2,... movie_id_5这样的字段。
我知道我可以做一个has_many关系,并限制模型级别的孩子数量,但我宁愿没有中间表。
我想知道什么是最好的方式来建模关系,其中一个对象正好与另一个类的n个对象相关联。我想将has_one关系扩展到n的特定值。ActiveRecord has_n关联
例如,TopFiveMoviesList将属于用户并具有恰好五个电影。我会想象底层的sql表会有像movie_id_1,movie_id_2,... movie_id_5这样的字段。
我知道我可以做一个has_many关系,并限制模型级别的孩子数量,但我宁愿没有中间表。
我的第一个直觉是使用连接表,但如果这不合意User.movie[1-5]_id
列将适合该法案。 (我认为movie1_id
适合用Rails约定比movie_id_1
更好。)
既然你标记这个Rails和ActiveRecord的,我会添加一些没有经过充分测试,可能有些错误的模型代码我的答案。 :)
class User < ActiveRecord::Base
TOP_N_MOVIES = 5
(1..TOP_N_MOVIES).each { |n| belongs_to "movie#{n}".to_sym, :class_name => Movie }
end
你可以包装在一个宏风格的方法行,但除非如果这是你的应用程序的通用模式,这样做将可能只是让你的代码更难与小DRY利益阅读。
您可能还需要添加验证以确保用户列表中没有重复的影片。
将您的电影课程关联回您的用户是类似的。
class Movie < ActiveRecord::Base
(1..User::TOP_N_MOVIES).each do |n|
has_many "users_list_as_top_#{n}".to_sym, :class_name => User, :foreign_key => "movie#{n}_id"
end
def users_list_as_top_anything
ary = []
(1..User::TOP_N_MOVIES).each {|n| ary += self.send("users_list_as_top_#{n}") }
return ary
end
end
(当然,这users_list_as_top_anything
可能会更好写出为明确的SQL。今天我懒。)
我假设你的意思是“实施”而不是“模型”?在UML中建模非常简单,比如说,您有一个由5个Movie实体组成的Person实体。
但是,当你说has_one时,难度会降到has_5。如果它是一个简单的标量值,则has_one可能是父实体的属性。 Has_5可能是2个通过UML中的“由...构成”关系相互关联的实体。
要回答的主要问题可能是“你能保证它始终是'前5名'吗?”如果是,请使用列进行建模,如您所述。如果不是,则用另一个实体进行建模。
另一个问题可能是“重构有多容易?”如果它很简单,嘿,从5列开始,并重构分离的实体,如果它改变了。
像往常一样,“最佳”取决于业务和技术环境。
我想通过一个连接模型实施这一模式将是你最好的在这里下注。它允许List
模型担心List逻辑和Movie
模型担心Movie逻辑。您可以创建一个Nomination
(名称不是最伟大的,但您知道我的意思)模型来处理电影和列表之间的关系,并且当限制为5时,您可以仅限制您撤回的提名数量。
有几个原因我认为这种方法更好。
首先,假设您希望能够遍历关系(movie.lists
和list.movies
),那么5列方法将变得更加复杂。
尽管ActiveRecord支持has n
关系会更好,但它不会,所以你会在那个框架上打架。此外,在这种情况下,我与has n
的关系似乎有点脆弱。我还没有看到ActiveRecord中的那种实现,尽管我真的很感兴趣看到它发生。 :)