Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
tree: 2508c83dca
Fetching contributors…

Cannot retrieve contributors at this time

94 lines (66 sloc) 1.89 kb
When
====
When adds :if and :unless conditions to ActiveRecord callbacks
and validations and ActionController filters. It works exactly
the way as the current implementation of #validates_acceptance_of.
It works on the 12 regular callbacks:
before_validation
before_validation_on_create
after_validation
after_validation_on_create
before_save
before_create
before_update
after_create
after_update
after_save
before_destroy
after_destroy
3 validations:
validate
validate_on_create
validate_on_update
and 1 filter:
before_filter
It works when :if or :unless is passed a Symbol, a lambdas or a String.
They return or evaluate to a true or false value.
Example
=======
class Address < ActiveRecord::Base
before_save :geolocate
def geolocate
if complete?
...
end
end
def complete?
street? && city? && state? && zip?
end
end
In this case, we want to find the latitude and longitude of an address only if
the address is complete.
Wrapping the entirety of a callback method with conditional logic is bad form.
The callback should execute WHEN the model's life cycle reaches its
"before_save" point and WHEN its address is "complete."
With When, the WHEN responsibility is moved to where it belongs:
as part of the callback.
class Address < ActiveRecord::Base
before_save :geolocate,
:if => :complete?
def geolocate
...
end
def complete?
street? && city? && state? && zip?
end
end
The callback's single responsibility is to execute code WHEN certain conditions are met.
The #geolocate method's single responsibility is to ... geolocate.
More Examples
=============
before_create :encrypt_password,
:unless => lambda {|user| user.password_confirmation.blank?}
before_filter :log_in!,
:only => [:new, :create],
:unless => :logged_in?
Copyright (c) 2008 Jared Carroll and Dan Croak, released under the MIT license
Jump to Line
Something went wrong with that request. Please try again.