2

所有的問候,Single-Table Inheritance是我的Rails問題的正確解決方案嗎?

我正在研究Ruby on Rails中的應用程序,我們需要跟蹤每個用戶的一堆外部服務(例如,Facebook,MySpace,Google,SalesForce,Twitter, WordPress等),該應用程序將代表用戶訪問。對於某些服務,我們需要存儲(加密的)用戶名和密碼,對於某些服務我們需要保存OAuth數據,某些OAuth2數據等等。隨着應用程序的增長,我們需要支持更多類型的帳戶,每個帳戶都有自己的一組驗證數據。

每個用戶都可以在應用程序中創建帖子,我們會將這些帖子發送給外部服務以發佈給用戶。然後,我們跟蹤發佈的帖子(Twitter上的推特,Facebook上的likes/shares等)的回覆。

所以:

class User < ActiveRecord::Base 
    has_many :services 
    has_many :posts 
end 

class Post < ActiveRecord::Base 
    belongs_to :user 
    has_many :publishes 
end 

class Publish < ActiveRecord::Base 
    has_one :service 
    belongs_to :post 
end 

class Service < ActiveRecord::Base 
    belongs_to :user 
    belongs_to :publish 
end 

我使用單表繼承了我的Service類型(例如,WordpressServiceFacebookServiceTwitterService,並簡單地序列化一個簡單的散列保存認證數據),並使用之爭一個傳統的,規範化的計劃,其中每種服務都是自己的模型和表格。我希望能夠輕鬆遍歷與用戶關聯的所有服務,並且發佈需要能夠關聯到任何類型的服務(例如,發佈可能發送到WordPress,Facebook或Twitter) 。

使用傳統的標準化方法可以實現這種模型關係嗎?或者這正是STI想要解決的問題?

謝謝。

回答

0

儘管我仍然不確定是否是解決此問題的「正確」方法,但我已決定使用單表繼承,以便我可以輕鬆獲取所有列表中的其他模型(因爲Service的每個子類也是Service,所以我可以撥打model_instance.services來獲得它們全部)。

爲了解決代碼重複的問題,我創建了一個模塊用於任何模型應該has_many :services以及每種類型的服務:

module HasServices 
    extend ActiveSupport::Concern 
    included do 
    has_many :services 
    has_many :facebook_services 
    has_many :twitter_services 
    has_many :wordpress_services 
    end 
end 

Service也知道它的子類,從而使菜單等可以很容易地創建:

class Service < ActiveRecord::Base 

    @child_classes = [] 

    ... 

    protected 

    def self.inherited(child) 
     @child_classes << child 
     super 
    end 

    def self.child_classes 
     @child_classes 
    end 
end 
0

您將存儲多少百萬個用戶,您每秒鐘會查詢多少次?總的來說,你的物理設計會受到這種類型的存儲器的影響,但硬件將克服大量應用程序的設計缺陷。如果您不是在大規模日期或大批量交易中操作,那麼您可以在任何情況下處理任何事情。

+0

嗨,斯蒂芬妮,謝謝你的回答 - 但我更多地指的是Rails框架本身的模型關係。我現在回頭澄清了我現在清醒的問題。 :) – 2010-09-23 15:08:03

+0

使用數據庫設計標記它會讓我困惑。 – 2010-09-23 19:56:56

2

您可能要檢查出omniauth plugin這是很容易設置和處理存儲認證證書的多項服務的開箱即用。有幾個railscast展示瞭如何設置它。如果沒有別的,你可以看看他們如何建議存儲的東西。

2

作爲替代STI,可以使用多態關聯:

class AccountAuth < AR::Base 
    belongs_to :account 
    belongs_to :authentication, :polymorphic => true 
end 
# account_id   :integer 
# authentication_id :integer 
# authentication_type :string 

module Auth 
    #common logic 
end 

class FacebookAuth < AR::Base 
    include Auth 
    has_one :account_auth,:as=>:authentication 
    has_one :account, :through => :account_auth 
end 

class Account < AR::Base 
    has_many :account_auths 
    has_many :authentications, :through => :account_auths 
end 

Thisthis可以幫助你。

相關問題