2014-08-29 111 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