ibm_db 0.9.0 → 0.9.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,131 +1,131 @@
1
- require 'abstract_unit'
2
-
3
- class AdapterTest < Test::Unit::TestCase
4
- def setup
5
- @connection = ActiveRecord::Base.connection
6
- end
7
-
8
- if current_adapter?(:IBM_DBAdapter)
9
- def test_a_connection_attributes
10
- if @connection.servertype.class.name.include?('::IBM_IDS')
11
- return
12
- end
13
- if @connection.respond_to?(:schema)
14
- previous_schema = ActiveRecord::Base.connection.schema
15
- ActiveRecord::Base.connection.schema = 'SYSCAT'
16
- assert_equal 'SYSCAT', ActiveRecord::Base.connection.schema
17
- ActiveRecord::Base.connection.schema = previous_schema
18
- else
19
- warn "#{@connection.class} does not support client connection attribute schema_name"
20
- end
21
-
22
- if @connection.respond_to?(:app_user)
23
- ActiveRecord::Base.connection.app_user = 'new_user'
24
- assert_equal 'new_user', ActiveRecord::Base.connection.app_user
25
- else
26
- warn "#{@connection.class} does not support client connection attribute SQL_ATTR_INFO_USER"
27
- end
28
-
29
- if @connection.respond_to?(:account)
30
- ActiveRecord::Base.connection.account = 'new_acct'
31
- assert_equal 'new_acct', ActiveRecord::Base.connection.account
32
- else
33
- warn "#{@connection.class} does not support client connection attribute SQL_ATTR_INFO_ACCTSTR"
34
- end
35
-
36
- if @connection.respond_to?(:application)
37
- ActiveRecord::Base.connection.application = 'new_app'
38
- assert_equal 'new_app', ActiveRecord::Base.connection.application
39
- else
40
- warn "#{@connection.class} does not support client connection attribute SQL_ATTR_INFO_APPLNAME"
41
- end
42
-
43
- if @connection.respond_to?(:workstation)
44
- ActiveRecord::Base.connection.workstation = 'new_wrkst'
45
- assert_equal 'new_wrkst', ActiveRecord::Base.connection.workstation
46
- else
47
- warn "#{@connection.class} does not support client connection attribute SQL_ATTR_INFO_WRKSTNNAME"
48
- end
49
- end
50
- end
51
-
52
- def test_tables
53
- if @connection.respond_to?(:tables)
54
- tables = @connection.tables
55
- assert tables.include?("accounts")
56
- assert tables.include?("authors")
57
- assert tables.include?("tasks")
58
- assert tables.include?("topics")
59
- else
60
- warn "#{@connection.class} does not respond to #tables"
61
- end
62
- end
63
-
64
- def test_indexes
65
- idx_name = "accounts_idx"
66
-
67
- if @connection.respond_to?(:indexes)
68
- indexes = @connection.indexes("accounts")
69
- assert indexes.empty?
70
-
71
- @connection.add_index :accounts, :firm_id, :name => idx_name
72
- indexes = @connection.indexes("accounts")
73
- assert_equal "accounts", indexes.first.table
74
- # OpenBase does not have the concept of a named index
75
- # Indexes are merely properties of columns.
76
- assert_equal idx_name, indexes.first.name unless current_adapter?(:OpenBaseAdapter)
77
- assert !indexes.first.unique
78
- assert_equal ["firm_id"], indexes.first.columns
79
- else
80
- warn "#{@connection.class} does not respond to #indexes"
81
- end
82
-
83
- ensure
84
- @connection.remove_index(:accounts, :name => idx_name) rescue nil
85
- end
86
-
87
- def test_current_database
88
- if @connection.respond_to?(:current_database)
89
- assert_equal ENV['ARUNIT_DB_NAME'] || "activerecord_unittest", @connection.current_database
90
- end
91
- end
92
-
93
- def test_table_alias
94
- def @connection.test_table_alias_length() 10; end
95
- class << @connection
96
- alias_method :old_table_alias_length, :table_alias_length
97
- alias_method :table_alias_length, :test_table_alias_length
98
- end
99
-
100
- assert_equal 'posts', @connection.table_alias_for('posts')
101
- assert_equal 'posts_comm', @connection.table_alias_for('posts_comments')
102
- assert_equal 'dbo_posts', @connection.table_alias_for('dbo.posts')
103
-
104
- class << @connection
105
- alias_method :table_alias_length, :old_table_alias_length
106
- end
107
- end
108
-
109
- # test resetting sequences in odd tables in postgreSQL
110
- if ActiveRecord::Base.connection.respond_to?(:reset_pk_sequence!)
111
- require 'fixtures/movie'
112
- require 'fixtures/subscriber'
113
-
114
- def test_reset_empty_table_with_custom_pk
115
- Movie.delete_all
116
- Movie.connection.reset_pk_sequence! 'movies'
117
- assert_equal 1, Movie.create(:name => 'fight club').id
118
- end
119
-
120
- if ActiveRecord::Base.connection.adapter_name != "FrontBase"
121
- def test_reset_table_with_non_integer_pk
122
- Subscriber.delete_all
123
- Subscriber.connection.reset_pk_sequence! 'subscribers'
124
- sub = Subscriber.new(:name => 'robert drake')
125
- sub.id = 'bob drake'
126
- assert_nothing_raised { sub.save! }
127
- end
128
- end
129
- end
130
-
131
- end
1
+ require 'abstract_unit'
2
+
3
+ class AdapterTest < Test::Unit::TestCase
4
+ def setup
5
+ @connection = ActiveRecord::Base.connection
6
+ end
7
+
8
+ if current_adapter?(:IBM_DBAdapter)
9
+ def test_a_connection_attributes
10
+ if @connection.servertype.class.name.include?('::IBM_IDS')
11
+ return
12
+ end
13
+ if @connection.respond_to?(:schema)
14
+ previous_schema = ActiveRecord::Base.connection.schema
15
+ ActiveRecord::Base.connection.schema = 'SYSCAT'
16
+ assert_equal 'SYSCAT', ActiveRecord::Base.connection.schema
17
+ ActiveRecord::Base.connection.schema = previous_schema
18
+ else
19
+ warn "#{@connection.class} does not support client connection attribute schema_name"
20
+ end
21
+
22
+ if @connection.respond_to?(:app_user)
23
+ ActiveRecord::Base.connection.app_user = 'new_user'
24
+ assert_equal 'new_user', ActiveRecord::Base.connection.app_user
25
+ else
26
+ warn "#{@connection.class} does not support client connection attribute SQL_ATTR_INFO_USER"
27
+ end
28
+
29
+ if @connection.respond_to?(:account)
30
+ ActiveRecord::Base.connection.account = 'new_acct'
31
+ assert_equal 'new_acct', ActiveRecord::Base.connection.account
32
+ else
33
+ warn "#{@connection.class} does not support client connection attribute SQL_ATTR_INFO_ACCTSTR"
34
+ end
35
+
36
+ if @connection.respond_to?(:application)
37
+ ActiveRecord::Base.connection.application = 'new_app'
38
+ assert_equal 'new_app', ActiveRecord::Base.connection.application
39
+ else
40
+ warn "#{@connection.class} does not support client connection attribute SQL_ATTR_INFO_APPLNAME"
41
+ end
42
+
43
+ if @connection.respond_to?(:workstation)
44
+ ActiveRecord::Base.connection.workstation = 'new_wrkst'
45
+ assert_equal 'new_wrkst', ActiveRecord::Base.connection.workstation
46
+ else
47
+ warn "#{@connection.class} does not support client connection attribute SQL_ATTR_INFO_WRKSTNNAME"
48
+ end
49
+ end
50
+ end
51
+
52
+ def test_tables
53
+ if @connection.respond_to?(:tables)
54
+ tables = @connection.tables
55
+ assert tables.include?("accounts")
56
+ assert tables.include?("authors")
57
+ assert tables.include?("tasks")
58
+ assert tables.include?("topics")
59
+ else
60
+ warn "#{@connection.class} does not respond to #tables"
61
+ end
62
+ end
63
+
64
+ def test_indexes
65
+ idx_name = "accounts_idx"
66
+
67
+ if @connection.respond_to?(:indexes)
68
+ indexes = @connection.indexes("accounts")
69
+ assert indexes.empty?
70
+
71
+ @connection.add_index :accounts, :firm_id, :name => idx_name
72
+ indexes = @connection.indexes("accounts")
73
+ assert_equal "accounts", indexes.first.table
74
+ # OpenBase does not have the concept of a named index
75
+ # Indexes are merely properties of columns.
76
+ assert_equal idx_name, indexes.first.name unless current_adapter?(:OpenBaseAdapter)
77
+ assert !indexes.first.unique
78
+ assert_equal ["firm_id"], indexes.first.columns
79
+ else
80
+ warn "#{@connection.class} does not respond to #indexes"
81
+ end
82
+
83
+ ensure
84
+ @connection.remove_index(:accounts, :name => idx_name) rescue nil
85
+ end
86
+
87
+ def test_current_database
88
+ if @connection.respond_to?(:current_database)
89
+ assert_equal ENV['ARUNIT_DB_NAME'] || "activerecord_unittest", @connection.current_database
90
+ end
91
+ end
92
+
93
+ def test_table_alias
94
+ def @connection.test_table_alias_length() 10; end
95
+ class << @connection
96
+ alias_method :old_table_alias_length, :table_alias_length
97
+ alias_method :table_alias_length, :test_table_alias_length
98
+ end
99
+
100
+ assert_equal 'posts', @connection.table_alias_for('posts')
101
+ assert_equal 'posts_comm', @connection.table_alias_for('posts_comments')
102
+ assert_equal 'dbo_posts', @connection.table_alias_for('dbo.posts')
103
+
104
+ class << @connection
105
+ alias_method :table_alias_length, :old_table_alias_length
106
+ end
107
+ end
108
+
109
+ # test resetting sequences in odd tables in postgreSQL
110
+ if ActiveRecord::Base.connection.respond_to?(:reset_pk_sequence!)
111
+ require 'fixtures/movie'
112
+ require 'fixtures/subscriber'
113
+
114
+ def test_reset_empty_table_with_custom_pk
115
+ Movie.delete_all
116
+ Movie.connection.reset_pk_sequence! 'movies'
117
+ assert_equal 1, Movie.create(:name => 'fight club').id
118
+ end
119
+
120
+ if ActiveRecord::Base.connection.adapter_name != "FrontBase"
121
+ def test_reset_table_with_non_integer_pk
122
+ Subscriber.delete_all
123
+ Subscriber.connection.reset_pk_sequence! 'subscribers'
124
+ sub = Subscriber.new(:name => 'robert drake')
125
+ sub.id = 'bob drake'
126
+ assert_nothing_raised { sub.save! }
127
+ end
128
+ end
129
+ end
130
+
131
+ end
@@ -1,445 +1,445 @@
1
- require 'abstract_unit'
2
- require 'fixtures/post'
3
- require 'fixtures/comment'
4
- require 'fixtures/author'
5
- require 'fixtures/category'
6
- require 'fixtures/company'
7
- require 'fixtures/person'
8
- require 'fixtures/reader'
9
-
10
- class EagerAssociationTest < Test::Unit::TestCase
11
- fixtures :posts, :comments, :authors, :categories, :categories_posts,
12
- :companies, :accounts, :tags, :people, :readers
13
-
14
- def test_loading_with_one_association
15
- posts = Post.find(:all, :include => :comments)
16
- post = posts.find { |p| p.id == 1 }
17
- assert_equal 2, post.comments.size
18
- assert post.comments.include?(comments(:greetings))
19
-
20
- post = Post.find(:first, :include => :comments, :conditions => "posts.title = 'Welcome to the weblog'")
21
- assert_equal 2, post.comments.size
22
- assert post.comments.include?(comments(:greetings))
23
- end
24
-
25
- def test_loading_conditions_with_or
26
- posts = authors(:david).posts.find(:all, :include => :comments, :conditions => "comments.body like 'Normal%' OR comments.#{QUOTED_TYPE} = 'SpecialComment'")
27
- assert_nil posts.detect { |p| p.author_id != authors(:david).id },
28
- "expected to find only david's posts"
29
- end
30
-
31
- def test_with_ordering
32
- list = Post.find(:all, :include => :comments, :order => "posts.id DESC")
33
- [:eager_other, :sti_habtm, :sti_post_and_comments, :sti_comments,
34
- :authorless, :thinking, :welcome
35
- ].each_with_index do |post, index|
36
- assert_equal posts(post), list[index]
37
- end
38
- end
39
-
40
- def test_loading_with_multiple_associations
41
- posts = Post.find(:all, :include => [ :comments, :author, :categories ], :order => "posts.id")
42
- assert_equal 2, posts.first.comments.size
43
- assert_equal 2, posts.first.categories.size
44
- assert posts.first.comments.include?(comments(:greetings))
45
- end
46
-
47
- def test_loading_from_an_association
48
- posts = authors(:david).posts.find(:all, :include => :comments, :order => "posts.id")
49
- assert_equal 2, posts.first.comments.size
50
- end
51
-
52
- def test_loading_with_no_associations
53
- assert_nil Post.find(posts(:authorless).id, :include => :author).author
54
- end
55
-
56
- def test_eager_association_loading_with_belongs_to
57
- comments = Comment.find(:all, :include => :post)
58
- assert_equal 10, comments.length
59
- titles = comments.map { |c| c.post.title }
60
- assert titles.include?(posts(:welcome).title)
61
- assert titles.include?(posts(:sti_post_and_comments).title)
62
- end
63
-
64
- def test_eager_association_loading_with_belongs_to_and_limit
65
- comments = Comment.find(:all, :include => :post, :limit => 5, :order => 'comments.id')
66
- assert_equal 5, comments.length
67
- assert_equal [1,2,3,5,6], comments.collect { |c| c.id }
68
- end
69
-
70
- def test_eager_association_loading_with_belongs_to_and_limit_and_conditions
71
- comments = Comment.find(:all, :include => :post, :conditions => 'post_id = 4', :limit => 3, :order => 'comments.id')
72
- assert_equal 3, comments.length
73
- assert_equal [5,6,7], comments.collect { |c| c.id }
74
- end
75
-
76
- def test_eager_association_loading_with_belongs_to_and_limit_and_offset
77
- comments = Comment.find(:all, :include => :post, :limit => 3, :offset => 2, :order => 'comments.id')
78
- assert_equal 3, comments.length
79
- assert_equal [3,5,6], comments.collect { |c| c.id }
80
- end
81
-
82
- def test_eager_association_loading_with_belongs_to_and_limit_and_offset_and_conditions
83
- comments = Comment.find(:all, :include => :post, :conditions => 'post_id = 4', :limit => 3, :offset => 1, :order => 'comments.id')
84
- assert_equal 3, comments.length
85
- assert_equal [6,7,8], comments.collect { |c| c.id }
86
- end
87
-
88
- def test_eager_association_loading_with_belongs_to_and_limit_and_offset_and_conditions_array
89
- comments = Comment.find(:all, :include => :post, :conditions => ['post_id = ?',4], :limit => 3, :offset => 1, :order => 'comments.id')
90
- assert_equal 3, comments.length
91
- assert_equal [6,7,8], comments.collect { |c| c.id }
92
- end
93
-
94
- def test_eager_association_loading_with_belongs_to_and_limit_and_multiple_associations
95
- posts = Post.find(:all, :include => [:author, :very_special_comment], :limit => 1, :order => 'posts.id')
96
- assert_equal 1, posts.length
97
- assert_equal [1], posts.collect { |p| p.id }
98
- end
99
-
100
- def test_eager_association_loading_with_belongs_to_and_limit_and_offset_and_multiple_associations
101
- posts = Post.find(:all, :include => [:author, :very_special_comment], :limit => 1, :offset => 1, :order => 'posts.id')
102
- assert_equal 1, posts.length
103
- assert_equal [2], posts.collect { |p| p.id }
104
- end
105
-
106
- def test_eager_with_has_many_through
107
- posts_with_comments = people(:michael).posts.find(:all, :include => :comments)
108
- posts_with_author = people(:michael).posts.find(:all, :include => :author )
109
- posts_with_comments_and_author = people(:michael).posts.find(:all, :include => [ :comments, :author ])
110
- assert_equal 2, posts_with_comments.inject(0) { |sum, post| sum += post.comments.size }
111
- assert_equal authors(:david), assert_no_queries { posts_with_author.first.author }
112
- assert_equal authors(:david), assert_no_queries { posts_with_comments_and_author.first.author }
113
- end
114
-
115
- def test_eager_with_has_many_through_an_sti_join_model
116
- author = Author.find(:first, :include => :special_post_comments, :order => 'authors.id')
117
- assert_equal [comments(:does_it_hurt)], assert_no_queries { author.special_post_comments }
118
- end
119
-
120
- def test_eager_with_has_many_through_an_sti_join_model_with_conditions_on_both
121
- author = Author.find(:first, :include => :special_nonexistant_post_comments, :order => 'authors.id')
122
- assert_equal [], author.special_nonexistant_post_comments
123
- end
124
-
125
- def test_eager_with_has_many_through_join_model_with_conditions
126
- assert_equal Author.find(:first, :include => :hello_post_comments,
127
- :order => 'authors.id').hello_post_comments.sort_by(&:id),
128
- Author.find(:first, :order => 'authors.id').hello_post_comments.sort_by(&:id)
129
- end
130
-
131
- def test_eager_with_has_many_and_limit
132
- posts = Post.find(:all, :order => 'posts.id asc', :include => [ :author, :comments ], :limit => 2)
133
- assert_equal 2, posts.size
134
- assert_equal 3, posts.inject(0) { |sum, post| sum += post.comments.size }
135
- end
136
-
137
- def test_eager_with_has_many_and_limit_and_conditions
138
- posts = Post.find(:all, :include => [ :author, :comments ], :limit => 2, :conditions => "posts.body = 'hello'", :order => "posts.id")
139
- assert_equal 2, posts.size
140
- assert_equal [4,5], posts.collect { |p| p.id }
141
- end
142
-
143
- def test_eager_with_has_many_and_limit_and_conditions_array
144
- posts = Post.find(:all, :include => [ :author, :comments ], :limit => 2, :conditions => [ "posts.body = ?", 'hello' ], :order => "posts.id")
145
- assert_equal 2, posts.size
146
- assert_equal [4,5], posts.collect { |p| p.id }
147
- end
148
-
149
- def test_eager_with_has_many_and_limit_and_conditions_array_on_the_eagers
150
- posts = Post.find(:all, :include => [ :author, :comments ], :limit => 2, :conditions => [ "authors.name = ?", 'David' ])
151
- assert_equal 2, posts.size
152
-
153
- count = Post.count(:include => [ :author, :comments ], :limit => 2, :conditions => [ "authors.name = ?", 'David' ])
154
- assert_equal count, posts.size
155
- end
156
-
157
- def test_eager_with_has_many_and_limit_ond_high_offset
158
- posts = Post.find(:all, :include => [ :author, :comments ], :limit => 2, :offset => 10, :conditions => [ "authors.name = ?", 'David' ])
159
- assert_equal 0, posts.size
160
- end
161
-
162
- def test_count_eager_with_has_many_and_limit_ond_high_offset
163
- posts = Post.count(:all, :include => [ :author, :comments ], :limit => 2, :offset => 10, :conditions => [ "authors.name = ?", 'David' ])
164
- assert_equal 0, posts
165
- end
166
-
167
- def test_eager_with_has_many_and_limit_with_no_results
168
- posts = Post.find(:all, :include => [ :author, :comments ], :limit => 2, :conditions => "posts.title = 'magic forest'")
169
- assert_equal 0, posts.size
170
- end
171
-
172
- def test_eager_with_has_and_belongs_to_many_and_limit
173
- posts = Post.find(:all, :include => :categories, :order => "posts.id", :limit => 3)
174
- assert_equal 3, posts.size
175
- assert_equal 2, posts[0].categories.size
176
- assert_equal 1, posts[1].categories.size
177
- assert_equal 0, posts[2].categories.size
178
- assert posts[0].categories.include?(categories(:technology))
179
- assert posts[1].categories.include?(categories(:general))
180
- end
181
-
182
- def test_eager_with_has_many_and_limit_and_conditions_on_the_eagers
183
- posts = authors(:david).posts.find(:all,
184
- :include => :comments,
185
- :conditions => "comments.body like 'Normal%' OR comments.#{QUOTED_TYPE}= 'SpecialComment'",
186
- :limit => 2
187
- )
188
- assert_equal 2, posts.size
189
-
190
- count = Post.count(
191
- :include => [ :comments, :author ],
192
- :conditions => "authors.name = 'David' AND (comments.body like 'Normal%' OR comments.#{QUOTED_TYPE}= 'SpecialComment')",
193
- :limit => 2
194
- )
195
- assert_equal count, posts.size
196
- end
197
-
198
- def test_eager_with_has_many_and_limit_and_scoped_conditions_on_the_eagers
199
- posts = nil
200
- Post.with_scope(:find => {
201
- :include => :comments,
202
- :conditions => "comments.body like 'Normal%' OR comments.#{QUOTED_TYPE}= 'SpecialComment'"
203
- }) do
204
- posts = authors(:david).posts.find(:all, :limit => 2)
205
- assert_equal 2, posts.size
206
- end
207
-
208
- Post.with_scope(:find => {
209
- :include => [ :comments, :author ],
210
- :conditions => "authors.name = 'David' AND (comments.body like 'Normal%' OR comments.#{QUOTED_TYPE}= 'SpecialComment')"
211
- }) do
212
- count = Post.count(:limit => 2)
213
- assert_equal count, posts.size
214
- end
215
- end
216
-
217
- def test_eager_with_has_many_and_limit_and_scoped_and_explicit_conditions_on_the_eagers
218
- Post.with_scope(:find => { :conditions => "1=1" }) do
219
- posts = authors(:david).posts.find(:all,
220
- :include => :comments,
221
- :conditions => "comments.body like 'Normal%' OR comments.#{QUOTED_TYPE}= 'SpecialComment'",
222
- :limit => 2
223
- )
224
- assert_equal 2, posts.size
225
-
226
- count = Post.count(
227
- :include => [ :comments, :author ],
228
- :conditions => "authors.name = 'David' AND (comments.body like 'Normal%' OR comments.#{QUOTED_TYPE}= 'SpecialComment')",
229
- :limit => 2
230
- )
231
- assert_equal count, posts.size
232
- end
233
- end
234
- def test_eager_association_loading_with_habtm
235
- posts = Post.find(:all, :include => :categories, :order => "posts.id")
236
- assert_equal 2, posts[0].categories.size
237
- assert_equal 1, posts[1].categories.size
238
- assert_equal 0, posts[2].categories.size
239
- assert posts[0].categories.include?(categories(:technology))
240
- assert posts[1].categories.include?(categories(:general))
241
- end
242
-
243
- def test_eager_with_inheritance
244
- posts = SpecialPost.find(:all, :include => [ :comments ])
245
- end
246
-
247
- def test_eager_has_one_with_association_inheritance
248
- post = Post.find(4, :include => [ :very_special_comment ])
249
- assert_equal "VerySpecialComment", post.very_special_comment.class.to_s
250
- end
251
-
252
- def test_eager_has_many_with_association_inheritance
253
- post = Post.find(4, :include => [ :special_comments ])
254
- post.special_comments.each do |special_comment|
255
- assert_equal "SpecialComment", special_comment.class.to_s
256
- end
257
- end
258
-
259
- def test_eager_habtm_with_association_inheritance
260
- post = Post.find(6, :include => [ :special_categories ])
261
- assert_equal 1, post.special_categories.size
262
- post.special_categories.each do |special_category|
263
- assert_equal "SpecialCategory", special_category.class.to_s
264
- end
265
- end
266
-
267
- def test_eager_with_has_one_dependent_does_not_destroy_dependent
268
- assert_not_nil companies(:first_firm).account
269
- f = Firm.find(:first, :include => :account,
270
- :conditions => ["companies.name = ?", "37signals"])
271
- assert_not_nil f.account
272
- assert_equal companies(:first_firm, :reload).account, f.account
273
- end
274
-
275
- def test_eager_with_invalid_association_reference
276
- assert_raises(ActiveRecord::ConfigurationError, "Association was not found; perhaps you misspelled it? You specified :include => :monkeys") {
277
- post = Post.find(6, :include=> :monkeys )
278
- }
279
- assert_raises(ActiveRecord::ConfigurationError, "Association was not found; perhaps you misspelled it? You specified :include => :monkeys") {
280
- post = Post.find(6, :include=>[ :monkeys ])
281
- }
282
- assert_raises(ActiveRecord::ConfigurationError, "Association was not found; perhaps you misspelled it? You specified :include => :monkeys") {
283
- post = Post.find(6, :include=>[ 'monkeys' ])
284
- }
285
- assert_raises(ActiveRecord::ConfigurationError, "Association was not found; perhaps you misspelled it? You specified :include => :monkeys, :elephants") {
286
- post = Post.find(6, :include=>[ :monkeys, :elephants ])
287
- }
288
- end
289
-
290
- def find_all_ordered(className, include=nil)
291
- className.find(:all, :order=>"#{className.table_name}.#{className.primary_key}", :include=>include)
292
- end
293
-
294
- def test_limited_eager_with_order
295
- unless current_adapter?(:IBM_DBAdapter)
296
- assert_equal [posts(:thinking), posts(:sti_comments)], Post.find(:all, :include => [:author, :comments], :conditions => "authors.name = 'David'", :order => 'UPPER(posts.title)', :limit => 2, :offset => 1)
297
- assert_equal [posts(:sti_post_and_comments), posts(:sti_comments)], Post.find(:all, :include => [:author, :comments], :conditions => "authors.name = 'David'", :order => 'UPPER(posts.title) DESC', :limit => 2, :offset => 1)
298
- else
299
- # LUW: [IBM][CLI Driver][DB2/LINUX] SQL0214N
300
- # An expression in the ORDER BY clause in the following position,
301
- # or starting with "UPPER..." in the "ORDER BY" clause is not valid.
302
- # Reason code = "2". SQLSTATE=42822 SQLCODE=-214:
303
- # SELECT O.* FROM (SELECT I.*, ROW_NUMBER() OVER () sys_row_num
304
- # FROM (SELECT DISTINCT posts.id FROM posts
305
- # LEFT OUTER JOIN authors ON authors.id = posts.author_id
306
- # LEFT OUTER JOIN comments ON comments.post_id = posts.id
307
- # WHERE (authors.name = 'David')
308
- # ORDER BY UPPER(posts.title)) AS I) AS O WHERE sys_row_num BETWEEN 2 AND 3
309
- #
310
- # i5: ActiveRecord::RecordNotFound: Couldn't find Post with ID=2
311
- #
312
- # zOS v9: ActiveRecord::RecordNotFound: Couldn't find Post with ID=2
313
- #
314
- end
315
- end
316
-
317
- def test_limited_eager_with_multiple_order_columns
318
- unless current_adapter?(:IBM_DBAdapter)
319
- assert_equal [posts(:thinking), posts(:sti_comments)], Post.find(:all, :include => [:author, :comments], :conditions => "authors.name = 'David'", :order => 'UPPER(posts.title), posts.id', :limit => 2, :offset => 1)
320
- assert_equal [posts(:sti_post_and_comments), posts(:sti_comments)], Post.find(:all, :include => [:author, :comments], :conditions => "authors.name = 'David'", :order => 'UPPER(posts.title) DESC, posts.id', :limit => 2, :offset => 1)
321
- else
322
- # LUW: [IBM][CLI Driver][DB2/LINUX] SQL0214N
323
- # An expression in the ORDER BY clause in the following position,
324
- # or starting with "UPPER..." in the "ORDER BY" clause is not valid.
325
- # Reason code = "2". SQLSTATE=42822 SQLCODE=-214:
326
- # SELECT O.* FROM (SELECT I.*, ROW_NUMBER() OVER () sys_row_num
327
- # FROM (SELECT DISTINCT posts.id FROM posts
328
- # LEFT OUTER JOIN authors ON authors.id = posts.author_id
329
- # LEFT OUTER JOIN comments ON comments.post_id = posts.id
330
- # WHERE (authors.name = 'David')
331
- # ORDER BY UPPER(posts.title), posts.id) AS I) AS O WHERE sys_row_num BETWEEN 2 AND 3
332
- #
333
- # i5: [IBM][CLI Driver][AS] SQL0214N
334
- # An expression in the ORDER BY clause in the following position,
335
- # or starting with "1" in the " OBY0002" clause is not valid.
336
- # Reason code = "2". SQLSTATE=42822 SQLCODE=-214:
337
- # SELECT DISTINCT posts.id FROM posts
338
- # LEFT OUTER JOIN authors ON authors.id = posts.author_id
339
- # LEFT OUTER JOIN comments ON comments.post_id = posts.id
340
- # WHERE (authors.name = 'David')
341
- # ORDER BY UPPER(posts.title), posts.id
342
- #
343
- # zOS 9: [IBM][CLI Driver][DB2] SQL0214N
344
- # An expression in the ORDER BY clause in the following position,
345
- # or starting with "1" in the "ORDER BY" clause is not valid.
346
- # Reason code = "2". SQLSTATE=42822 SQLCODE=-214:
347
- # SELECT DISTINCT posts.id FROM posts
348
- # LEFT OUTER JOIN authors ON authors.id = posts.author_id
349
- # LEFT OUTER JOIN comments ON comments.post_id = posts.id
350
- # WHERE (authors.name = 'David')
351
- # ORDER BY UPPER(posts.title), posts.id
352
- #
353
- end
354
- end
355
-
356
- def test_eager_with_multiple_associations_with_same_table_has_many_and_habtm
357
- # Eager includes of has many and habtm associations aren't necessarily sorted in the same way
358
- def assert_equal_after_sort(item1, item2, item3 = nil)
359
- assert_equal(item1.sort{|a,b| a.id <=> b.id}, item2.sort{|a,b| a.id <=> b.id})
360
- assert_equal(item3.sort{|a,b| a.id <=> b.id}, item2.sort{|a,b| a.id <=> b.id}) if item3
361
- end
362
- # Test regular association, association with conditions, association with
363
- # STI, and association with conditions assured not to be true
364
- post_types = [:posts, :other_posts, :special_posts]
365
- # test both has_many and has_and_belongs_to_many
366
- [Author, Category].each do |className|
367
- d1 = find_all_ordered(className)
368
- # test including all post types at once
369
- d2 = find_all_ordered(className, post_types)
370
- d1.each_index do |i|
371
- assert_equal(d1[i], d2[i])
372
- assert_equal_after_sort(d1[i].posts, d2[i].posts)
373
- post_types[1..-1].each do |post_type|
374
- # test including post_types together
375
- d3 = find_all_ordered(className, [:posts, post_type])
376
- assert_equal(d1[i], d3[i])
377
- assert_equal_after_sort(d1[i].posts, d3[i].posts)
378
- assert_equal_after_sort(d1[i].send(post_type), d2[i].send(post_type), d3[i].send(post_type))
379
- end
380
- end
381
- end
382
- end
383
-
384
- def test_eager_with_multiple_associations_with_same_table_has_one
385
- d1 = find_all_ordered(Firm)
386
- d2 = find_all_ordered(Firm, :account)
387
- d1.each_index do |i|
388
- assert_equal(d1[i], d2[i])
389
- assert_equal(d1[i].account, d2[i].account)
390
- end
391
- end
392
-
393
- def test_eager_with_multiple_associations_with_same_table_belongs_to
394
- firm_types = [:firm, :firm_with_basic_id, :firm_with_other_name, :firm_with_condition]
395
- d1 = find_all_ordered(Client)
396
- d2 = find_all_ordered(Client, firm_types)
397
- d1.each_index do |i|
398
- assert_equal(d1[i], d2[i])
399
- firm_types.each { |type| assert_equal(d1[i].send(type), d2[i].send(type)) }
400
- end
401
- end
402
- def test_eager_with_valid_association_as_string_not_symbol
403
- assert_nothing_raised { Post.find(:all, :include => 'comments') }
404
- end
405
-
406
- def test_preconfigured_includes_with_belongs_to
407
- author = posts(:welcome).author_with_posts
408
- assert_equal 5, author.posts.size
409
- end
410
-
411
- def test_preconfigured_includes_with_has_one
412
- comment = posts(:sti_comments).very_special_comment_with_post
413
- assert_equal posts(:sti_comments), comment.post
414
- end
415
-
416
- def test_preconfigured_includes_with_has_many
417
- posts = authors(:david).posts_with_comments
418
- one = posts.detect { |p| p.id == 1 }
419
- assert_equal 5, posts.size
420
- assert_equal 2, one.comments.size
421
- end
422
-
423
- def test_preconfigured_includes_with_habtm
424
- posts = authors(:david).posts_with_categories
425
- one = posts.detect { |p| p.id == 1 }
426
- assert_equal 5, posts.size
427
- assert_equal 2, one.categories.size
428
- end
429
-
430
- def test_preconfigured_includes_with_has_many_and_habtm
431
- posts = authors(:david).posts_with_comments_and_categories
432
- one = posts.detect { |p| p.id == 1 }
433
- assert_equal 5, posts.size
434
- assert_equal 2, one.comments.size
435
- assert_equal 2, one.categories.size
436
- end
437
-
438
- def test_count_with_include
439
- if current_adapter?(:SQLServerAdapter, :SybaseAdapter)
440
- assert_equal 3, authors(:david).posts_with_comments.count(:conditions => "len(comments.body) > 15")
441
- else
442
- assert_equal 3, authors(:david).posts_with_comments.count(:conditions => "length(comments.body) > 15")
443
- end
444
- end
445
- end
1
+ require 'abstract_unit'
2
+ require 'fixtures/post'
3
+ require 'fixtures/comment'
4
+ require 'fixtures/author'
5
+ require 'fixtures/category'
6
+ require 'fixtures/company'
7
+ require 'fixtures/person'
8
+ require 'fixtures/reader'
9
+
10
+ class EagerAssociationTest < Test::Unit::TestCase
11
+ fixtures :posts, :comments, :authors, :categories, :categories_posts,
12
+ :companies, :accounts, :tags, :people, :readers
13
+
14
+ def test_loading_with_one_association
15
+ posts = Post.find(:all, :include => :comments)
16
+ post = posts.find { |p| p.id == 1 }
17
+ assert_equal 2, post.comments.size
18
+ assert post.comments.include?(comments(:greetings))
19
+
20
+ post = Post.find(:first, :include => :comments, :conditions => "posts.title = 'Welcome to the weblog'")
21
+ assert_equal 2, post.comments.size
22
+ assert post.comments.include?(comments(:greetings))
23
+ end
24
+
25
+ def test_loading_conditions_with_or
26
+ posts = authors(:david).posts.find(:all, :include => :comments, :conditions => "comments.body like 'Normal%' OR comments.#{QUOTED_TYPE} = 'SpecialComment'")
27
+ assert_nil posts.detect { |p| p.author_id != authors(:david).id },
28
+ "expected to find only david's posts"
29
+ end
30
+
31
+ def test_with_ordering
32
+ list = Post.find(:all, :include => :comments, :order => "posts.id DESC")
33
+ [:eager_other, :sti_habtm, :sti_post_and_comments, :sti_comments,
34
+ :authorless, :thinking, :welcome
35
+ ].each_with_index do |post, index|
36
+ assert_equal posts(post), list[index]
37
+ end
38
+ end
39
+
40
+ def test_loading_with_multiple_associations
41
+ posts = Post.find(:all, :include => [ :comments, :author, :categories ], :order => "posts.id")
42
+ assert_equal 2, posts.first.comments.size
43
+ assert_equal 2, posts.first.categories.size
44
+ assert posts.first.comments.include?(comments(:greetings))
45
+ end
46
+
47
+ def test_loading_from_an_association
48
+ posts = authors(:david).posts.find(:all, :include => :comments, :order => "posts.id")
49
+ assert_equal 2, posts.first.comments.size
50
+ end
51
+
52
+ def test_loading_with_no_associations
53
+ assert_nil Post.find(posts(:authorless).id, :include => :author).author
54
+ end
55
+
56
+ def test_eager_association_loading_with_belongs_to
57
+ comments = Comment.find(:all, :include => :post)
58
+ assert_equal 10, comments.length
59
+ titles = comments.map { |c| c.post.title }
60
+ assert titles.include?(posts(:welcome).title)
61
+ assert titles.include?(posts(:sti_post_and_comments).title)
62
+ end
63
+
64
+ def test_eager_association_loading_with_belongs_to_and_limit
65
+ comments = Comment.find(:all, :include => :post, :limit => 5, :order => 'comments.id')
66
+ assert_equal 5, comments.length
67
+ assert_equal [1,2,3,5,6], comments.collect { |c| c.id }
68
+ end
69
+
70
+ def test_eager_association_loading_with_belongs_to_and_limit_and_conditions
71
+ comments = Comment.find(:all, :include => :post, :conditions => 'post_id = 4', :limit => 3, :order => 'comments.id')
72
+ assert_equal 3, comments.length
73
+ assert_equal [5,6,7], comments.collect { |c| c.id }
74
+ end
75
+
76
+ def test_eager_association_loading_with_belongs_to_and_limit_and_offset
77
+ comments = Comment.find(:all, :include => :post, :limit => 3, :offset => 2, :order => 'comments.id')
78
+ assert_equal 3, comments.length
79
+ assert_equal [3,5,6], comments.collect { |c| c.id }
80
+ end
81
+
82
+ def test_eager_association_loading_with_belongs_to_and_limit_and_offset_and_conditions
83
+ comments = Comment.find(:all, :include => :post, :conditions => 'post_id = 4', :limit => 3, :offset => 1, :order => 'comments.id')
84
+ assert_equal 3, comments.length
85
+ assert_equal [6,7,8], comments.collect { |c| c.id }
86
+ end
87
+
88
+ def test_eager_association_loading_with_belongs_to_and_limit_and_offset_and_conditions_array
89
+ comments = Comment.find(:all, :include => :post, :conditions => ['post_id = ?',4], :limit => 3, :offset => 1, :order => 'comments.id')
90
+ assert_equal 3, comments.length
91
+ assert_equal [6,7,8], comments.collect { |c| c.id }
92
+ end
93
+
94
+ def test_eager_association_loading_with_belongs_to_and_limit_and_multiple_associations
95
+ posts = Post.find(:all, :include => [:author, :very_special_comment], :limit => 1, :order => 'posts.id')
96
+ assert_equal 1, posts.length
97
+ assert_equal [1], posts.collect { |p| p.id }
98
+ end
99
+
100
+ def test_eager_association_loading_with_belongs_to_and_limit_and_offset_and_multiple_associations
101
+ posts = Post.find(:all, :include => [:author, :very_special_comment], :limit => 1, :offset => 1, :order => 'posts.id')
102
+ assert_equal 1, posts.length
103
+ assert_equal [2], posts.collect { |p| p.id }
104
+ end
105
+
106
+ def test_eager_with_has_many_through
107
+ posts_with_comments = people(:michael).posts.find(:all, :include => :comments)
108
+ posts_with_author = people(:michael).posts.find(:all, :include => :author )
109
+ posts_with_comments_and_author = people(:michael).posts.find(:all, :include => [ :comments, :author ])
110
+ assert_equal 2, posts_with_comments.inject(0) { |sum, post| sum += post.comments.size }
111
+ assert_equal authors(:david), assert_no_queries { posts_with_author.first.author }
112
+ assert_equal authors(:david), assert_no_queries { posts_with_comments_and_author.first.author }
113
+ end
114
+
115
+ def test_eager_with_has_many_through_an_sti_join_model
116
+ author = Author.find(:first, :include => :special_post_comments, :order => 'authors.id')
117
+ assert_equal [comments(:does_it_hurt)], assert_no_queries { author.special_post_comments }
118
+ end
119
+
120
+ def test_eager_with_has_many_through_an_sti_join_model_with_conditions_on_both
121
+ author = Author.find(:first, :include => :special_nonexistant_post_comments, :order => 'authors.id')
122
+ assert_equal [], author.special_nonexistant_post_comments
123
+ end
124
+
125
+ def test_eager_with_has_many_through_join_model_with_conditions
126
+ assert_equal Author.find(:first, :include => :hello_post_comments,
127
+ :order => 'authors.id').hello_post_comments.sort_by(&:id),
128
+ Author.find(:first, :order => 'authors.id').hello_post_comments.sort_by(&:id)
129
+ end
130
+
131
+ def test_eager_with_has_many_and_limit
132
+ posts = Post.find(:all, :order => 'posts.id asc', :include => [ :author, :comments ], :limit => 2)
133
+ assert_equal 2, posts.size
134
+ assert_equal 3, posts.inject(0) { |sum, post| sum += post.comments.size }
135
+ end
136
+
137
+ def test_eager_with_has_many_and_limit_and_conditions
138
+ posts = Post.find(:all, :include => [ :author, :comments ], :limit => 2, :conditions => "posts.body = 'hello'", :order => "posts.id")
139
+ assert_equal 2, posts.size
140
+ assert_equal [4,5], posts.collect { |p| p.id }
141
+ end
142
+
143
+ def test_eager_with_has_many_and_limit_and_conditions_array
144
+ posts = Post.find(:all, :include => [ :author, :comments ], :limit => 2, :conditions => [ "posts.body = ?", 'hello' ], :order => "posts.id")
145
+ assert_equal 2, posts.size
146
+ assert_equal [4,5], posts.collect { |p| p.id }
147
+ end
148
+
149
+ def test_eager_with_has_many_and_limit_and_conditions_array_on_the_eagers
150
+ posts = Post.find(:all, :include => [ :author, :comments ], :limit => 2, :conditions => [ "authors.name = ?", 'David' ])
151
+ assert_equal 2, posts.size
152
+
153
+ count = Post.count(:include => [ :author, :comments ], :limit => 2, :conditions => [ "authors.name = ?", 'David' ])
154
+ assert_equal count, posts.size
155
+ end
156
+
157
+ def test_eager_with_has_many_and_limit_ond_high_offset
158
+ posts = Post.find(:all, :include => [ :author, :comments ], :limit => 2, :offset => 10, :conditions => [ "authors.name = ?", 'David' ])
159
+ assert_equal 0, posts.size
160
+ end
161
+
162
+ def test_count_eager_with_has_many_and_limit_ond_high_offset
163
+ posts = Post.count(:all, :include => [ :author, :comments ], :limit => 2, :offset => 10, :conditions => [ "authors.name = ?", 'David' ])
164
+ assert_equal 0, posts
165
+ end
166
+
167
+ def test_eager_with_has_many_and_limit_with_no_results
168
+ posts = Post.find(:all, :include => [ :author, :comments ], :limit => 2, :conditions => "posts.title = 'magic forest'")
169
+ assert_equal 0, posts.size
170
+ end
171
+
172
+ def test_eager_with_has_and_belongs_to_many_and_limit
173
+ posts = Post.find(:all, :include => :categories, :order => "posts.id", :limit => 3)
174
+ assert_equal 3, posts.size
175
+ assert_equal 2, posts[0].categories.size
176
+ assert_equal 1, posts[1].categories.size
177
+ assert_equal 0, posts[2].categories.size
178
+ assert posts[0].categories.include?(categories(:technology))
179
+ assert posts[1].categories.include?(categories(:general))
180
+ end
181
+
182
+ def test_eager_with_has_many_and_limit_and_conditions_on_the_eagers
183
+ posts = authors(:david).posts.find(:all,
184
+ :include => :comments,
185
+ :conditions => "comments.body like 'Normal%' OR comments.#{QUOTED_TYPE}= 'SpecialComment'",
186
+ :limit => 2
187
+ )
188
+ assert_equal 2, posts.size
189
+
190
+ count = Post.count(
191
+ :include => [ :comments, :author ],
192
+ :conditions => "authors.name = 'David' AND (comments.body like 'Normal%' OR comments.#{QUOTED_TYPE}= 'SpecialComment')",
193
+ :limit => 2
194
+ )
195
+ assert_equal count, posts.size
196
+ end
197
+
198
+ def test_eager_with_has_many_and_limit_and_scoped_conditions_on_the_eagers
199
+ posts = nil
200
+ Post.with_scope(:find => {
201
+ :include => :comments,
202
+ :conditions => "comments.body like 'Normal%' OR comments.#{QUOTED_TYPE}= 'SpecialComment'"
203
+ }) do
204
+ posts = authors(:david).posts.find(:all, :limit => 2)
205
+ assert_equal 2, posts.size
206
+ end
207
+
208
+ Post.with_scope(:find => {
209
+ :include => [ :comments, :author ],
210
+ :conditions => "authors.name = 'David' AND (comments.body like 'Normal%' OR comments.#{QUOTED_TYPE}= 'SpecialComment')"
211
+ }) do
212
+ count = Post.count(:limit => 2)
213
+ assert_equal count, posts.size
214
+ end
215
+ end
216
+
217
+ def test_eager_with_has_many_and_limit_and_scoped_and_explicit_conditions_on_the_eagers
218
+ Post.with_scope(:find => { :conditions => "1=1" }) do
219
+ posts = authors(:david).posts.find(:all,
220
+ :include => :comments,
221
+ :conditions => "comments.body like 'Normal%' OR comments.#{QUOTED_TYPE}= 'SpecialComment'",
222
+ :limit => 2
223
+ )
224
+ assert_equal 2, posts.size
225
+
226
+ count = Post.count(
227
+ :include => [ :comments, :author ],
228
+ :conditions => "authors.name = 'David' AND (comments.body like 'Normal%' OR comments.#{QUOTED_TYPE}= 'SpecialComment')",
229
+ :limit => 2
230
+ )
231
+ assert_equal count, posts.size
232
+ end
233
+ end
234
+ def test_eager_association_loading_with_habtm
235
+ posts = Post.find(:all, :include => :categories, :order => "posts.id")
236
+ assert_equal 2, posts[0].categories.size
237
+ assert_equal 1, posts[1].categories.size
238
+ assert_equal 0, posts[2].categories.size
239
+ assert posts[0].categories.include?(categories(:technology))
240
+ assert posts[1].categories.include?(categories(:general))
241
+ end
242
+
243
+ def test_eager_with_inheritance
244
+ posts = SpecialPost.find(:all, :include => [ :comments ])
245
+ end
246
+
247
+ def test_eager_has_one_with_association_inheritance
248
+ post = Post.find(4, :include => [ :very_special_comment ])
249
+ assert_equal "VerySpecialComment", post.very_special_comment.class.to_s
250
+ end
251
+
252
+ def test_eager_has_many_with_association_inheritance
253
+ post = Post.find(4, :include => [ :special_comments ])
254
+ post.special_comments.each do |special_comment|
255
+ assert_equal "SpecialComment", special_comment.class.to_s
256
+ end
257
+ end
258
+
259
+ def test_eager_habtm_with_association_inheritance
260
+ post = Post.find(6, :include => [ :special_categories ])
261
+ assert_equal 1, post.special_categories.size
262
+ post.special_categories.each do |special_category|
263
+ assert_equal "SpecialCategory", special_category.class.to_s
264
+ end
265
+ end
266
+
267
+ def test_eager_with_has_one_dependent_does_not_destroy_dependent
268
+ assert_not_nil companies(:first_firm).account
269
+ f = Firm.find(:first, :include => :account,
270
+ :conditions => ["companies.name = ?", "37signals"])
271
+ assert_not_nil f.account
272
+ assert_equal companies(:first_firm, :reload).account, f.account
273
+ end
274
+
275
+ def test_eager_with_invalid_association_reference
276
+ assert_raises(ActiveRecord::ConfigurationError, "Association was not found; perhaps you misspelled it? You specified :include => :monkeys") {
277
+ post = Post.find(6, :include=> :monkeys )
278
+ }
279
+ assert_raises(ActiveRecord::ConfigurationError, "Association was not found; perhaps you misspelled it? You specified :include => :monkeys") {
280
+ post = Post.find(6, :include=>[ :monkeys ])
281
+ }
282
+ assert_raises(ActiveRecord::ConfigurationError, "Association was not found; perhaps you misspelled it? You specified :include => :monkeys") {
283
+ post = Post.find(6, :include=>[ 'monkeys' ])
284
+ }
285
+ assert_raises(ActiveRecord::ConfigurationError, "Association was not found; perhaps you misspelled it? You specified :include => :monkeys, :elephants") {
286
+ post = Post.find(6, :include=>[ :monkeys, :elephants ])
287
+ }
288
+ end
289
+
290
+ def find_all_ordered(className, include=nil)
291
+ className.find(:all, :order=>"#{className.table_name}.#{className.primary_key}", :include=>include)
292
+ end
293
+
294
+ def test_limited_eager_with_order
295
+ unless current_adapter?(:IBM_DBAdapter)
296
+ assert_equal [posts(:thinking), posts(:sti_comments)], Post.find(:all, :include => [:author, :comments], :conditions => "authors.name = 'David'", :order => 'UPPER(posts.title)', :limit => 2, :offset => 1)
297
+ assert_equal [posts(:sti_post_and_comments), posts(:sti_comments)], Post.find(:all, :include => [:author, :comments], :conditions => "authors.name = 'David'", :order => 'UPPER(posts.title) DESC', :limit => 2, :offset => 1)
298
+ else
299
+ # LUW: [IBM][CLI Driver][DB2/LINUX] SQL0214N
300
+ # An expression in the ORDER BY clause in the following position,
301
+ # or starting with "UPPER..." in the "ORDER BY" clause is not valid.
302
+ # Reason code = "2". SQLSTATE=42822 SQLCODE=-214:
303
+ # SELECT O.* FROM (SELECT I.*, ROW_NUMBER() OVER () sys_row_num
304
+ # FROM (SELECT DISTINCT posts.id FROM posts
305
+ # LEFT OUTER JOIN authors ON authors.id = posts.author_id
306
+ # LEFT OUTER JOIN comments ON comments.post_id = posts.id
307
+ # WHERE (authors.name = 'David')
308
+ # ORDER BY UPPER(posts.title)) AS I) AS O WHERE sys_row_num BETWEEN 2 AND 3
309
+ #
310
+ # i5: ActiveRecord::RecordNotFound: Couldn't find Post with ID=2
311
+ #
312
+ # zOS v9: ActiveRecord::RecordNotFound: Couldn't find Post with ID=2
313
+ #
314
+ end
315
+ end
316
+
317
+ def test_limited_eager_with_multiple_order_columns
318
+ unless current_adapter?(:IBM_DBAdapter)
319
+ assert_equal [posts(:thinking), posts(:sti_comments)], Post.find(:all, :include => [:author, :comments], :conditions => "authors.name = 'David'", :order => 'UPPER(posts.title), posts.id', :limit => 2, :offset => 1)
320
+ assert_equal [posts(:sti_post_and_comments), posts(:sti_comments)], Post.find(:all, :include => [:author, :comments], :conditions => "authors.name = 'David'", :order => 'UPPER(posts.title) DESC, posts.id', :limit => 2, :offset => 1)
321
+ else
322
+ # LUW: [IBM][CLI Driver][DB2/LINUX] SQL0214N
323
+ # An expression in the ORDER BY clause in the following position,
324
+ # or starting with "UPPER..." in the "ORDER BY" clause is not valid.
325
+ # Reason code = "2". SQLSTATE=42822 SQLCODE=-214:
326
+ # SELECT O.* FROM (SELECT I.*, ROW_NUMBER() OVER () sys_row_num
327
+ # FROM (SELECT DISTINCT posts.id FROM posts
328
+ # LEFT OUTER JOIN authors ON authors.id = posts.author_id
329
+ # LEFT OUTER JOIN comments ON comments.post_id = posts.id
330
+ # WHERE (authors.name = 'David')
331
+ # ORDER BY UPPER(posts.title), posts.id) AS I) AS O WHERE sys_row_num BETWEEN 2 AND 3
332
+ #
333
+ # i5: [IBM][CLI Driver][AS] SQL0214N
334
+ # An expression in the ORDER BY clause in the following position,
335
+ # or starting with "1" in the " OBY0002" clause is not valid.
336
+ # Reason code = "2". SQLSTATE=42822 SQLCODE=-214:
337
+ # SELECT DISTINCT posts.id FROM posts
338
+ # LEFT OUTER JOIN authors ON authors.id = posts.author_id
339
+ # LEFT OUTER JOIN comments ON comments.post_id = posts.id
340
+ # WHERE (authors.name = 'David')
341
+ # ORDER BY UPPER(posts.title), posts.id
342
+ #
343
+ # zOS 9: [IBM][CLI Driver][DB2] SQL0214N
344
+ # An expression in the ORDER BY clause in the following position,
345
+ # or starting with "1" in the "ORDER BY" clause is not valid.
346
+ # Reason code = "2". SQLSTATE=42822 SQLCODE=-214:
347
+ # SELECT DISTINCT posts.id FROM posts
348
+ # LEFT OUTER JOIN authors ON authors.id = posts.author_id
349
+ # LEFT OUTER JOIN comments ON comments.post_id = posts.id
350
+ # WHERE (authors.name = 'David')
351
+ # ORDER BY UPPER(posts.title), posts.id
352
+ #
353
+ end
354
+ end
355
+
356
+ def test_eager_with_multiple_associations_with_same_table_has_many_and_habtm
357
+ # Eager includes of has many and habtm associations aren't necessarily sorted in the same way
358
+ def assert_equal_after_sort(item1, item2, item3 = nil)
359
+ assert_equal(item1.sort{|a,b| a.id <=> b.id}, item2.sort{|a,b| a.id <=> b.id})
360
+ assert_equal(item3.sort{|a,b| a.id <=> b.id}, item2.sort{|a,b| a.id <=> b.id}) if item3
361
+ end
362
+ # Test regular association, association with conditions, association with
363
+ # STI, and association with conditions assured not to be true
364
+ post_types = [:posts, :other_posts, :special_posts]
365
+ # test both has_many and has_and_belongs_to_many
366
+ [Author, Category].each do |className|
367
+ d1 = find_all_ordered(className)
368
+ # test including all post types at once
369
+ d2 = find_all_ordered(className, post_types)
370
+ d1.each_index do |i|
371
+ assert_equal(d1[i], d2[i])
372
+ assert_equal_after_sort(d1[i].posts, d2[i].posts)
373
+ post_types[1..-1].each do |post_type|
374
+ # test including post_types together
375
+ d3 = find_all_ordered(className, [:posts, post_type])
376
+ assert_equal(d1[i], d3[i])
377
+ assert_equal_after_sort(d1[i].posts, d3[i].posts)
378
+ assert_equal_after_sort(d1[i].send(post_type), d2[i].send(post_type), d3[i].send(post_type))
379
+ end
380
+ end
381
+ end
382
+ end
383
+
384
+ def test_eager_with_multiple_associations_with_same_table_has_one
385
+ d1 = find_all_ordered(Firm)
386
+ d2 = find_all_ordered(Firm, :account)
387
+ d1.each_index do |i|
388
+ assert_equal(d1[i], d2[i])
389
+ assert_equal(d1[i].account, d2[i].account)
390
+ end
391
+ end
392
+
393
+ def test_eager_with_multiple_associations_with_same_table_belongs_to
394
+ firm_types = [:firm, :firm_with_basic_id, :firm_with_other_name, :firm_with_condition]
395
+ d1 = find_all_ordered(Client)
396
+ d2 = find_all_ordered(Client, firm_types)
397
+ d1.each_index do |i|
398
+ assert_equal(d1[i], d2[i])
399
+ firm_types.each { |type| assert_equal(d1[i].send(type), d2[i].send(type)) }
400
+ end
401
+ end
402
+ def test_eager_with_valid_association_as_string_not_symbol
403
+ assert_nothing_raised { Post.find(:all, :include => 'comments') }
404
+ end
405
+
406
+ def test_preconfigured_includes_with_belongs_to
407
+ author = posts(:welcome).author_with_posts
408
+ assert_equal 5, author.posts.size
409
+ end
410
+
411
+ def test_preconfigured_includes_with_has_one
412
+ comment = posts(:sti_comments).very_special_comment_with_post
413
+ assert_equal posts(:sti_comments), comment.post
414
+ end
415
+
416
+ def test_preconfigured_includes_with_has_many
417
+ posts = authors(:david).posts_with_comments
418
+ one = posts.detect { |p| p.id == 1 }
419
+ assert_equal 5, posts.size
420
+ assert_equal 2, one.comments.size
421
+ end
422
+
423
+ def test_preconfigured_includes_with_habtm
424
+ posts = authors(:david).posts_with_categories
425
+ one = posts.detect { |p| p.id == 1 }
426
+ assert_equal 5, posts.size
427
+ assert_equal 2, one.categories.size
428
+ end
429
+
430
+ def test_preconfigured_includes_with_has_many_and_habtm
431
+ posts = authors(:david).posts_with_comments_and_categories
432
+ one = posts.detect { |p| p.id == 1 }
433
+ assert_equal 5, posts.size
434
+ assert_equal 2, one.comments.size
435
+ assert_equal 2, one.categories.size
436
+ end
437
+
438
+ def test_count_with_include
439
+ if current_adapter?(:SQLServerAdapter, :SybaseAdapter)
440
+ assert_equal 3, authors(:david).posts_with_comments.count(:conditions => "len(comments.body) > 15")
441
+ else
442
+ assert_equal 3, authors(:david).posts_with_comments.count(:conditions => "length(comments.body) > 15")
443
+ end
444
+ end
445
+ end