基本上,用户可以作为(或可能是两者)供应商和作为活动教员的成员参与一个或多个活动。
默认情况下,用户既不是供应商也不是教师,而是在事件的上下文中获得(或两者)状态(例如,用户已被录取为事件)教职员工。)
似乎我想说的是用户通过供应商或教师链接表中的任何一个(或两者)有很多事件,但我不确定我是否会在我的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 :(得分: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
好的。然后我们会有User
和Event
:
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
的理解,这是&#34;它是Pass
,其type
是VendorPass
&#34;,与FacultyPass
。
好的部分:
Pass
es而无需更改数据库不良部分:
Pass
的特定子类中:它们全部在同一个表中type
成为string
,而不是最快的比较类型答案 1 :(得分: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