rails/rails — pull request #7524 by al2o3cr (2012-09-04 22:49:08+00:00)
Title: Fix bugs in AR::Store and add boolean accessor

Note: the commits here are split to facilitate discussion. Happy to squash before merging.

The attached commits fix two bugs in `ActiveRecord::Store` and add a new feature.

* the first commit moves the call to `will_change!` above the actual change to the attribute - otherwise, the attribute is marked as changed but attempts to access the previous value (using `_was` or `_change`) will return the *new* value instead

* the second commit ensures that additional calls to `store_accessor` don't overwrite previously-set values in `stored_attributes`. This functionality is described in the documentation (regarding subclasses) but subsequent calls to `store_accessor` overwrote the list each time.

* the final commit adds a new variant of `store_accessor` that provides type conversion for booleans to simplify (for instance) setting stored attributes with checkboxes. An example:
```ruby
class User < ActiveRecord::Base
store :flags
store_boolean_attribute :flags, :likes_ruby, :likes_python, :likes_clojure
end

User.first.likes_ruby? # => returns true or false

@user.update_attributes(:likes_ruby => '0') # => stores false in flags['likes_ruby']
```

There is some fairly gross duplication between `store_accessor` and `store_boolean_accessor`; any suggestions for a refactor are welcome - as is a better name than `store_boolean_accessor`.

One other open question: would it be better to add more "typed" variants to handle parsing input (for datetimes, etc)? My application only needed booleans, but there's certainly an argument to be made for extending the same type-casting behavior to `store_accessor` attributes as plain attributes.