一个复杂的has_many通过关系

时间:2013-10-15 12:59:47

标签: ruby-on-rails ruby-on-rails-3 associations has-many-through

我在三种不同的方式之间来回实现has_many通过关系,我需要一些帮助来决定哪种方式最好。

在基本级别,我有Contributor个模型,其中包含个人的详细信息,我有一个Project模型,贡献者可以贡献。他们可以通过多种不同的方式做出贡献; Contributor可以是编辑,作者,作曲家,研究员等。贡献者可以通过多种方式为同一Project做出贡献(例如,他们可以是作曲家和编辑),他们可以贡献多个Projects

所以我设置了一个名为Contributorship的连接模型。我的问题是下一步该做什么。据我所知,我有三个选择:

  1. contribution_type属性添加到Contributorship,其中包含贡献类型(来自预定义的枚举)。当我在ContributorProject之间建立关系时,我将其设置为适当的值。

  2. has_many through上创建多个Project关系,每种类型的贡献一个。每个仍然会解析为Contributor,但在Contributorship上使用不同的外键。

  3. 抛弃Contributorship并将其替换为多个联接模型 - EditorAuthor等等,这些联盟模式全部解析为Contributors

3 个答案:

答案 0 :(得分:2)

选项1听起来干净简单。它还允许您在一个查询中获取所有贡献者,而不管其类型如何。并且您始终可以在Project上创建查找器方法以仅获取编辑器或作者。它还允许非常容易地添加contribution_types。

选项2和3可以工作,但比第一个选项更严格。它们还需要创建更多的表和模型类。

我的建议:选择最简单的解决方案,这些解决方案现在可以使用,并等到需要更复杂关系的新要求时。

答案 1 :(得分:2)

我会选择第一个选项。另外,我会在项目上定义方法以便于访问。

class Project < ActiveRecord::Base
  # ... relations defined
  Contributorship::TYPES.each do |c_type|
    define_method c_type do
      contributors.where( "contributorship.contribution_type" => c_type )
    end
  end
end

答案 2 :(得分:1)

你害怕ContributionType模特吗?

绝对是第一个选项,但我会通过Project模型关联三个模型:ContributorContributionTypeContributorship(新的,而不是枚举)。

这使您最接近现实,并最终在任何未来的动作(模型复杂性,授权等)中给予通用自由。