Just a simple little Rails tip to end the week. Nothing new here, but a nice snippet of code to remember and keep in your toolbox.
Let’s say you have an Address model. Every time you update an address, you want it geocoded. So you add an after_save :geocode callback. Now let’s say you want to standardize all state names to 2 letter uppercase abbreviations. We want to go back and upcase all the states that are already in the database but not re-geocode them (since the address didn’t actually change).
Here’s a handy little snippet code you can stick onto ActiveRecord::Base that will easily let you skip callback:
ActiveRecord::Base.class_eval do
def self.skip_callback(callback, &block)
method = instance_method(callback)
remove_method(callback) if respond_to?(callback)
define_method(callback){ true }
begin
result = yield
ensure
remove_method(callback)
define_method(callback, method)
end
result
end
end
Now in script/console you can do the following:
Address.skip_callback(:geocode) do
Address.find_each do |address|
address.update_attributes! :state=>address.state.upcase
end
end