diff options
author | Yves Senn <yves.senn@gmail.com> | 2014-01-21 17:17:13 +0100 |
---|---|---|
committer | Yves Senn <yves.senn@gmail.com> | 2014-01-21 17:21:20 +0100 |
commit | e011258c30b61f30e40fb2d9b2f58eb1f700dfd5 (patch) | |
tree | 6244915c20c76047a61b08993ec8b0e3dd6590f4 | |
parent | c60e06261b9e26110f8ac639224c153d4ff77752 (diff) | |
download | rails-e011258c30b61f30e40fb2d9b2f58eb1f700dfd5.tar.gz rails-e011258c30b61f30e40fb2d9b2f58eb1f700dfd5.tar.bz2 rails-e011258c30b61f30e40fb2d9b2f58eb1f700dfd5.zip |
prepend table name for `Relation#select` columns.
This fixes a bug where `select(:id)` combined with `joins()` raised:
```
ActiveRecord::StatementInvalid: SQLite3::SQLException: ambiguous column name: id:
SELECT id, authors.author_address_id
FROM "posts"
INNER JOIN "authors"
ON "authors"."id" = "posts"."author_id"
ORDER BY posts.id LIMIT 3
```
The `select_values` are still String and Symbols because other parts (mainly calculations.rb)
rely on that fact.
/cc @tenderlove
-rw-r--r-- | activerecord/CHANGELOG.md | 10 | ||||
-rw-r--r-- | activerecord/lib/active_record/relation/query_methods.rb | 5 | ||||
-rw-r--r-- | activerecord/test/cases/relations_test.rb | 6 |
3 files changed, 20 insertions, 1 deletions
diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md index 25a61b3614..9b2e9c4660 100644 --- a/activerecord/CHANGELOG.md +++ b/activerecord/CHANGELOG.md @@ -1,3 +1,13 @@ +* Prepend table name for column names passed to `Relation#select`. + + Example: + + Post.select(:id) + # Before: => SELECT id FROM "posts" + # After: => SELECT "posts"."id" FROM "posts" + + *Yves Senn* + * Fail early with "Primary key not included in the custom select clause" in `find_in_batches`. diff --git a/activerecord/lib/active_record/relation/query_methods.rb b/activerecord/lib/active_record/relation/query_methods.rb index 979216bee7..d392f759bd 100644 --- a/activerecord/lib/active_record/relation/query_methods.rb +++ b/activerecord/lib/active_record/relation/query_methods.rb @@ -987,7 +987,10 @@ module ActiveRecord def build_select(arel, selects) if !selects.empty? - arel.project(*selects) + expanded_select = selects.map do |field| + columns_hash.key?(field.to_s) ? arel_table[field] : field + end + arel.project(*expanded_select) elsif from_value arel.project(Arel.star) else diff --git a/activerecord/test/cases/relations_test.rb b/activerecord/test/cases/relations_test.rb index 9227c2b72f..e874c93110 100644 --- a/activerecord/test/cases/relations_test.rb +++ b/activerecord/test/cases/relations_test.rb @@ -1505,6 +1505,12 @@ class RelationTest < ActiveRecord::TestCase end end + test "joins with select" do + posts = Post.joins(:author).select("id", "authors.author_address_id").order("posts.id").limit(3) + assert_equal [1, 2, 4], posts.map(&:id) + assert_equal [1, 1, 1], posts.map(&:author_address_id) + end + test "delegations do not leak to other classes" do Topic.all.by_lifo assert Topic.all.class.method_defined?(:by_lifo) |