diff options
author | Rafael Mendonça França <rafaelmfranca@gmail.com> | 2013-04-19 12:36:53 -0700 |
---|---|---|
committer | Rafael Mendonça França <rafaelmfranca@gmail.com> | 2013-04-19 12:36:53 -0700 |
commit | a489bfe48bc0fbbb50a472bc66bd42d408c73fcb (patch) | |
tree | 838c9686ec081959b7e6f9b007f290212d3bad25 /activerecord | |
parent | 08c6df8532a1884050c8e9087e9fce9df6528ae2 (diff) | |
parent | 66001f360661fefad89d9e271b9ff75a86b4b886 (diff) | |
download | rails-a489bfe48bc0fbbb50a472bc66bd42d408c73fcb.tar.gz rails-a489bfe48bc0fbbb50a472bc66bd42d408c73fcb.tar.bz2 rails-a489bfe48bc0fbbb50a472bc66bd42d408c73fcb.zip |
Merge pull request #10211 from neerajdotname/4208
fix respond_to? for non selected column
Diffstat (limited to 'activerecord')
-rw-r--r-- | activerecord/CHANGELOG.md | 23 | ||||
-rw-r--r-- | activerecord/lib/active_record/attribute_methods.rb | 14 | ||||
-rw-r--r-- | activerecord/test/cases/relation_test.rb | 5 |
3 files changed, 41 insertions, 1 deletions
diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md index 278da322f2..e46ca3bd07 100644 --- a/activerecord/CHANGELOG.md +++ b/activerecord/CHANGELOG.md @@ -1,5 +1,28 @@ ## Rails 4.0.0 (unreleased) ## +* If a query selects only a few columns and gives custom names to + those columns then `respond_to?` was returning true for the non + selected columns. However calling those non selected columns + raises exception. + + post = Post.select("'title' as post_title").first + + In the above case when `post.body` is invoked then an exception is + raised since `body` attribute is not selected. Howevere `respond_to?` + did not behave correctly. + + pos.respond_to?(:body) #=> true + + Reason was that Active Record calls `super` to pass the call to + Active Model and all the columns are defined on Active Model. + + Fix is to actually check if the data returned from the db contains + the data for column in question. + + Fixes #4208. + + *Neeraj Singh* + * Run `rake migrate:down` & `rake migrate:up` in transaction if database supports. *Alexander Bondarev* diff --git a/activerecord/lib/active_record/attribute_methods.rb b/activerecord/lib/active_record/attribute_methods.rb index 22405c5d74..d0c51b77c2 100644 --- a/activerecord/lib/active_record/attribute_methods.rb +++ b/activerecord/lib/active_record/attribute_methods.rb @@ -163,8 +163,20 @@ module ActiveRecord # person.respond_to('age?') # => true # person.respond_to(:nothing) # => false def respond_to?(name, include_private = false) + name = name.to_s self.class.define_attribute_methods unless self.class.attribute_methods_generated? - super + result = super + + # If the result is false then it means this method is not supported by ActiveModel too + return false unless result + + # If the result is true then check for the select case. + # For queries selecting a subset of columns, return false for unselected columns. + if @attributes.present? && self.class.column_names.include?(name) + return has_attribute?(name) + end + + return true end # Returns +true+ if the given attribute is in the attributes hash, otherwise +false+. diff --git a/activerecord/test/cases/relation_test.rb b/activerecord/test/cases/relation_test.rb index 34ecdb3cc9..06723b9d7f 100644 --- a/activerecord/test/cases/relation_test.rb +++ b/activerecord/test/cases/relation_test.rb @@ -185,6 +185,11 @@ module ActiveRecord assert_equal 3, authors(:david).posts.merge(posts_with_special_comments_with_ratings).count.length end + def test_respond_to_for_non_selected_element + post = Post.select("'title' as post_title").first + assert !post.respond_to?(:body), "post should not respond_to?(:body) since invoking it raises exception" + end + end class RelationMutationTest < ActiveSupport::TestCase |