From 371edb14ca51b186f1a5130b20f5cbf0fb4b579c Mon Sep 17 00:00:00 2001 From: Tatsuya Ono Date: Mon, 11 Jan 2010 21:18:49 +0000 Subject: [PATCH 1/2] added a test to reproduce issue on joining with has_one-through association. --- activerecord/test/cases/finder_test.rb | 17 +++++++++++++++++ activerecord/test/models/comment.rb | 1 + 2 files changed, 18 insertions(+), 0 deletions(-) diff --git a/activerecord/test/cases/finder_test.rb b/activerecord/test/cases/finder_test.rb index d2451f2..97edb20 100644 --- a/activerecord/test/cases/finder_test.rb +++ b/activerecord/test/cases/finder_test.rb @@ -1027,6 +1027,23 @@ class FinderTest < ActiveRecord::TestCase end end + def test_finder_with_association + comments_on_thinking = Post.find(2).comments.count + + comments = Comment.find :all, :conditions=>["posts.title = ?", "So I was thinking"], :joins=>[:post] + + assert_equal comments_on_thinking, comments.size + end + + def test_finder_with_association_through + david = Author.find 1 + comments_on_david = david.posts.inject(0) {|sum, post| sum += post.comments.count } + + comments = Comment.find :all, :conditions=>["authors.name = ?", "David"], :joins=>[:post_author] + + assert_equal comments_on_david, comments.size + end + protected def bind(statement, *vars) if vars.first.is_a?(Hash) diff --git a/activerecord/test/models/comment.rb b/activerecord/test/models/comment.rb index a8a99f6..ec275eb 100644 --- a/activerecord/test/models/comment.rb +++ b/activerecord/test/models/comment.rb @@ -6,6 +6,7 @@ class Comment < ActiveRecord::Base :conditions => { "posts.author_id" => 1 } belongs_to :post, :counter_cache => true + has_one :post_author, :through=>:post, :source=>:author def self.what_are_you 'a comment...' -- 1.6.6 From a3d33fa1a81a1fbf0ba941325536c7460b2c7a0c Mon Sep 17 00:00:00 2001 From: Tatsuya Ono Date: Thu, 4 Feb 2010 00:42:27 +0000 Subject: [PATCH 2/2] fixed an issue on joining with has_one-through association. --- activerecord/lib/active_record/associations.rb | 18 ++++++++++++------ 1 files changed, 12 insertions(+), 6 deletions(-) diff --git a/activerecord/lib/active_record/associations.rb b/activerecord/lib/active_record/associations.rb index 57785b4..70e29aa 100755 --- a/activerecord/lib/active_record/associations.rb +++ b/activerecord/lib/active_record/associations.rb @@ -1964,14 +1964,20 @@ module ActiveRecord when :has_many, :has_one if reflection.options[:through] join_table = Arel::Table.new(through_reflection.klass.table_name, :as => aliased_join_table_name, :engine => arel_engine) - jt_foreign_key = jt_as_extra = jt_source_extra = jt_sti_extra = nil + jt_first_key = jt_second_key = jt_as_extra = jt_source_extra = jt_sti_extra = nil first_key = second_key = as_extra = nil - if through_reflection.options[:as] # has_many :through against a polymorphic join - jt_foreign_key = through_reflection.options[:as].to_s + '_id' - jt_as_extra = join_table[through_reflection.options[:as].to_s + '_type'].eq(parent.active_record.base_class.name) + if through_reflection.macro == :belongs_to + jt_first_key = through_reflection.primary_key_name + jt_second_key = parent.primary_key else - jt_foreign_key = through_reflection.primary_key_name + jt_first_key = parent.primary_key + if through_reflection.options[:as] # has_many :through against a polymorphic join + jt_second_key = through_reflection.options[:as].to_s + '_id' + jt_as_extra = join_table[through_reflection.options[:as].to_s + '_type'].eq(parent.active_record.base_class.name) + else + jt_second_key = through_reflection.primary_key_name + end end case source_reflection.macro @@ -1999,7 +2005,7 @@ module ActiveRecord end [ - [parent_table[parent.primary_key].eq(join_table[jt_foreign_key]), jt_as_extra, jt_source_extra, jt_sti_extra].reject{|x| x.blank? }, + [parent_table[jt_first_key].eq(join_table[jt_second_key]), jt_as_extra, jt_source_extra, jt_sti_extra].reject{|x| x.blank? }, aliased_table[first_key].eq(join_table[second_key]) ] elsif reflection.options[:as] -- 1.6.6