Immutable Attribute Plugin 5

Posted by wesley.moxam
on Tuesday, November 13

A new Ruby on Rails validation plugin that allows you to mark model attributes as immutable.

Rails surprisingly does not include a validation method to make a model attribute immutable. (That is, the attribute can not be changed after it is set the first time.) I created this validation plugin to help that.

To install:

  script/plugin install http://svn.savvica.com/public/plugins/ensures_immutability_of

To use, drop this in your model:

  ensures_immutability_of :attribute_name

You can specify multiple immutable attributes in one line:

  ensures_immutability_of :attribute1, :attribute2

Now if something attempts to set a protected attribute, it will raise an error. For example:

class Account < ActiveRecord::Base
  ensures_immutability_of :username, :email
end

account = Account.create(:username => 'jgreen')
...
account.update(:username => 'jgreen')  # raises ActiveRecord::ImmutableAttributeError

This plugin works especially nicely with the Email Veracity Plugin. If you have an email-verification process (such as sending an activation email) then you will most likely want to mark the email attribute as immutable, and create new records for when users add other email addresses.

But this is probably most excellent for username and relationship attributes (foreign key fields). That is exactly how we are using it on Languify.

Would love to hear any ideas on how to make this better! We really appreciated all the helpful feedback on the Email Veracity Plugin.

Also I would like to thank Paul Ingles for the inspiration for this plugin.

Update:

Rather than raising a RuntimeError when an attribute is modified, now a ActiveRecord::ImmutableAttributeError is raised instead. Thanks goes to Jeffery Hardy for the suggestion.

Comments

Leave a response

  1. TedNovember 14, 2007 @ 08:35 AM
    Funny you should mention this in conjunction with the e-mail veracity plug-in. I too was working on a project where I needed immutable e-mail addresses. I used to old regex for e-mail validation (but might switch to your plug-in in the near future) and I blogged about my attempt at immutability here http://trak3r.blogspot.com/2007/03/immutable-activerecord-attributes.html A colleague of mine took this and made his own plug-in here http://railsboard.org/rails-models-with-immutable-attributes
  2. Jack DangerNovember 14, 2007 @ 08:52 AM
    Ahoy Wesley! I really like the way you set up the configuration message - much better design than the way my plugin has it.
  3. Wesley MoxamNovember 14, 2007 @ 10:15 AM
    @Ted: Ah, if I knew about that plugin I likely would have used it. Thanks for the links! @Jack: Thanks!
  4. Jeffrey HardyNovember 14, 2007 @ 05:48 PM
    Nice work, Wesley. I've done something similar in the past. About the only difference in my own implementation is that I added a new exception class to ActiveRecord like so:
    class ImmutableAttributeError < ActiveRecord::ActiveRecordError
      def initialize(message=nil)
        super(message || 'Cannot modify immutable attribute')
      end
    end
    
    This makes it easier to test (since a RuntimeError could be anything), e.g.:
    assert_raises ActiveRecord::ImmutableAttributeError do
      account.username = 'foobar'
    end
    
  5. Wesley MoxamNovember 15, 2007 @ 08:45 AM
    That's a great idea Jeff. I'll update the code later today to use it's own exception class. Thanks!
Comment