2008-12-31 79 views
2

我想知道什么是最好的方式来建模关系,其中一个对象正好与另一个类的n个对象相关联。我想将has_one关系扩展到n的特定值。ActiveRecord has_n关联

例如,TopFiveMoviesList将属于用户并具有恰好五个电影。我会想象底层的sql表会有像movie_id_1,movie_id_2,... movie_id_5这样的字段。

我知道我可以做一个has_many关系,并限制模型级别的孩子数量,但我宁愿没有中间表。

回答

1

我的第一个直觉是使用连接表,但如果这不合意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。今天我懒。)

1

我假设你的意思是“实施”而不是“模型”?在UML中建模非常简单,比如说,您有一个由5个Movie实体组成的Person实体。

但是,当你说has_one时,难度会降到has_5。如果它是一个简单的标量值,则has_one可能是父实体的属性。 Has_5可能是2个通过UML中的“由...构成”关系相互关联的实体。

要回答的主要问题可能是“你能保证它始终是'前5名'吗?”如果是,请使用列进行建模,如您所述。如果不是,则用另一个实体进行建模。

另一个问题可能是“重构有多容易?”如果它很简单,嘿,从5列开始,并重构分离的实体,如果它改变了。

像往常一样,“最佳”取决于业务和技术环境。

2

我想通过一个连接模型实施这一模式将是你最好的在这里下注。它允许List模型担心List逻辑和Movie模型担心Movie逻辑。您可以创建一个Nomination(名称不是最伟大的,但您知道我的意思)模型来处理电影和列表之间的关系,并且当限制为5时,您可以仅限制您撤回的提名数量。

有几个原因我认为这种方法更好。

首先,假设您希望能够遍历关系(movie.listslist.movies),那么5列方法将变得更加复杂。

尽管ActiveRecord支持has n关系会更好,但它不会,所以你会在那个框架上打架。此外,在这种情况下,我与has n的关系似乎有点脆弱。我还没有看到ActiveRecord中的那种实现,尽管我真的很感兴趣看到它发生。 :)