In the rails app I am working on I have a model Order, Order technically has 2 types (newspaper and web) but they are both represented in the Order Model. The children below Order are different based on the type of Order and thus the methods used to obtain data about the orders are different.
I have a CurrentMonthsOrders serializer where I would like to be able to call:
order.start_date
order.end_date
without having to check what type of Order I am dealing with. So what I would like to be able to do is include the module based on the type of Order I am dealing with. Is this possible/is this the best way to go about this problem?
Below are the modules:
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
Typically, in Rails, this sort of data model would be done via Single Table Inheritance (often abbreviated STI). You would have an Order class (and corresponding orders
table in the database), which would have a type
column. Then you would define subclasses of Order for WebOrder and Newspaper:
class WebOrder < Order
def start_date
...
end
...
end
class Newspaper < Order
...
end
When WebOrder or Newspaper orders are saved to the database, Rails will record the class in the type
column, and when records are pulled from the database, Rails will use the type
column to create instances of the correct subclass.
It is possible to add the methods of a module to a particular instance of a class, but I wouldn't recommend it in general, because then you have objects which are ostensibly the same class, but have different code/behavior. Also, it can lead to higher memory usage, since you are customizing many individual objects. But if you were to do it, it would work roughly like this:
order = Order.new
order.extend(Newspaper)
You'd have to remember to do that sometime between loading your Order instance and calling the customized methods, though. If you use Single Table Inheritance, Rails will take care of it for you.
There's a pretty good explanation of Single Table Inheritance here: http://eewang.github.io/blog/2013/03/12/how-and-when-to-use-single-table-inheritance-in-rails/