[英]Conditionally Include a Module based on the Instance of a Model Ruby on Rails
在我正在使用的rails应用程序中,我有一个订单模型,订单在技术上有两种类型(报纸和网络),但它们都在订购模型中表示。 Order的子级根据Order的类型而不同,因此用于获取有关订单数据的方法也不同。
我有一个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
通常,在Rails中,此类数据模型将通过“单表继承”(通常缩写为STI)来完成。 您将拥有一个Order类(以及数据库中的相应orders
表), type
具有一个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/
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.