1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00

AR::AttributeMethods#[] raises AM::AttributeMissingError for missing attributes.

This fixes the following behaviour:

    class Person < ActiveRecord::Base
      belongs_to :company
    end

    # Before:
    person = Person.select('id').first
    person[:name]       # => nil
    person.name         # => ActiveModel::MissingAttributeError: missing_attribute: name
    person[:company_id] # => nil
    person.company      # => nil

    # After:
    person = Person.select('id').first
    person[:name]       # => ActiveModel::MissingAttributeError: missing_attribute: name
    person.name         # => ActiveModel::MissingAttributeError: missing_attribute: name
    person[:company_id] # => ActiveModel::MissingAttributeError: missing_attribute: company_id
    person.company      # => ActiveModel::MissingAttributeError: missing_attribute: company_id

Fixes #5433.
This commit is contained in:
Francesco Rodriguez 2012-10-28 14:18:31 -05:00
parent e46a8d89ba
commit 10f6f90d9d
3 changed files with 38 additions and 3 deletions

View file

@ -1,5 +1,28 @@
## Rails 4.0.0 (unreleased) ##
* `ActiveRecord::AttributeMethods#[]` raises `ActiveModel::MissingAttributeError`
error if the given attribute is missing. Fixes #5433.
class Person < ActiveRecord::Base
belongs_to :company
end
# Before:
person = Person.select('id').first
person[:name] # => nil
person.name # => ActiveModel::MissingAttributeError: missing_attribute: name
person[:company_id] # => nil
person.company # => nil
# After:
person = Person.select('id').first
person[:name] # => ActiveModel::MissingAttributeError: missing_attribute: name
person.name # => ActiveModel::MissingAttributeError: missing_attribute: name
person[:company_id] # => ActiveModel::MissingAttributeError: missing_attribute: company_id
person.company # => ActiveModel::MissingAttributeError: missing_attribute: company_id
*Francesco Rodriguez*
* Small binary fields use the `VARBINARY` MySQL type, instead of `TINYBLOB`.
*Victor Costan*
@ -51,7 +74,7 @@
*Scott Willson*
* Fix bug where sum(expression) returns string '0' for no matching records
* Fix bug where sum(expression) returns string '0' for no matching records.
Fixes #7439
*Tim Macfarlane*

View file

@ -266,16 +266,22 @@ module ActiveRecord
# Returns the value of the attribute identified by <tt>attr_name</tt> after it has been typecast (for example,
# "2004-12-12" in a data column is cast to a date object, like Date.new(2004, 12, 12)).
# (Alias for the protected <tt>read_attribute</tt> method).
# (Alias for the protected <tt>read_attribute</tt> method). It raises an <tt>ActiveModel::MissingAttributeError</tt>
# error if the identified attribute is missing.
#
# class Person < ActiveRecord::Base
# belongs_to :organization
# end
#
# person = Person.new(name: 'Francesco', age: '22'
# person[:name] # => "Francesco"
# person[:age] # => 22
#
# person = Person.select('id').first
# person[:name] # => ActiveModel::MissingAttributeError: missing attribute: name
# person[:organization_id] # => ActiveModel::MissingAttributeError: missing attribute: organization_id
def [](attr_name)
read_attribute(attr_name)
read_attribute(attr_name) { |n| missing_attribute(n, caller) }
end
# Updates the attribute identified by <tt>attr_name</tt> with the specified +value+.

View file

@ -287,6 +287,12 @@ class AttributeMethodsTest < ActiveRecord::TestCase
assert_equal "Don't change the topic", topic[:title]
end
def test_read_attribute_raises_missing_attribute_error_when_not_exists
computer = Computer.select('id').first
assert_raises(ActiveModel::MissingAttributeError) { computer[:developer] }
assert_raises(ActiveModel::MissingAttributeError) { computer[:extendedWarranty] }
end
def test_read_attribute_when_false
topic = topics(:first)
topic.approved = false