SafeAttributes

By default Rails creates attribute accessors for all database table columns in each model. Columns with specific names cause errors because they result in Rails redefining a key method within either Ruby or Rails in an incompatible way. A classic example for me has been tables with a column named ‘class’, though there are many other possible examples.

Using this gem enhances activerecord to change the default behavior for the creation of attribute accessors. Methods in ActiveRecord::Base and its superclasses, 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.

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)

Installing

gem install safe_attributes --force

The –force flag is here because I believe rubygems to have some sort of dependency tracking issue. Without it, it wants to install the newest activemodel (3.0.3 at this time) and arel. These are not necessary for the gem and this should not be happening. As long as you have activerecord 3.0.0 or better it should work. Here’s the error message in case you see it.

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

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.

class MyModel < ActiveRecord::Base
  bad_attribute_names :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 C. Brian Jones. See LICENSE for details.