ibm_db 0.9.0 → 0.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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