Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Changing Business Rule Validations Over Time in Rails

Several times I've been in a situation where we have a model with a business-driven validation such as:

class Order < ActiveRecord::Base
  validates_numericality_of :total, :greater_than => 5.0

  # Some more logic
end

At some point, the boss man decides that the new minimum order should be $10, so we update the validation to 10. However, this means that any existing orders with values between $5 and $10 will no longer validate, and any logic where I call order.save() will begin to fail (sometimes unpleasantly silently). I've run into this many times in a largish shipping Rails app, and haven't found a good solution yet. Some ideas:

  1. Ensure that there are no pending "orders" that will be affected when the code change is rolled out
  2. Add an :if => Proc.new { |o| o.created_at.nil? or o.created_at > date_new_validation_is_effective } to the new validation, but certain this quickly becomes unwieldy
  3. "Validate" business rules somewhere else, such as the controllers where user-specified input is accepted, rather than as model validations. But this violates the Fat Model/Skinny Controller principle that has many proponents in Rails.

Is there a different approach for integrating this logic, or keeping a strategy like #2 manageable in the long run?

like image 812
John Laxson Avatar asked Oct 24 '25 06:10

John Laxson


2 Answers

You could set this business logic validation to only run :on => :create. I'm assuming that you don't often edit/update the total of an order.

That would put it into effect for all orders going forward, while not affecting the validity of existing models in the system.

like image 173
Bryce Avatar answered Oct 26 '25 20:10

Bryce


You could add a version to the order record and version specific validations.

like image 33
Mark Swardstrom Avatar answered Oct 26 '25 20:10

Mark Swardstrom