Permalink
Browse files

Fixed that single-table inheritance sub-classes couldn't be used to l…

…imit the result set with eager loading #1215 [Chris McGrath]

git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@1619 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
  • Loading branch information...
1 parent 703d18e commit d9d22c7596118051ba8908c163c797b90cca7aa3 @dhh dhh committed Jul 3, 2005
View
@@ -1,5 +1,7 @@
*SVN*
+* Fixed that single-table inheritance sub-classes couldn't be used to limit the result set with eager loading #1215 [Chris McGrath]
+
* Fixed validates_numericality_of to work with overrided getter-method when :allow_nil is on #1316 [raidel@onemail.at]
* Added roots, root, and siblings to the batch of methods added by acts_as_tree #1541 [michael@schuerig.de]
@@ -793,11 +793,21 @@ def construct_finder_sql_with_included_associations(options, schema_abbreviation
sql << reflections.collect { |reflection| association_join(reflection) }.to_s
sql << "#{options[:joins]} " if options[:joins]
add_conditions!(sql, options[:conditions])
+ add_sti_conditions!(sql, reflections)
sql << "ORDER BY #{options[:order]} " if options[:order]
return sanitize_sql(sql)
end
+ def add_sti_conditions!(sql, reflections)
+ sti_sql = ""
+ reflections.each do |reflection|
+ sti_sql << " AND #{reflection.klass.send(:type_condition)}" unless reflection.klass.descends_from_active_record?
+ end
+ sti_sql.sub!(/AND/, "WHERE") unless sql =~ /where/i
+ sql << sti_sql
+ end
+
def column_aliases(schema_abbreviations)
schema_abbreviations.collect { |cn, tc| "#{tc.join(".")} AS #{cn}" }.join(", ")
end
@@ -21,9 +21,12 @@ def test_loading_with_one_association
def test_with_ordering
posts = Post.find(:all, :include => :comments, :order => "posts.id DESC")
- assert_equal posts(:authorless), posts[0]
- assert_equal posts(:thinking), posts[1]
- assert_equal posts(:welcome), posts[2]
+ assert_equal posts(:sti_habtm), posts[0]
+ assert_equal posts(:sti_post_and_comments), posts[1]
+ assert_equal posts(:sti_comments), posts[2]
+ assert_equal posts(:authorless), posts[3]
+ assert_equal posts(:thinking), posts[4]
+ assert_equal posts(:welcome), posts[5]
end
def test_loading_with_multiple_associations
@@ -46,7 +49,7 @@ def test_eager_association_loading_with_belongs_to
comments = Comment.find(:all, :include => :post)
titles = comments.map { |c| c.post.title }
assert titles.include?(posts(:welcome).title)
- assert titles.include?(posts(:thinking).title)
+ assert titles.include?(posts(:sti_post_and_comments).title)
end
def test_eager_association_loading_with_habtm
@@ -62,6 +65,26 @@ def test_eager_with_inheritance
posts = SpecialPost.find(:all, :include => [ :comments ])
end
+ def test_eager_has_one_with_association_inheritance
+ post = Post.find(4, :include => [ :very_special_comment ])
+ assert_equal "VerySpecialComment", post.very_special_comment.class.to_s
+ end
+
+ def test_eager_has_many_with_association_inheritance
+ post = Post.find(4, :include => [ :special_comments ])
+ post.special_comments.each do |special_comment|
+ assert_equal "SpecialComment", special_comment.class.to_s
+ end
+ end
+
+ def test_eager_habtm_with_association_inheritance
+ post = Post.find(6, :include => [ :special_categories ])
+ assert_equal 1, post.special_categories.size
+ post.special_categories.each do |special_category|
+ assert_equal "SpecialCategory", special_category.class.to_s
+ end
+ end
+
def test_eager_with_has_one_dependent_does_not_destroy_dependent
assert_not_nil companies(:first_firm).account
f = Firm.find(:first, :include => :account,
@@ -1,7 +1,14 @@
general:
id: 1
name: General
+ type: Category
technology:
id: 2
name: Technology
+ type: Category
+
+sti_test:
+ id: 3
+ name: Special category
+ type: SpecialCategory
@@ -9,3 +9,11 @@ technology_welcome:
general_thinking:
category_id: 1
post_id: 2
+
+general_sti_habtm:
+ category_id: 1
+ post_id: 6
+
+sti_test_sti_habtm:
+ category_id: 3
+ post_id: 6
@@ -1,3 +1,5 @@
class Category < ActiveRecord::Base
has_and_belongs_to_many :posts
end
+
+class SpecialCategory < Category; end;
@@ -2,4 +2,6 @@ class Comment < ActiveRecord::Base
belongs_to :post
end
-class SpecialComment < Comment; end;
+class SpecialComment < Comment; end;
+
+class VerySpecialComment < Comment; end;
@@ -14,4 +14,46 @@ does_it_hurt:
id: 3
post_id: 2
body: Don't think too hard
- type: SpecialComment
+ type: SpecialComment
+
+eager_sti_on_associations_comment:
+ id: 4
+ post_id: 4
+ body: Normal type
+ type: Comment
+
+eager_sti_on_associations_vs_comment:
+ id: 5
+ post_id: 4
+ body: Very Special type
+ type: VerySpecialComment
+
+eager_sti_on_associations_s_comment1:
+ id: 6
+ post_id: 4
+ body: Special type
+ type: SpecialComment
+
+eager_sti_on_associations_s_comment2:
+ id: 7
+ post_id: 4
+ body: Special type 2
+ type: SpecialComment
+
+eager_sti_on_associations_comment:
+ id: 8
+ post_id: 4
+ body: Normal type
+ type: Comment
+
+check_eager_sti_on_associations:
+ id: 9
+ post_id: 5
+ body: Normal type
+ type: Comment
+
+check_eager_sti_on_associations2:
+ id: 10
+ post_id: 5
+ body: Special Type
+ type: SpecialComment
@@ -160,7 +160,8 @@ CREATE TABLE tasks (
CREATE TABLE categories (
id int generated by default as identity (start with +10000),
- name varchar(255) NOT NULL
+ name varchar(255) NOT NULL,
+ type varchar(40) default NULL
);
CREATE TABLE categories_posts (
@@ -162,6 +162,7 @@ CREATE TABLE `tasks` (
CREATE TABLE `categories` (
`id` int(11) NOT NULL auto_increment,
`name` VARCHAR(255) NOT NULL,
+ `type` VARCHAR(255) NOT NULL,
PRIMARY KEY (`id`)
) TYPE=InnoDB;
@@ -198,7 +198,8 @@ create table tasks (
create table categories (
id integer not null primary key,
- name varchar(255) default null
+ name varchar(255) default null,
+ type varchar(255) default null
);
create table categories_posts (
@@ -177,7 +177,8 @@ CREATE TABLE tasks (
CREATE TABLE categories (
id serial,
- name varchar(255)
+ name varchar(255),
+ type varchar(255)
);
CREATE TABLE categories_posts (
@@ -147,7 +147,8 @@ CREATE TABLE 'tasks' (
CREATE TABLE 'categories' (
'id' INTEGER NOT NULL PRIMARY KEY,
- 'name' VARCHAR(255) NOT NULL
+ 'name' VARCHAR(255) NOT NULL,
+ 'type' VARCHAR(255) DEFAULT NULL
);
CREATE TABLE 'categories_posts' (
@@ -147,7 +147,8 @@ CREATE TABLE tasks (
CREATE TABLE categories (
id int NOT NULL IDENTITY(1, 1) PRIMARY KEY,
- name varchar(255)
+ name varchar(255),
+ type varchar(255) default NULL
);
CREATE TABLE categories_posts (
@@ -1,8 +1,14 @@
class Post < ActiveRecord::Base
belongs_to :author
has_many :comments, :order => "body"
+ has_one :very_special_comment, :class_name => "VerySpecialComment"
+ has_many :special_comments, :class_name => "SpecialComment"
has_and_belongs_to_many :categories
+ has_and_belongs_to_many :special_categories, :join_table => "categories_posts"
end
-class SpecialPost < Post
-end
+class SpecialPost < Post; end;
+
+class StiPost < Post
+ has_one :special_comment, :class_name => "SpecialComment"
+end
@@ -18,3 +18,24 @@ authorless:
title: I don't have any comments
body: I just don't want to
type: Post
+
+sti_comments:
+ id: 4
+ author_id: 1
+ title: sti comments
+ body: hello
+ type: Post
+
+sti_post_and_comments:
+ id: 5
+ author_id: 1
+ title: sti me
+ body: hello
+ type: StiPost
+
+sti_habtm:
+ id: 6
+ author_id: 1
+ title: habtm sti test
+ body: hello
+ type: Post

0 comments on commit d9d22c7

Please sign in to comment.