在我正在开发的rails应用程序中,我有一个模型订单,订单在技术上有两种类型(报纸和网络),但它们都在订单模型中表示。订单下面的子项根据订单类型而有所不同,因此用于获取订单数据的方法也不同。
我有一个CurrentMonthsOrders序列化程序,我希望能够调用:
order.start_date
order.end_date
无需检查我正在处理的订单类型。所以我希望能够做的是根据我正在处理的订单类型包含模块。这可能/这是解决这个问题的最佳方法吗?
以下是模块:
module WebOrder
def start_date
web_line_items.sort_by(&:start_date).first.start_date
end
def end_date
web_line_items.sort_by(&:end_date).last.end_date
end
end
module Newspaper
def start_date
newspaper_placements.last.date.strftime('%m/%d')
end
def end_date
object.newspaper_placements.first.date.strftime('%Y/%-m/%-d')
end
end
答案 0 :(得分:1)
通常,在Rails中,这种数据模型将通过单表继承(通常缩写为STI)来完成。您将拥有一个Order类(以及数据库中相应的orders
表),它将具有type
列。然后,您将为WebOrder和Newspaper定义Order的子类:
class WebOrder < Order
def start_date
...
end
...
end
class Newspaper < Order
...
end
当WebOrder或Newspaper订单保存到数据库时,Rails会将该类记录在type
列中,当从数据库中提取记录时,Rails将使用type
列创建实例正确的子类。
可以将模块的方法添加到类的特定实例中,但我不推荐它,因为那时你有对象表面上是同一个类,但有不同的代码/行为。此外,它可以导致更高的内存使用量,因为您正在自定义许多单个对象。但如果你这样做,它的工作方式大致如下:
order = Order.new
order.extend(Newspaper)
但是,您必须记住在加载Order实例和调用自定义方法之间的某个时间。如果您使用单表继承,Rails将为您处理它。
这里有一个很好的单表继承解释:http://eewang.github.io/blog/2013/03/12/how-and-when-to-use-single-table-inheritance-in-rails/