好的,所以我有一个关于如何最好地解决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
表。这可以按照我的意图运作,但感觉很草率。
有更好的方法吗?
答案 0 :(得分: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
关系。缺点是使用变得更加困难(尽管您可以通过委派来缓解这种情况),更重要的是,您需要小心多个查询和/或连接的性能损失。