Problem
Suppose you’ve got an ActiveRecord object that could benefit from state behavior. Perhaps it’s a multi-step form or wizard? Suppose further that you don’t want the full weight of a state machine plugin like AASM. How can you elegantly configure validations for each state?
Solution
Whenever possible, I like to use Semantic Attributes for validations. But this example works equally well with Rails’ own validates methods.
class Post < ActiveRecord::Base
# First, we want query methods for each state. Not necessary, but nice!
def draft?; self.state == 'draft' end
def live?; self.state == 'live' end
def archived?; self.state == 'archived' end
def complete?; !draft? end
# validations for every state
title_is_required
# validations for post-draft state
with_options :if => :complete? do |c|
# Perhaps you prefer the Semantic Attributes library?
c.body_is_required
# Or perhaps you want something custom
c.validates_each :body do |record, attr, value|
record.errors.add attr, "Body is not well-formed." unless Tidy.valid?(value)
end
end
endAnd there you have it. By using with_options we can clean up our code and make it self-documenting.
This looks like a perfect case for AASM…
@Brian: I clarified the part where this is for people who don’t want AASM. :-)