SafeAttributes

By default Rails/ActiveRecord 3 creates attribute accessors for all database table columns in each model. Columns with specific names cause errors because they result in ActiveRecord redefining a key method within either Ruby or ActiveRecord in an incompatible way. A classic example is any table with a column named ‘class’, though there are other possible examples. Put simply, this gem makes it easier to support a legacy database schema with ActiveRecord.

Using this gem enhances ActiveRecord to change the default behavior for the creation of attribute accessors. Instance methods in ActiveRecord::Base, except for ‘id’, are combined into a list. This list is checked before the creation of two types of attribute accessors: attribute() and attribute=().

You can add to this list by calling bad_attribute_names with a list of method names you do not want generated. Rails generates additional methods that this module does not prevent the creation of:

  • attribute_before_type_cast

  • attribute_changed?

  • attribute_was

  • attribute_will_change!

  • attribute?

These largely should not run afoul of Ruby or ActiveRecord in most cases.

Accessing Attributes

To access an attribute in ActiveRecord without its normal getter or setter you can use a couple of different approaches.

  • model_instance # works as both getter and setter like a hash

  • model_instance.read_attribute(‘attribute’)

  • model_instance.write_attribute(‘attribute’, value)

You can read more about reserved words and magic field names on Rails’ wiki pages.

Validations

By including safe_attributes, an instance method read_attribute_for_validation is defined in a way that will work for all attributes instead of the default implementation that relies upon the default accessors. In other words, ‘validates_presence_of :class’ will work as of version 1.0.3.

Installing

gem install safe_attributes

If you do not have the newest version of ActiveRecord, rubygems will attempt to install it for you. This can result in an error like below.

ERROR:  Error installing safe_attributes:
  activemodel requires activesupport (= 3.0.3, runtime)

You can use this gem with activerecord and activesupport >= 3.0 and < 3.1.

If you already have an appropriate version of activerecord and activesupport installed then use –ignore-dependencies to avoid this error. If you have the latest version already then the gem should install without issue using the recommended approach above.

Using

Rails

Add safe_attributes to your Gemfile.

gem 'safe_attributes'

SafeAttributes is included into ActiveRecord::Base automatically. While nothing else should be necessary, you can still add to the list of bad attributes if you find it necessary. This list is a list of method names not to generate.

class MyModel < ActiveRecord::Base
  bad_attribute_names :my_attr
  validates_presence_of :my_attr
end

Outside of Rails

require 'safe_attributes'
class MyModel < ActiveRecord::Base
  include SafeAttributes
end

Note on Patches/Pull Requests

  • Fork the project.

  • Make your feature addition or bug fix.

  • Add tests for it. This is important so I don’t break it in a future version unintentionally.

  • Commit, do not mess with rakefile, version, or history. (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)

  • Send me a pull request. Bonus points for topic branches.

Copyright © 2010,2011 C. Brian Jones. See LICENSE for details.

Thanks