我需要帮助正确形成这个ActiveRecord关联

基本上,用户可以作为(或可能是两者)供应商和作为活动教员的成员参与一个或多个事件。

默认情况下,用户既不是供应商也不是教师,而是在事件的上下文中获得(或两者)状态(例如,用户已作为其成员被接纳为事件)学院)。

看起来我想说的是用户通过供应商或教师链接表中的任何一个(或两个)都有很多事件,但我不确定我是否会在我的Rails模型中表示这一点。 这是我到目前为止所尝试的内容:

class User  vendors has_many :events through => faculty end 

这是我认为我需要进行的查询示例:

 Select * from vendors where user_id = 1; Select * from faculty where user_id = 1; 

有人可以提供一些指导如何正确形成这个ActiveRecord关联?

更新:

所以,我已经尝试使用单表inheritance来解决这个问题,而我最终得到的用户表记录只包含一个用户类型。 虽然仍然使用单表inheritance,但如何让我的用户拥有多种类型? (我知道这实际上是一个多对多的关系;我只是不确定如何使用STI实现这一点。)

 id | first_name | last_name | birth_date | city | zip_code | email | type | created_at | updated_at ----+------------+-----------+------------+------+----------+-------+---------+----------------------------+---------------------------- 1 | Akira | Yamaoka | | | | | Vendor | 2014-08-30 14:58:26.917333 | 2014-08-30 14:58:26.917333 2 | Pyramid | Head | | | | | Faculty | 2014-08-30 15:02:04.70209 | 2014-08-30 15:02:04.70209 

单表inheritance可能就是您所需要的。 简而言之:它允许将具有相同类型数据的多个类放入一个表中。 唯一的要求是该表有一个type列,一个string

基本上,这是常识。 比方说,用户可以获得一个事件的通行证:供应商的通行证和教员通行证。 他可能都有。 让我们创建一个Pass模型,记住我们需要不同类型的模型。 但我们稍后会用它。 现在让我们坚持使用has_many through

 rails g model Pass type:string user:references event:references 

迁移它,我们不再需要修改我们的数据库了。 我们只修改Ruby。 我们应该有一个类Pass ,我们需要在关联中标记它的作用:

 class Pass < ActiveRecord::Base belongs_to :user belongs_to :event end 

行。 然后我们将有这种UserEvent

 class Event < ActiveRecord::Base has_many :passes has_many :users, through: :passes end class User < ActiveRecord::Base has_many :passes has_many :events, through: :passes end 

这是STI魔术的来源。 让我们再创建两个类。

 rails g model VendorPass --no-migration --parent=Pass rails g model FacultyPass --no-migration --parent=Pass 

我们已经生成了一些没有数据库表的类(我们不需要它们)。 它们是空的,我们不会改变它:它们inheritance了Pass ,这就是我们所需要的。 但是我们需要在UserEvent和new pass之间创建一些额外的关联。 最后,我发现这个工作:

 class Event < ActiveRecord::Base # We already had this has_many :passes has_many :users, through: :passes # New stuff! has_many :vendor_passes has_many :vendors, through: :vendor_passes, source: :user has_many :faculty_passes has_many :faculty_members, through: :faculty_passes, source: :user end class User < ActiveRecord::Base # We already had this has_many :passes has_many :events, through: :passes # New stuff! has_many :vendor_passes has_many :vendor_events, through: :vendor_passes, source: :event has_many :faculty_passes has_many :faculty_events, through: :faculty_passes, source: :event end 

Rails维护自己对VendorPass的理解,这是“它是一个Pass ,其typeVendorPass ”,与FacultyPass相同。

好的部分:

  • 容易想象:数据结构看起来很健全且合乎逻辑
  • 我们可以自由添加更多类型的Pass es而无需更改数据库

坏的部分:

  • 无法将额外的字段仅添加到Pass特定子类:它们都在同一个表中
  • 协会看起来有点重复和繁琐
  • Rails只允许typestring ,而不是要比较的最快类型

假设每个活动都有一张个人独有的门票,一个活动,并说明该人是否被录取为教职员工或供应商。

 class User < ActiveRecord::Base has_many :tickets has_many :events, through: :tickets end class Event < ActiveRecord::Base has_many :tickets has_many :users, through: :tickets end class Ticket < ActiveRecord::Base belongs_to :event belongs_to :user belongs_to :vendor belongs_to :faculty end class Faculty < ActiveRecord::Base has_many :tickets end class Vendor < ActiveRecord::Base has_many :tickets end