I'm looking for orientation for either a concrete or abstract approach in Ruby-Like (Rails 4/5) to model the following requirement or user story:
Given a model, let's call it PurchaseOrder with the following attributes:
- amount_to_produce
- amount_taken_from_stock
- placement_date
- delivery_date
- product_id
- client_id
As a user, i want to be able to see a table list of these PurchaseOrder and, when necessary, group them.
Detail Info: When a collection of PurchaseOrder is grouped, that grouped collection should behave exactly like a PurchaseOrder, in the sense that it must be displayed as a record in the table, filtering operations should work on the grouped record as they do on single PurchaseOrder instances, same goes for pagination and sorting. Moreover, the group must cache or at least i'm thinking it that way, the sum of amount_to_produce, amount_taken_from_stock, the minimum placement_date among all placement dates and last but not least, the minimum delivery_date also among them all.
Im thinking in modelling this implicitly in the PurchaseOrder like this:
Class PurchaseOrder < ApplicationRecord
belongs_to :group, class_name: PurchaseOrder.model_name.to_s, inverse_of: :purchase_orders
# purchase order can represent a "group" of purchase orders
has_many :purchase_orders, inverse_of: :group, foreign_key: :group_id
end
This way it would achieve the purpose of been displayed in the table view easily, filtering pagination and sorting would work out of the box and just by scoping records with group_id nil, the grouped records can be left out of the table.
However i'm foreseeing immediate drawbacks:
- When updating a group member attribute, say amount_to_produce, the parent cached amount_to_produce should be updated also, same for the other three attributes. This would probably led to model callbacks before_update, which i tend not to use unless it concerns behaviour of the single instance itself.
- When ungrouping a member, same history
- Same when destroying a member of the group (it can and will happen).
For 1. we could imply that there's no need to cache the amounts or date attributes in the parent PurchaseOrder, since we can override the getter for those attributes and return the sum / min of the children if purchase_orders.size.nonzero?, however, this smells like something wrong.
So summing it up, i would like if not the best, an optimistic approach to model this scenario and regarding the method to group and ungroup members to / from a group, ideas on what's the best domain place to implement it, i'm thinking of a concern like Groupable.
Pd: For each group, the client_id of the group will be a default seeded client called "Multiple Customers", and the product_id, the same as the product_id of the children, since it's a restriction that only PurchaseOrder with same product_id can be grouped, no groups with different product_id's can be grouped.
Thanks.