如何在Rails中为两个表之间的两种不同类型的关系设置has_many关系?

时间:2013-01-11 21:38:10

标签: ruby-on-rails associations rails-activerecord

这是我的架构:

Participant = 
   id: int
   user_id: int
   program_id: int
   ... other fields
end

User = 
   id: int
   name: text
   ... other fields
end

Program = 
   id: int
   user_id:  int # this is the manager of the program
end

所以,用英语:

  • 用户是人。
  • 程序由用户管理。
  • 程序还有一组参与者,每个参与者都是一个用户

在Rails中也是如此:

class Participant
   belongs_to :user
   belongs_to
end

class User
   has_many :programs
   has_many :participants
end

class Program
   has_many :participants
   belongs_to :user
end

请注意,用户确实拥有多个程序,他们管理的程序,以及通过参与者的has_many程序,这是他们参与的所有程序。

我想要的是能够说:

  • a_user.manages_programs
  • a_user.participates_in_programs

因此有两种用户可以使用多种程序。我需要做一些神奇的组合:通过,:as,:class,或类似的东西,但到目前为止我无法弄明白。

继续这个例子还有一个问题。我现在有

class User
  has_many :participations, class_name: "Participant"
  has_many :moderated_programs, class_name: "Program", foreign_key: 'moderator_id'
  has_many :participating_programs, through: :participations, class_name: "Program", source: :program
end

class Participant
  belongs_to :user
  belongs_to :program
end

注意第三行。我想要的是利用这一系列的关联:参与者有一个user_id和一个program_id。我希望能够说出u1.participating_programs并获得该用户参与的一个或多个程序的列表,但上述内容无法正常工作。你能说出我离开的地方吗?

2 个答案:

答案 0 :(得分:2)

我同意Charles的观点,你有一些令人困惑的措辞/语言问题。参与可能是一个更好的术语。我不建议在这里使用多态 - 用户可能有两个不同的角色,但用户不会是不同的类型。特别是如果经理也可以成为参与者......

class User
  has_many :participations
  has_many :programs, through: :participations
  has_many :managed_programs, class_name: 'Program'
end

class Program
  belongs_to :manager, class_name: 'User'
  has_many :participations
  has_many :users, through: :participations
end

# Just a join table.  Nothing special
class Participation
  belongs_to :user
  belongs_to :program
end

答案 1 :(得分:1)

首先,只是一种语言:我不认为用户有很多参与者。他 是参与者,或者项目的经理。所以他宁愿参与很多。

您可以按如下方式编写:

class User
    has_many :participations, class_name: "Participant"
    has_many :managed_programs, class_name: "Program"
end

此外,至少在上面的代码中,参与者类缺失

belongs_to :user

由于您似乎需要区分两种不同类型的用户,因此polymorphic功能会派上用场。那么您不需要额外的参与者表。 See here