-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Description
My team is using RuboCop with Rails cops enabled as a first step in cleaning up a legacy codebase. We found some code like this:
...
after_initialize :set_variations
def set_variations
if read_attribute(:page_id) && !self.page_id.nil?
...
Among many others, we got this warning from RuboCop:
C: Prefer self[:attr] over read_attribute(:attr).
if read_attribute(:page_id) && !self.page_id.nil?
^^^^^^^^^^^^^^
which refers to this recommendation in the style guide.
And our specs blew up. :( We got several of these:
ActiveModel::MissingAttributeError:
missing attribute: page_id
# activerecord-4.0.13/lib/active_record/attribute_methods/read.rb:95:in `block (2 levels) in read_attribute'
# activerecord-4.0.13/lib/active_record/attribute_methods/read.rb:94:in `fetch'
# activerecord-4.0.13/lib/active_record/attribute_methods/read.rb:94:in `block in read_attribute'
# activerecord-4.0.13/lib/active_record/attribute_methods/read.rb:84:in `fetch'
# activerecord-4.0.13/lib/active_record/attribute_methods/read.rb:84:in `read_attribute'
# activerecord-4.0.13/lib/active_record/attribute_methods.rb:345:in `[]'
It turns out that ActiveRecord::AttributeMethods::Read#read_attribute
and ActiveRecord::AttributeMethods#[]
are not exact synonyms: the latter will raise an ActiveModel::MissingAttributeError
if the attribute is not found, whereas the former (I think) just returns nil
and fails silently.
It's true that our example is especially gnarly code (read_attribute
in an after_initialize
callback), but I thought I should at least leave a note here that the two methods can't always be swapped safely. Would it be helpful to reword the style recommendation to make that more clear?