2017-03-09 46 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关系。缺点是用法变得越来越难(尽管你可以通过委托来缓解这种情况),更重要的是,你需要小心多个查询和/或连接的性能。