2017-03-09 64 views
0

好的,所以我有一個關於如何最好地解決rails問題的問題。我將展示我是如何解決這個問題的,但是真的很希望得到關於這種方法的一些反饋意見,以及是否有更好的方法。解決多表繼承問題的最佳途徑

首先,我有一個基本的電子商務應用程序,包括客戶,付款方式和付款。

現在支付方式可以有幾種不同的類型,EG'Stripe,Braintree,Paypal'。這些都是付款方式,但他們有非常不同的邏輯來處理他們的工作。

理想情況下,我希望能夠撥打customer.payment_methods並收到付款方式的關係。我還希望能夠撥打customer.stripe_payment_methods,並獲得Stripe方法。

我最初想到使用和STI模型,但這似乎效率低下,因爲每種付款方式有不同的列它依賴。

在表格中存儲類型字段似乎很浪費。

以下是相關車型

class PaymentMethod 
    scope :stripe, -> {where(type: 'PaymentMethod::Stripe')} 
    scope :paypal, -> {where(type: 'PaymentMethod::Paypal')} 

    # Lists available payment types 
    def self.available_types 
     PaymentMethod.subclasses.map { |d| [d::NAME, d.to_s] } 
    end 
end 

class PaymentMethod::Stripe < PaymentMethod 
    #performs Stripe specific methods 
end 

class PaymentMethod::Paypal < PaymentMethod 
    #performs Paypal specific actions. 
end 

這些都使用payment_methods表。這是按照我的意圖運作的,但感覺馬虎。

有沒有更好的方法來做到這一點?

回答

1

你並不需要範圍。

PaymentMethod.all   # will get you all payments of any type 
PaymentMethod::Stripe.all # will get you only the records using Stripe 
PaymentMethod::Paypal.all # will get you only records using Paypal 

這並不總是理想的,因爲額外的領域。你有幾個選擇:

1)住在重複。大多數數據庫都非常高效,不會浪費太多空間。這個問題更多的是關於在代碼中錯誤地使用它們。

2)使用通用字段名稱和在子類中添加方法轉化爲更好的字段名

3)使用JSON字段類型,並在子類中添加的方法來簡化訪問

4)將特定於Stripe的字段分爲第二個表和Paypal特有的字段。您將有一個Payment has_one :tripe關係。缺點是用法變得越來越難(儘管你可以通過委託來緩解這種情況),更重要的是,你需要小心多個查詢和/或連接的性能。