diff options
Diffstat (limited to 'activerecord')
-rw-r--r-- | activerecord/CHANGELOG.md | 22 | ||||
-rw-r--r-- | activerecord/lib/active_record/attribute_methods.rb | 2 | ||||
-rw-r--r-- | activerecord/test/cases/relation_test.rb | 5 |
3 files changed, 11 insertions, 18 deletions
diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md index 3f9dddf57c..ad766d3267 100644 --- a/activerecord/CHANGELOG.md +++ b/activerecord/CHANGELOG.md @@ -1,23 +1,13 @@ ## 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. +* If a model was instantiated from the database using `select`, `respond_to?` + returns false for non-selected attributes. For example: - post = Post.select("'title' as post_title").first + post = Post.select(:title).first + post.respond_to?(:body) # => false - In the above case when `post.body` is invoked then an exception is - raised since `body` attribute is not selected. However `respond_to?` - did not behave correctly. - - post.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. + post = Post.select('title as post_title').first + post.respond_to?(:title) # => false Fixes #4208. diff --git a/activerecord/lib/active_record/attribute_methods.rb b/activerecord/lib/active_record/attribute_methods.rb index d0c51b77c2..7f59d0b4c6 100644 --- a/activerecord/lib/active_record/attribute_methods.rb +++ b/activerecord/lib/active_record/attribute_methods.rb @@ -167,7 +167,7 @@ module ActiveRecord self.class.define_attribute_methods unless self.class.attribute_methods_generated? result = super - # If the result is false then it means this method is not supported by ActiveModel too + # If the result is false the answer is false. return false unless result # If the result is true then check for the select case. diff --git a/activerecord/test/cases/relation_test.rb b/activerecord/test/cases/relation_test.rb index 06723b9d7f..482c1b3d48 100644 --- a/activerecord/test/cases/relation_test.rb +++ b/activerecord/test/cases/relation_test.rb @@ -186,8 +186,11 @@ module ActiveRecord end def test_respond_to_for_non_selected_element + post = Post.select(:title).first + assert_equal false, post.respond_to?(:body), "post should not respond_to?(:body) since invoking it raises exception" + post = Post.select("'title' as post_title").first - assert !post.respond_to?(:body), "post should not respond_to?(:body) since invoking it raises exception" + assert_equal false, post.respond_to?(:title), "post should not respond_to?(:body) since invoking it raises exception" end end |