2010-09-06 92 views
3

我知道有很多的資源在這一點,但我有相關的任何人到我的情況,所以我希望有人能幫助我澄清是如何工作的一個艱難的時期:幫助理解polymophic協會(導軌)

基本上,我有一個模型Action(它會在用戶做某些事情會影響另一個用戶時創建,例如評論他們的文章或對某人的照片進行投票),這些操作將在用戶儀表板頁面中列出,已經發生的與他們有關的行爲,如流...有點像Github的「新聞饋送」

Github's "News Feed"

我決定去創造一個多態關聯,這裏是我的模型看起來像:

class Action < ActiveRecord::Base 
    belongs_to :instigator, :polymorphic => true 
    belongs_to :victim, :polymorphic => true 
end 

我用始作俑者和受害者,因爲任何人都可以創建這些動作,這又總是影響其他用戶,這裏是我的User模型

class User < ActiveRecord::Base 
    has_many :actions, :as => :instigator 
    has_many :actions, :as => :victim 
end 

而這正是我想我會錯,因爲最終我想有,當我運行像User.find(1).actions查詢實際返回的所有研究所其中用戶既是instigatorvictim,我認爲我不能同時擁有這兩個have_many,因爲當像這樣使用時,我只能得到用戶爲victim的實例。

這裏是我的移民:

create_table :actions do |t| 
    t.references :instigator, :polymorphic => true 
    t.references :victim, :polymorphic => true 
    t.string :action_performed 
    t.references :resource, :polymorphic => true 
    t.timestamps 
end 

感謝您的幫助,我永遠愛偉大的建議和幫助多所社區給予。

+0

資源看起來像一個很好的候選人多態關係,但除非有比這可能需要對教唆者或受害者的角色用戶的其他實體始作俑者和受害者不應該是多態的。 – 2010-09-06 09:55:46

回答

2

這提醒了經典的友誼模型問題。多態聯繫除了重點之外。

的Rails版本無關的解決方案:

class User < ActiveRecord::Base 
    has_many :instigator_actions, :class_name => "Action", :as => :instigator 
    has_many :victim_actions, :class_name => "Action", :as => :victim 
    has_many :actions, :finder_sql => ' 
     SELECT a.* 
     FROM actions a 
     WHERE (a.instigator_type = "User" AND instigator_id = #{id}) OR 
       (a.victim_type  = "User" AND victim_id  = #{id})' 
end 

在創建操作使用他們的前兩個協會的一個創造。

u1.instigator_actions.create(:victim => u2) 

OR

u1.victim_actions.create(:instigator => u2) 

同時你可以得到與使用actions關聯的用戶相關聯的操作的列表。

u1.actions 
1

首先,我建議你通過Single table Inheritance使用角色。在你的用戶表中,你可以有一個類型列來標識某人是煽動者還是受害者。 (當然,如果有人是兩個人,他將有2排,所以你將不得不確保你沒有名稱作爲主鍵。)

所以現在你有一個更結構化的佈局。出現多態性問題,請嘗試使用不同的接口。如在,

class Action < ActiveRecord::Base 
    belongs_to :actionable, :polymorphic => true 
end 

可操作性不必是一個單獨的類。它只是一個給界面的名字。在協會的另一邊就像明智一樣。

Obie Fernandez的Rails Way爲您提供了一個清晰的圖像,因此您可以將它引用到多態關聯上。