Jamie's Blog

Ruby developer. CTO. Swimmer. Always trying to write more

Conditional Validation in Rails

I was implementing the Strategy pattern presented here to avoid the limitations of Single-Type Inheritance but I wanted to implement some conditional validations based on the type:

  • If it’s a “MonthDay-based” recurring event (e.g. 23rd of every month), then the monthday field must be present
  • If it’s a “Date-based” recurring event (e.g. 1st August, repeating every year), then the frequency and unit fiels must be present
It turns out that the validatesXXX methods can be an ‘if’ parameter but it didn’t seem to work as expected. You can’t just do
validatespresenceof :count, 
  :if => recurringstrategy == "WeekDay"
but a quick Google codesearch revealed a more standard pattern:
validatesnumericalityof :count, 
  :if => Proc.new{|s| s.recurringstrategy == "WeekDay" }
A more experienced ruby'er could tell you exactly what this is doing but I’ll hazard a guess that Proc.new creates a new procedure that’s called with the parameter s to test the if condition. Anyway, it seems to work. The only hassle I had it that in the strategy example they overrode the paymentstrategy accessor which isn’t really necessary and makes accessing the ‘type’ of strategy quite difficult.