在 Rails 上有条件地包含基于模型实例 Ruby 的模块
Conditionally Include a Module based on the Instance of a Model Ruby on Rails
在我正在开发的 rails 应用程序中,我有一个订单模型,订单在技术上有 2 种类型(报纸和网络),但它们都在订单模型中表示。 Order下面的children根据Order的类型不同,因此获取订单数据的方法也不同。
我有一个 CurrentMonthsOrders 序列化程序,我希望能够在其中调用:
order.start_date
order.end_date
无需检查我正在处理的订单类型。所以我希望能够做的是根据我正在处理的订单类型包含模块。 possible/is 这是解决这个问题的最佳方法吗?
以下是模块:
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 中,这种数据模型将通过单一 Table 继承(通常缩写为 STI)来完成。您将有一个订单 class(以及数据库中相应的 orders
table),它会有一个 type
列。然后,您将为 WebOrder 和 Newspaper 定义 Order 的 subclasses:
class WebOrder < Order
def start_date
...
end
...
end
class Newspaper < Order
...
end
当 WebOrder 或 Newspaper 订单保存到数据库时,Rails 将在 type
列中记录 class,当从数据库中提取记录时,Rails 将使用 type
列创建正确子 class.
的实例
可以将模块的方法添加到 class 的特定实例,但我通常不推荐这样做,因为这样你具有表面上相同 class,但具有不同 code/behavior 的对象。此外,它会导致更高的内存使用量,因为您要自定义许多单独的对象。但如果你要这样做,它的工作原理大致如下:
order = Order.new
order.extend(Newspaper)
不过,您必须记住在加载 Order 实例和调用自定义方法之间的某个时间执行此操作。如果您使用单一 Table 继承,Rails 会为您处理。
Single Table Inheritance 在这里有一个很好的解释:http://eewang.github.io/blog/2013/03/12/how-and-when-to-use-single-table-inheritance-in-rails/
在我正在开发的 rails 应用程序中,我有一个订单模型,订单在技术上有 2 种类型(报纸和网络),但它们都在订单模型中表示。 Order下面的children根据Order的类型不同,因此获取订单数据的方法也不同。
我有一个 CurrentMonthsOrders 序列化程序,我希望能够在其中调用:
order.start_date
order.end_date
无需检查我正在处理的订单类型。所以我希望能够做的是根据我正在处理的订单类型包含模块。 possible/is 这是解决这个问题的最佳方法吗?
以下是模块:
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 中,这种数据模型将通过单一 Table 继承(通常缩写为 STI)来完成。您将有一个订单 class(以及数据库中相应的 orders
table),它会有一个 type
列。然后,您将为 WebOrder 和 Newspaper 定义 Order 的 subclasses:
class WebOrder < Order
def start_date
...
end
...
end
class Newspaper < Order
...
end
当 WebOrder 或 Newspaper 订单保存到数据库时,Rails 将在 type
列中记录 class,当从数据库中提取记录时,Rails 将使用 type
列创建正确子 class.
可以将模块的方法添加到 class 的特定实例,但我通常不推荐这样做,因为这样你具有表面上相同 class,但具有不同 code/behavior 的对象。此外,它会导致更高的内存使用量,因为您要自定义许多单独的对象。但如果你要这样做,它的工作原理大致如下:
order = Order.new
order.extend(Newspaper)
不过,您必须记住在加载 Order 实例和调用自定义方法之间的某个时间执行此操作。如果您使用单一 Table 继承,Rails 会为您处理。
Single Table Inheritance 在这里有一个很好的解释:http://eewang.github.io/blog/2013/03/12/how-and-when-to-use-single-table-inheritance-in-rails/