Hey everyone, i’m a bit stuck with choosing the path to solve this, would appreciate your thoughts
- User has many products, each product has many prices.
- Recipient (user2) copies a product including all prices from sender (user1)
- Sender updates this product (changes attributes or prices)
- Recipient can see the diff between his copy and sender’s copy, and can update his copy to match sender’s copy
- Recipient can have his own products
there are a few ways to implement this:
-
Create a nested hash with a product and all prices on each change, store it in Versions table (like paper_trail gem). Recipient links to a version in this table. Comparison can be done with hashdiff gem, syncing will be relinking to a newer version. Cons: recipient can have his own products, this will require two different implementations for own products and received products. Also in case he will need to change a received product - this will require some extra wires. Also each time product or price table needs to be updated - hashes in Versions table might need to be rebuilt
-
Iterate through product and prices and compare them using ActiveModel::Dirty. Merge results in one hash to show diffs. Syncing will be iterating again with save! inside a transaction. Feels a bit brute force
product2.attributes = product1.attributes.slice(attributes)
product2.changes -
Build nested hashes for both products and compare hashes using hashdiff. Syncing is sending nested hash to a form object that will parse this hash and apply changes to models
Product.first.as_json(include: :prices)
(There is also amoeba gem and deep_cloneable gem for building nested hashes)
The last option looks the most appealing at the moment, as this interface can be also used in API - it will work if data comes from another model or from external source.
I’d appreciate your thoughts. Am I missing something or overcomplicating things? Is there a better way to compare and sync models with associations?
Thanks!