aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord
diff options
context:
space:
mode:
Diffstat (limited to 'activerecord')
-rw-r--r--activerecord/CHANGELOG.md22
-rw-r--r--activerecord/lib/active_record/attribute_methods.rb2
-rw-r--r--activerecord/test/cases/relation_test.rb5
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