Tuesday, March 20

Immutable ActiveRecord Attributes

At last night's Ruby Meetup I posed the question of how to make an ActiveRecord attribute immutable, meaning the ability to set a value once and never allow it to change.

I got lots of theories but no solid answers. One person suggested using callbacks but the hooks aren't there for the logic he proposed. Another person suggested overwriting the assignment method, but I wondered about the update_attributes method undermining it. It turns out the latter calls the former so it's safe.

I wrote some unit tests today and started experimenting and found a solution that seems to work nicely (and consistently).

class Sender < ActiveRecord::Base
def email=(address)
if new_record?
write_attribute(:email, address)
else
raise 'Sender.email is immutable!'
end
end
end