2014-08-29 108 views
0

基本上,用户可以参与一个或多个事件作为供应商或作为该事件的成员。我需要帮助正确组成这个ActiveRecord协会

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

看来我想说的是,用户有很多事件通过供应商或教师连接表(或两者),但我不知道我会去代表这在我的Rails模型。以下是我试过到目前为止:

class User < ActiveRecord::Base 
    has_many :events through => vendors 
    has_many :events through => faculty 
end 

这里有一个查询的样本,我认为我需要做:

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

有人可以提供一些方向如何正确的形成这ActiveRecord协会?

更新:

所以,我一直在使用单表继承来解决问题试过了,我已经结束了与记录只包含一个用户类型的用户表。在仍然使用单表继承的同时,如何让我的用户拥有多种类型? (我知道这基本上是一个多一对多的关系,我只是不知道如何做到这一点使用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 
+0

请提供您需要对该数据进行的查询。当然,指定的内容不正确,因为您列出了两个具有相同名称但参数不同的关联。 – 2014-08-29 19:14:43

+0

更新了原始帖子。 – 2014-08-29 19:38:58

+0

我认为,你可以坚持'has_many ...,通过...',并使用单表继承来建立链接类型:common(不用于直接使用),member和vendor(从common继承)。准备好后我会告诉你更多。随时看看STI如何运作。 – 2014-08-29 21:01:15

回答

2

单表继承可能是你需要的。简而言之:它允许将具有相同类型数据的多个类放入一个表中。唯一的要求是该表具有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 

我们已经生成了一些没有数据库表的类(我们不需要它们)。它们是空的,我们不会改变它们:它们继承了Pass,这就是我们需要的。但是我们需要在User,Event与新通行证之间建立一些额外关联。最后,我发现这个工作:

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只允许type是一个string,不是最快的类型比较
+0

感谢您抽出时间提供这样深入的回复。我想我在这里看到你在做什么。我会思考这一段时间。 – 2014-08-30 17:29:07

+0

这很适合这项法案。你摇滚,伙计。认真。 – 2014-08-30 17:43:45

0

比方说,每一个事件都有一票是唯一的一个人,一个事件,并说这个人是否被录取为教师或供应商。

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