Changed habtm eager loading to also use joins

git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@1201 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
上级 bceb88ef
*SVN*
* Fixed loading of fixtures in to be in the right order (or PostgreSQL would bark) #1047 [stephenh@chase3000.com]
* Fixed page caching for non-vhost applications living underneath the root #1004 [Ben Schumacher]
* Fixes a problem with the SQL Adapter which was resulting in IDENTITY_INSERT not being set to ON when it should be #1104 [adelle]
......
......@@ -708,16 +708,10 @@ def generate_primary_key_table(reflections, schema_abbreviations)
def construct_finder_sql_with_included_associations(options, schema_abbreviations, reflections)
habtm_associations = reflections.find_all { |r| r.macro == :has_and_belongs_to_many }
sql = "SELECT #{column_aliases(schema_abbreviations)} FROM #{table_name}"
add_habtm_join_tables!(habtm_associations, sql)
sql << " "
sql = "SELECT #{column_aliases(schema_abbreviations)} FROM #{table_name} "
add_association_joins!(reflections, sql)
sql << "#{options[:joins]} " if options[:joins]
add_habtm_conditions!(habtm_associations, options)
add_conditions!(sql, options[:conditions])
sql << "ORDER BY #{options[:order]} " if options[:order]
return sanitize_sql(sql)
......@@ -727,35 +721,25 @@ def column_aliases(schema_abbreviations)
schema_abbreviations.collect { |cn, tc| "#{tc.join(".")} AS #{cn}" }.join(", ")
end
def add_habtm_join_tables!(habtm_associations, sql)
return if habtm_associations.empty?
sql << ", " + habtm_associations.collect { |a| [ a.klass.table_name, a.options[:join_table] ] }.join(", ")
end
def add_habtm_conditions!(habtm_associations, options)
return if habtm_associations.empty?
options[:conditions] = [
options[:conditions],
habtm_associations.collect { |r|
join_table = r.options[:join_table]
"#{join_table}.#{table_name.classify.foreign_key} = #{table_name}.#{primary_key} AND " +
"#{join_table}.#{r.klass.table_name.classify.foreign_key} = #{r.klass.table_name}.#{r.klass.primary_key}"
}
].compact.join(" AND ")
end
def add_association_joins!(reflections, sql)
reflections.each { |reflection| sql << association_join(reflection) }
end
def association_join(reflection)
case reflection.macro
when :has_and_belongs_to_many
" LEFT OUTER JOIN #{reflection.options[:join_table]} ON " +
"#{reflection.options[:join_table]}.#{reflection.options[:foreign_key] || table_name.classify.foreign_key} = " +
"#{table_name}.#{primary_key} " +
" LEFT OUTER JOIN #{reflection.klass.table_name} ON " +
"#{reflection.options[:join_table]}.#{reflection.options[:associated_foreign_key] || reflection.klass.table_name.classify.foreign_key} = " +
"#{reflection.klass.table_name}.#{reflection.klass.primary_key} "
when :has_many, :has_one
" LEFT JOIN #{reflection.klass.table_name} ON " +
" LEFT OUTER JOIN #{reflection.klass.table_name} ON " +
"#{reflection.klass.table_name}.#{reflection.options[:foreign_key] || table_name.classify.foreign_key} = " +
"#{table_name}.#{primary_key} "
when :belongs_to
" LEFT JOIN #{reflection.klass.table_name} ON " +
" LEFT OUTER JOIN #{reflection.klass.table_name} ON " +
"#{reflection.klass.table_name}.#{reflection.klass.primary_key} = " +
"#{table_name}.#{reflection.options[:foreign_key] || reflection.klass.table_name.classify.foreign_key} "
else
......
......@@ -18,10 +18,10 @@ def test_loading_with_one_association
end
def test_loading_with_multiple_associations
posts = Post.find(:all, :include => [ :comments, :author, :categories ])
posts = Post.find(:all, :include => [ :comments, :author, :categories ], :order => "posts.id")
assert_equal 2, posts.first.comments.size
assert_equal 2, posts.first.categories.size
assert_equal @greetings.body, posts.first.comments.first.body
assert posts.first.comments.include?(@greetings)
end
def test_loading_from_an_association
......@@ -40,11 +40,12 @@ def test_eager_association_loading_with_belongs_to
end
def test_eager_association_loading_with_habtm
posts = Post.find(:all, :include => :categories)
assert_equal 2, posts.first.categories.size
assert_equal 1, posts.last.categories.size
assert_equal @technology.name, posts.first.categories.last.name
assert_equal @general.name, posts.last.categories.first.name
posts = Post.find(:all, :include => :categories, :order => "posts.id")
assert_equal 2, posts[0].categories.size
assert_equal 1, posts[1].categories.size
assert_equal 0, posts[2].categories.size
assert posts[0].categories.include?(@technology)
assert posts[1].categories.include?(@general)
end
def test_eager_with_inheritance
......
......@@ -14,6 +14,7 @@ thinking:
authorless:
id: 3
author_id: 0
title: I don't have any comments
body: I just don't want to
type: Post
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册