ruby-hyperloop / hyper-mesh

The project has moved to Hyperstack!! - Synchronization of active record models across multiple clients using Pusher, ActionCable, or Polling
https://hyperstack.org/
MIT License
22 stars 12 forks source link

records being saved without validation causing issues #101

Open catmando opened 6 years ago

catmando commented 6 years ago

HyperMesh does a temporary save of related records inside of a rolled back transaction without validations so that the client state is setup on the server. This is fine unless you have a Model that must not be saved if its invalid, then you have a problem.

Reported by @sfcgeorge

Will require either rethinking how we deal with unsaved client side changes, during validation.

sfcgeorge commented 6 years ago

1st issue we found is unique constraints: If you have a join table you may well have a compound unique constraint on it as we do below. For data integrity you also add a corresponding database unique constraint (the Rails validation isn't atomic). This new change causes the join table to be saved without validation, so you get an unfriendly database error instead of the nice Rails message.

validates :industry_id, uniqueness: { scope: :preference_id }

2nd issue is an off by one limit validation. The below used to let you save 3 then give you this error. Now, because the join table is saved before validations are run, it only lets you save 2.

validate :maximum_industries
def maximum_industries
  return unless preference.industries.count >= 3
  errors.add(:industries, "maximum 3 industries")
end

So when saving complex trees this causes all kinds of issues, so I don't think the change is tenable. I get that you want to build the tree of models on the server as it is on the client, then save. So why not do just that? build all the models and associations, then call save on the top level parent record, let Rails save all the associations and leaves as usual.