ibm_db 0.9.4 → 0.9.5

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.
data/test/adapter_test.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  require 'abstract_unit'
2
2
 
3
- class AdapterTest < Test::Unit::TestCase
3
+ class IBMDBAdapterTest < Test::Unit::TestCase
4
4
  def setup
5
5
  @connection = ActiveRecord::Base.connection
6
6
  end
@@ -48,7 +48,7 @@ class AdapterTest < Test::Unit::TestCase
48
48
  end
49
49
  end
50
50
  end
51
-
51
+
52
52
  def test_tables
53
53
  if @connection.respond_to?(:tables)
54
54
  tables = @connection.tables
@@ -62,8 +62,8 @@ class AdapterTest < Test::Unit::TestCase
62
62
  end
63
63
 
64
64
  def test_indexes
65
- idx_name = "#{ActiveRecord::Base.connection.schema}.accounts_idx"
66
-
65
+ idx_name = "accounts_idx"
66
+
67
67
  if @connection.respond_to?(:indexes)
68
68
  indexes = @connection.indexes("accounts")
69
69
  assert indexes.empty?
@@ -83,24 +83,42 @@ class AdapterTest < Test::Unit::TestCase
83
83
  ensure
84
84
  @connection.remove_index(:accounts, :name => idx_name) rescue nil
85
85
  end
86
-
86
+
87
87
  def test_current_database
88
88
  if @connection.respond_to?(:current_database)
89
89
  assert_equal ENV['ARUNIT_DB_NAME'] || "activerecord_unittest", @connection.current_database
90
90
  end
91
91
  end
92
92
 
93
+ if current_adapter?(:MysqlAdapter)
94
+ def test_charset
95
+ assert_not_nil @connection.charset
96
+ assert_not_equal 'character_set_database', @connection.charset
97
+ assert_equal @connection.show_variable('character_set_database'), @connection.charset
98
+ end
99
+
100
+ def test_collation
101
+ assert_not_nil @connection.collation
102
+ assert_not_equal 'collation_database', @connection.collation
103
+ assert_equal @connection.show_variable('collation_database'), @connection.collation
104
+ end
105
+
106
+ def test_show_nonexistent_variable_returns_nil
107
+ assert_nil @connection.show_variable('foo_bar_baz')
108
+ end
109
+ end
110
+
93
111
  def test_table_alias
94
112
  def @connection.test_table_alias_length() 10; end
95
113
  class << @connection
96
114
  alias_method :old_table_alias_length, :table_alias_length
97
115
  alias_method :table_alias_length, :test_table_alias_length
98
116
  end
99
-
117
+
100
118
  assert_equal 'posts', @connection.table_alias_for('posts')
101
119
  assert_equal 'posts_comm', @connection.table_alias_for('posts_comments')
102
120
  assert_equal 'dbo_posts', @connection.table_alias_for('dbo.posts')
103
-
121
+
104
122
  class << @connection
105
123
  alias_method :table_alias_length, :old_table_alias_length
106
124
  end
@@ -110,7 +128,7 @@ class AdapterTest < Test::Unit::TestCase
110
128
  if ActiveRecord::Base.connection.respond_to?(:reset_pk_sequence!)
111
129
  require 'fixtures/movie'
112
130
  require 'fixtures/subscriber'
113
-
131
+
114
132
  def test_reset_empty_table_with_custom_pk
115
133
  Movie.delete_all
116
134
  Movie.connection.reset_pk_sequence! 'movies'
@@ -37,6 +37,18 @@ class EagerAssociationTest < Test::Unit::TestCase
37
37
  end
38
38
  end
39
39
 
40
+ def test_with_two_tables_in_from_without_getting_double_quoted
41
+ posts = Post.find(:all,
42
+ :select => "posts.*",
43
+ :from => "authors, posts",
44
+ :include => :comments,
45
+ :conditions => "posts.author_id = authors.id",
46
+ :order => "posts.id"
47
+ )
48
+
49
+ assert_equal 2, posts.first.comments.size
50
+ end
51
+
40
52
  def test_loading_with_multiple_associations
41
53
  posts = Post.find(:all, :include => [ :comments, :author, :categories ], :order => "posts.id")
42
54
  assert_equal 2, posts.first.comments.size
@@ -103,6 +115,14 @@ class EagerAssociationTest < Test::Unit::TestCase
103
115
  assert_equal [2], posts.collect { |p| p.id }
104
116
  end
105
117
 
118
+ def test_eager_association_loading_with_explicit_join
119
+ unless current_adapter?(:IBM_DBAdapter)#throws an error with sqlcode=-214,DISTINCT keyword in the select query not allowed
120
+
121
+ posts = Post.find(:all, :include => :comments, :joins => "INNER JOIN authors ON posts.author_id = authors.id AND authors.name = 'Mary'", :limit => 1, :order => 'author_id')
122
+ assert_equal 1, posts.length
123
+ end
124
+ end
125
+
106
126
  def test_eager_with_has_many_through
107
127
  posts_with_comments = people(:michael).posts.find(:all, :include => :comments)
108
128
  posts_with_author = people(:michael).posts.find(:all, :include => :author )
@@ -135,13 +155,21 @@ class EagerAssociationTest < Test::Unit::TestCase
135
155
  end
136
156
 
137
157
  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")
158
+ if current_adapter?(:OpenBaseAdapter)
159
+ posts = Post.find(:all, :include => [ :author, :comments ], :limit => 2, :conditions => "FETCHBLOB(posts.body) = 'hello'", :order => "posts.id")
160
+ else
161
+ posts = Post.find(:all, :include => [ :author, :comments ], :limit => 2, :conditions => "posts.body = 'hello'", :order => "posts.id")
162
+ end
139
163
  assert_equal 2, posts.size
140
164
  assert_equal [4,5], posts.collect { |p| p.id }
141
165
  end
142
166
 
143
167
  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")
168
+ if current_adapter?(:OpenBaseAdapter)
169
+ posts = Post.find(:all, :include => [ :author, :comments ], :limit => 2, :conditions => [ "FETCHBLOB(posts.body) = ?", 'hello' ], :order => "posts.id")
170
+ else
171
+ posts = Post.find(:all, :include => [ :author, :comments ], :limit => 2, :conditions => [ "posts.body = ?", 'hello' ], :order => "posts.id")
172
+ end
145
173
  assert_equal 2, posts.size
146
174
  assert_equal [4,5], posts.collect { |p| p.id }
147
175
  end
@@ -168,6 +196,12 @@ class EagerAssociationTest < Test::Unit::TestCase
168
196
  posts = Post.find(:all, :include => [ :author, :comments ], :limit => 2, :conditions => "posts.title = 'magic forest'")
169
197
  assert_equal 0, posts.size
170
198
  end
199
+
200
+ def test_eager_count_performed_on_a_has_many_association_with_multi_table_conditional
201
+ author = authors(:david)
202
+ author_posts_without_comments = author.posts.select { |post| post.comments.blank? }
203
+ assert_equal author_posts_without_comments.size, author.posts.count(:all, :include => :comments, :conditions => 'comments.id is null')
204
+ end
171
205
 
172
206
  def test_eager_with_has_and_belongs_to_many_and_limit
173
207
  posts = Post.find(:all, :include => :categories, :order => "posts.id", :limit => 3)
@@ -231,6 +265,15 @@ class EagerAssociationTest < Test::Unit::TestCase
231
265
  assert_equal count, posts.size
232
266
  end
233
267
  end
268
+
269
+ def test_eager_with_scoped_order_using_association_limiting_without_explicit_scope
270
+ posts_with_explicit_order = Post.find(:all, :conditions => 'comments.id is not null', :include => :comments, :order => 'posts.id DESC', :limit => 2)
271
+ posts_with_scoped_order = Post.with_scope(:find => {:order => 'posts.id DESC'}) do
272
+ Post.find(:all, :conditions => 'comments.id is not null', :include => :comments, :limit => 2)
273
+ end
274
+ assert_equal posts_with_explicit_order, posts_with_scoped_order
275
+ end
276
+
234
277
  def test_eager_association_loading_with_habtm
235
278
  posts = Post.find(:all, :include => :categories, :order => "posts.id")
236
279
  assert_equal 2, posts[0].categories.size
@@ -271,6 +314,13 @@ class EagerAssociationTest < Test::Unit::TestCase
271
314
  assert_not_nil f.account
272
315
  assert_equal companies(:first_firm, :reload).account, f.account
273
316
  end
317
+
318
+ def test_eager_with_multi_table_conditional_properly_counts_the_records_when_using_size
319
+ author = authors(:david)
320
+ posts_with_no_comments = author.posts.select { |post| post.comments.blank? }
321
+ assert_equal posts_with_no_comments.size, author.posts_with_no_comments.size
322
+ assert_equal posts_with_no_comments, author.posts_with_no_comments
323
+ end
274
324
 
275
325
  def test_eager_with_invalid_association_reference
276
326
  assert_raises(ActiveRecord::ConfigurationError, "Association was not found; perhaps you misspelled it? You specified :include => :monkeys") {
@@ -292,65 +342,18 @@ class EagerAssociationTest < Test::Unit::TestCase
292
342
  end
293
343
 
294
344
  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
345
+ unless current_adapter?(:IBM_DBAdapter)#throws an error with sqlcode=-214,DISTINCT keyword in the select query not allowed.
346
+ assert_equal posts(:thinking, :sti_comments), Post.find(:all, :include => [:author, :comments], :conditions => "authors.name = 'David'", :order => 'UPPER(posts.title)', :limit => 2, :offset => 1)
347
+ assert_equal posts(:sti_post_and_comments, :sti_comments), Post.find(:all, :include => [:author, :comments], :conditions => "authors.name = 'David'", :order => 'UPPER(posts.title) DESC', :limit => 2, :offset => 1)
348
+ end
315
349
  end
316
350
 
317
351
  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
352
+ unless current_adapter?(:IBM_DBAdapter)#throws an error with sqlcode=-214,DISTINCT keyword in the select query not allowed
353
+
354
+ assert_equal posts(:thinking, :sti_comments), Post.find(:all, :include => [:author, :comments], :conditions => "authors.name = 'David'", :order => 'UPPER(posts.title), posts.id', :limit => 2, :offset => 1)
355
+ assert_equal posts(:sti_post_and_comments, :sti_comments), Post.find(:all, :include => [:author, :comments], :conditions => "authors.name = 'David'", :order => 'UPPER(posts.title) DESC, posts.id', :limit => 2, :offset => 1)
356
+ end
354
357
  end
355
358
 
356
359
  def test_eager_with_multiple_associations_with_same_table_has_many_and_habtm
@@ -438,6 +441,8 @@ class EagerAssociationTest < Test::Unit::TestCase
438
441
  def test_count_with_include
439
442
  if current_adapter?(:SQLServerAdapter, :SybaseAdapter)
440
443
  assert_equal 3, authors(:david).posts_with_comments.count(:conditions => "len(comments.body) > 15")
444
+ elsif current_adapter?(:OpenBaseAdapter)
445
+ assert_equal 3, authors(:david).posts_with_comments.count(:conditions => "length(FETCHBLOB(comments.body)) > 15")
441
446
  else
442
447
  assert_equal 3, authors(:david).posts_with_comments.count(:conditions => "length(comments.body) > 15")
443
448
  end
@@ -7,12 +7,17 @@ require 'fixtures/reply'
7
7
  require 'fixtures/computer'
8
8
  require 'fixtures/customer'
9
9
  require 'fixtures/order'
10
+ require 'fixtures/categorization'
10
11
  require 'fixtures/category'
11
12
  require 'fixtures/post'
12
13
  require 'fixtures/author'
14
+ require 'fixtures/comment'
15
+ require 'fixtures/tag'
16
+ require 'fixtures/tagging'
17
+ require 'fixtures/person'
18
+ require 'fixtures/reader'
13
19
 
14
-
15
- class AssociationsTest < Test::Unit::TestCase
20
+ class IBMDBAssociationsTest < Test::Unit::TestCase
16
21
  fixtures :accounts, :companies, :developers, :projects, :developers_projects,
17
22
  :computers
18
23
 
@@ -21,24 +26,26 @@ class AssociationsTest < Test::Unit::TestCase
21
26
  Class.new(ActiveRecord::Base).has_many(:wheels, :name => 'wheels')
22
27
  end
23
28
  end
29
+
30
+ def test_should_construct_new_finder_sql_after_create
31
+ person = Person.new
32
+ assert_equal [], person.readers.find(:all)
33
+ person.save!
34
+ reader = Reader.create! :person => person, :post => Post.new(:title => "foo", :body => "bar")
35
+ assert_equal [reader], person.readers.find(:all)
36
+ end
24
37
 
25
38
  def test_force_reload
26
39
  firm = Firm.new("name" => "A New Firm, Inc")
27
40
  firm.save
28
41
  firm.clients.each {|c|} # forcing to load all clients
29
42
  assert firm.clients.empty?, "New firm shouldn't have client objects"
30
- assert_deprecated do
31
- assert !firm.has_clients?, "New firm shouldn't have clients"
32
- end
33
43
  assert_equal 0, firm.clients.size, "New firm should have 0 clients"
34
44
 
35
45
  client = Client.new("name" => "TheClient.com", "firm_id" => firm.id)
36
46
  client.save
37
47
 
38
48
  assert firm.clients.empty?, "New firm should have cached no client objects"
39
- assert_deprecated do
40
- assert !firm.has_clients?, "New firm should have cached a no-clients response"
41
- end
42
49
  assert_equal 0, firm.clients.size, "New firm should have cached 0 clients count"
43
50
 
44
51
  assert !firm.clients(true).empty?, "New firm should have reloaded client objects"
@@ -48,7 +55,7 @@ class AssociationsTest < Test::Unit::TestCase
48
55
  def test_storing_in_pstore
49
56
  require "tmpdir"
50
57
  store_filename = File.join(Dir.tmpdir, "ar-pstore-association-test")
51
- File.delete(store_filename) if File.exists?(store_filename)
58
+ File.delete(store_filename) if File.exist?(store_filename)
52
59
  require "pstore"
53
60
  apple = Firm.create("name" => "Apple")
54
61
  natural = Client.new("name" => "Natural Company")
@@ -66,9 +73,9 @@ class AssociationsTest < Test::Unit::TestCase
66
73
  end
67
74
  end
68
75
 
69
- class AssociationProxyTest < Test::Unit::TestCase
70
- fixtures :authors, :posts
71
-
76
+ class IBMDBAssociationProxyTest < Test::Unit::TestCase
77
+ fixtures :authors, :posts, :categorizations, :categories, :developers, :projects, :developers_projects
78
+
72
79
  def test_proxy_accessors
73
80
  welcome = posts(:welcome)
74
81
  assert_equal welcome, welcome.author.proxy_owner
@@ -81,21 +88,73 @@ class AssociationProxyTest < Test::Unit::TestCase
81
88
  assert_equal david.class.reflect_on_association(:posts), david.posts.proxy_reflection
82
89
  david.posts.first # force load target
83
90
  assert_equal david.posts, david.posts.proxy_target
84
-
91
+
85
92
  assert_equal david, david.posts_with_extension.testing_proxy_owner
86
93
  assert_equal david.class.reflect_on_association(:posts_with_extension), david.posts_with_extension.testing_proxy_reflection
87
94
  david.posts_with_extension.first # force load target
88
95
  assert_equal david.posts_with_extension, david.posts_with_extension.testing_proxy_target
89
96
  end
97
+
98
+ def test_push_does_not_load_target
99
+ david = authors(:david)
100
+
101
+ david.categories << categories(:technology)
102
+ assert !david.categories.loaded?
103
+ assert david.categories.include?(categories(:technology))
104
+ end
105
+
106
+ def test_push_does_not_lose_additions_to_new_record
107
+ josh = Author.new(:name => "Josh")
108
+ josh.posts << Post.new(:title => "New on Edge", :body => "More cool stuff!")
109
+ assert josh.posts.loaded?
110
+ assert_equal 1, josh.posts.size
111
+ end
112
+
113
+ def test_save_on_parent_does_not_load_target
114
+ david = developers(:david)
115
+
116
+ assert !david.projects.loaded?
117
+ david.update_attribute(:created_at, Time.now)
118
+ assert !david.projects.loaded?
119
+ end
120
+
121
+ def test_save_on_parent_saves_children
122
+ developer = Developer.create :name => "Bryan", :salary => 50_000
123
+ assert_equal 1, developer.reload.audit_logs.size
124
+ end
125
+
126
+ def test_failed_reload_returns_nil
127
+ p = setup_dangling_association
128
+ assert_nil p.author.reload
129
+ end
130
+
131
+ def test_failed_reset_returns_nil
132
+ p = setup_dangling_association
133
+ assert_nil p.author.reset
134
+ end
135
+
136
+ def test_reload_returns_assocition
137
+ david = developers(:david)
138
+ assert_nothing_raised do
139
+ assert_equal david.projects, david.projects.reload.reload
140
+ end
141
+ end
142
+
143
+ def setup_dangling_association
144
+ josh = Author.create(:name => "Josh")
145
+ p = Post.create(:title => "New on Edge", :body => "More cool stuff!", :author => josh)
146
+ josh.destroy
147
+ p
148
+ end
90
149
  end
91
150
 
92
- class HasOneAssociationsTest < Test::Unit::TestCase
151
+ class IBMDBHasOneAssociationsTest < Test::Unit::TestCase
93
152
  fixtures :accounts, :companies, :developers, :projects, :developers_projects
94
-
153
+
95
154
  def setup
96
155
  Account.destroyed_account_ids.clear
97
156
  end
98
-
157
+
99
158
  def test_has_one
100
159
  assert_equal companies(:first_firm).account, Account.find(1)
101
160
  assert_equal Account.find(1).credit_limit, companies(:first_firm).account.credit_limit
@@ -143,22 +202,22 @@ class HasOneAssociationsTest < Test::Unit::TestCase
143
202
  apple.account = citibank
144
203
  assert_equal apple.id, citibank.firm_id
145
204
  end
146
-
205
+
147
206
  def test_natural_assignment_to_nil
148
207
  old_account_id = companies(:first_firm).account.id
149
208
  companies(:first_firm).account = nil
150
209
  companies(:first_firm).save
151
210
  assert_nil companies(:first_firm).account
152
211
  # account is dependent, therefore is destroyed when reference to owner is lost
153
- assert_raises(ActiveRecord::RecordNotFound) { Account.find(old_account_id) }
212
+ assert_raises(ActiveRecord::RecordNotFound) { Account.find(old_account_id) }
154
213
  end
155
-
214
+
156
215
  def test_assignment_without_replacement
157
216
  apple = Firm.create("name" => "Apple")
158
217
  citibank = Account.create("credit_limit" => 10)
159
218
  apple.account = citibank
160
219
  assert_equal apple.id, citibank.firm_id
161
-
220
+
162
221
  hsbc = apple.build_account({ :credit_limit => 20}, false)
163
222
  assert_equal apple.id, hsbc.firm_id
164
223
  hsbc.save
@@ -175,7 +234,7 @@ class HasOneAssociationsTest < Test::Unit::TestCase
175
234
  citibank = Account.create("credit_limit" => 10)
176
235
  apple.account = citibank
177
236
  assert_equal apple.id, citibank.firm_id
178
-
237
+
179
238
  hsbc = apple.create_account({:credit_limit => 10}, false)
180
239
  assert_equal apple.id, hsbc.firm_id
181
240
  hsbc.save
@@ -195,12 +254,6 @@ class HasOneAssociationsTest < Test::Unit::TestCase
195
254
  assert_equal [account_id], Account.destroyed_account_ids[firm.id]
196
255
  end
197
256
 
198
- def test_deprecated_exclusive_dependence
199
- assert_deprecated(/:exclusively_dependent.*:dependent => :delete_all/) do
200
- Firm.has_many :deprecated_exclusively_dependent_clients, :class_name => 'Client', :exclusively_dependent => true
201
- end
202
- end
203
-
204
257
  def test_exclusive_dependence
205
258
  num_accounts = Account.count
206
259
 
@@ -248,9 +301,9 @@ class HasOneAssociationsTest < Test::Unit::TestCase
248
301
  end
249
302
 
250
303
  def test_create_association
251
- firm = Firm.new("name" => "GlobalMegaCorp")
252
- firm.save
253
- assert_equal firm.create_account("credit_limit" => 1000), firm.account
304
+ firm = Firm.create(:name => "GlobalMegaCorp")
305
+ account = firm.create_account(:credit_limit => 1000)
306
+ assert_equal account, firm.reload.account
254
307
  end
255
308
 
256
309
  def test_build
@@ -288,7 +341,7 @@ class HasOneAssociationsTest < Test::Unit::TestCase
288
341
  def test_failing_build_association
289
342
  firm = Firm.new("name" => "GlobalMegaCorp")
290
343
  firm.save
291
-
344
+
292
345
  firm.account = account = Account.new
293
346
  assert_equal account, firm.account
294
347
  assert !account.save
@@ -316,6 +369,13 @@ class HasOneAssociationsTest < Test::Unit::TestCase
316
369
  firm.destroy
317
370
  end
318
371
 
372
+ def test_dependence_with_missing_association_and_nullify
373
+ Account.destroy_all
374
+ firm = DependentFirm.find(:first)
375
+ assert firm.account.nil?
376
+ firm.destroy
377
+ end
378
+
319
379
  def test_assignment_before_parent_saved
320
380
  firm = Firm.new("name" => "GlobalMegaCorp")
321
381
  firm.account = a = Account.find(1)
@@ -372,29 +432,22 @@ class HasOneAssociationsTest < Test::Unit::TestCase
372
432
  firm.account = Account.find(:first).clone
373
433
  assert_queries(2) { firm.save! }
374
434
  end
375
-
435
+
376
436
  def test_save_still_works_after_accessing_nil_has_one
377
437
  jp = Company.new :name => 'Jaded Pixel'
378
438
  jp.dummy_account.nil?
379
-
439
+
380
440
  assert_nothing_raised do
381
441
  jp.save!
382
- end
383
- end
384
-
385
- def test_deprecated_inferred_foreign_key
386
- assert_not_deprecated { Company.belongs_to :firm }
387
- assert_not_deprecated { Company.belongs_to :client, :foreign_key => "firm_id" }
388
- assert_not_deprecated { Company.belongs_to :firm, :class_name => "Firm", :foreign_key => "client_of" }
389
- assert_deprecated("inferred foreign_key name") { Company.belongs_to :client, :class_name => "Firm" }
442
+ end
390
443
  end
391
444
 
392
445
  end
393
446
 
394
447
 
395
- class HasManyAssociationsTest < Test::Unit::TestCase
448
+ class IBMDBHasManyAssociationsTest < Test::Unit::TestCase
396
449
  fixtures :accounts, :companies, :developers, :projects,
397
- :developers_projects, :topics
450
+ :developers_projects, :topics, :authors, :comments
398
451
 
399
452
  def setup
400
453
  Client.destroyed_client_ids.clear
@@ -413,9 +466,7 @@ class HasManyAssociationsTest < Test::Unit::TestCase
413
466
  end
414
467
 
415
468
  def test_counting_with_single_conditions
416
- assert_deprecated 'count' do
417
- assert_equal 2, Firm.find(:first).plain_clients.count('1=1')
418
- end
469
+ assert_equal 2, Firm.find(:first).plain_clients.count(:conditions => '1=1')
419
470
  end
420
471
 
421
472
  def test_counting_with_single_hash
@@ -436,6 +487,36 @@ class HasManyAssociationsTest < Test::Unit::TestCase
436
487
  assert_equal 2, companies(:first_firm).limited_clients.find(:all, :limit => nil).size
437
488
  end
438
489
 
490
+ def test_dynamic_find_should_respect_association_order
491
+ assert_equal companies(:second_client), companies(:first_firm).clients_sorted_desc.find(:first, :conditions => "type = 'Client'")
492
+ assert_equal companies(:second_client), companies(:first_firm).clients_sorted_desc.find_by_type('Client')
493
+ end
494
+
495
+ def test_dynamic_find_order_should_override_association_order
496
+ assert_equal companies(:first_client), companies(:first_firm).clients_sorted_desc.find(:first, :conditions => "type = 'Client'", :order => 'id')
497
+ assert_equal companies(:first_client), companies(:first_firm).clients_sorted_desc.find_by_type('Client', :order => 'id')
498
+ end
499
+
500
+ def test_dynamic_find_all_should_respect_association_order
501
+ assert_equal [companies(:second_client), companies(:first_client)], companies(:first_firm).clients_sorted_desc.find(:all, :conditions => "type = 'Client'")
502
+ assert_equal [companies(:second_client), companies(:first_client)], companies(:first_firm).clients_sorted_desc.find_all_by_type('Client')
503
+ end
504
+
505
+ def test_dynamic_find_all_order_should_override_association_order
506
+ assert_equal [companies(:first_client), companies(:second_client)], companies(:first_firm).clients_sorted_desc.find(:all, :conditions => "type = 'Client'", :order => 'id')
507
+ assert_equal [companies(:first_client), companies(:second_client)], companies(:first_firm).clients_sorted_desc.find_all_by_type('Client', :order => 'id')
508
+ end
509
+
510
+ def test_dynamic_find_all_should_respect_association_limit
511
+ assert_equal 1, companies(:first_firm).limited_clients.find(:all, :conditions => "type = 'Client'").length
512
+ assert_equal 1, companies(:first_firm).limited_clients.find_all_by_type('Client').length
513
+ end
514
+
515
+ def test_dynamic_find_all_limit_should_override_association_limit
516
+ assert_equal 2, companies(:first_firm).limited_clients.find(:all, :conditions => "type = 'Client'", :limit => 9_000).length
517
+ assert_equal 2, companies(:first_firm).limited_clients.find_all_by_type('Client', :limit => 9_000).length
518
+ end
519
+
439
520
  def test_triple_equality
440
521
  assert !(Array === Firm.find(:first).clients)
441
522
  assert Firm.find(:first).clients === Array
@@ -472,13 +553,15 @@ class HasManyAssociationsTest < Test::Unit::TestCase
472
553
 
473
554
  def test_counting_using_sql
474
555
  assert_equal 1, Firm.find(:first).clients_using_counter_sql.size
556
+ assert Firm.find(:first).clients_using_counter_sql.any?
475
557
  assert_equal 0, Firm.find(:first).clients_using_zero_counter_sql.size
558
+ assert !Firm.find(:first).clients_using_zero_counter_sql.any?
476
559
  end
477
560
 
478
561
  def test_counting_non_existant_items_using_sql
479
562
  assert_equal 0, Firm.find(:first).no_clients_using_counter_sql.size
480
563
  end
481
-
564
+
482
565
  def test_belongs_to_sanity
483
566
  c = Client.new
484
567
  assert_nil c.firm
@@ -513,45 +596,47 @@ class HasManyAssociationsTest < Test::Unit::TestCase
513
596
  assert_raises(ActiveRecord::RecordNotFound) { firm.clients.find(2, 99) }
514
597
  end
515
598
 
599
+ def test_find_string_ids_when_using_finder_sql
600
+ firm = Firm.find(:first)
601
+
602
+ client = firm.clients_using_finder_sql.find("2")
603
+ assert_kind_of Client, client
604
+
605
+ client_ary = firm.clients_using_finder_sql.find(["2"])
606
+ assert_kind_of Array, client_ary
607
+ assert_equal client, client_ary.first
608
+
609
+ client_ary = firm.clients_using_finder_sql.find("2", "3")
610
+ assert_kind_of Array, client_ary
611
+ assert_equal 2, client_ary.size
612
+ assert client_ary.include?(client)
613
+ end
614
+
516
615
  def test_find_all
517
- assert_deprecated 'find_all' do
518
- firm = Firm.find_first
519
- assert_equal firm.clients, firm.clients.find_all
520
- assert_equal 2, firm.clients.find(:all, :conditions => "#{QUOTED_TYPE} = 'Client'").length
521
- assert_equal 1, firm.clients.find(:all, :conditions => "name = 'Summit'").length
522
- end
616
+ firm = Firm.find(:first)
617
+ assert_equal 2, firm.clients.find(:all, :conditions => "#{QUOTED_TYPE} = 'Client'").length
618
+ assert_equal 1, firm.clients.find(:all, :conditions => "name = 'Summit'").length
523
619
  end
524
620
 
525
621
  def test_find_all_sanitized
526
- assert_deprecated 'find_all' do
527
- firm = Firm.find_first
528
- assert_equal firm.clients.find_all("name = 'Summit'"), firm.clients.find_all(["name = '%s'", "Summit"])
529
- summit = firm.clients.find(:all, :conditions => "name = 'Summit'")
530
- assert_equal summit, firm.clients.find(:all, :conditions => ["name = ?", "Summit"])
531
- assert_equal summit, firm.clients.find(:all, :conditions => ["name = :name", { :name => "Summit" }])
532
- end
622
+ firm = Firm.find(:first)
623
+ summit = firm.clients.find(:all, :conditions => "name = 'Summit'")
624
+ assert_equal summit, firm.clients.find(:all, :conditions => ["name = ?", "Summit"])
625
+ assert_equal summit, firm.clients.find(:all, :conditions => ["name = :name", { :name => "Summit" }])
533
626
  end
534
627
 
535
628
  def test_find_first
536
- assert_deprecated 'find_first' do
537
- firm = Firm.find_first
538
- client2 = Client.find(2)
539
- assert_equal firm.clients.first, firm.clients.find_first
540
- assert_equal client2, firm.clients.find_first("#{QUOTED_TYPE} = 'Client'")
541
- assert_equal client2, firm.clients.find(:first, :conditions => "#{QUOTED_TYPE} = 'Client'")
542
- end
629
+ firm = Firm.find(:first)
630
+ client2 = Client.find(2)
631
+ assert_equal firm.clients.first, firm.clients.find(:first)
632
+ assert_equal client2, firm.clients.find(:first, :conditions => "#{QUOTED_TYPE} = 'Client'")
543
633
  end
544
634
 
545
635
  def test_find_first_sanitized
546
- assert_deprecated 'find_first' do
547
- firm = Firm.find_first
548
- client2 = Client.find(2)
549
- assert_deprecated(/find_first/) do
550
- assert_equal client2, firm.clients.find_first(["#{QUOTED_TYPE} = ?", "Client"])
551
- end
552
- assert_equal client2, firm.clients.find(:first, :conditions => ["#{QUOTED_TYPE} = ?", 'Client'])
553
- assert_equal client2, firm.clients.find(:first, :conditions => ["#{QUOTED_TYPE} = :type", { :type => 'Client' }])
554
- end
636
+ firm = Firm.find(:first)
637
+ client2 = Client.find(2)
638
+ assert_equal client2, firm.clients.find(:first, :conditions => ["#{QUOTED_TYPE} = ?", 'Client'])
639
+ assert_equal client2, firm.clients.find(:first, :conditions => ["#{QUOTED_TYPE} = :type", { :type => 'Client' }])
555
640
  end
556
641
 
557
642
  def test_find_in_collection
@@ -583,12 +668,39 @@ class HasManyAssociationsTest < Test::Unit::TestCase
583
668
  assert_equal 3, first_firm.plain_clients.size
584
669
  end
585
670
 
671
+ def test_create_with_bang_on_has_many_when_parent_is_new_raises
672
+ assert_raises(ActiveRecord::RecordNotSaved) do
673
+ firm = Firm.new
674
+ firm.plain_clients.create! :name=>"Whoever"
675
+ end
676
+ end
677
+
678
+ def test_regular_create_on_has_many_when_parent_is_new_raises
679
+ assert_raises(ActiveRecord::RecordNotSaved) do
680
+ firm = Firm.new
681
+ firm.plain_clients.create :name=>"Whoever"
682
+ end
683
+ end
684
+
685
+ def test_create_with_bang_on_has_many_raises_when_record_not_saved
686
+ assert_raises(ActiveRecord::RecordInvalid) do
687
+ firm = Firm.find(:first)
688
+ firm.plain_clients.create!
689
+ end
690
+ end
691
+
692
+ def test_create_with_bang_on_habtm_when_parent_is_new_raises
693
+ assert_raises(ActiveRecord::RecordNotSaved) do
694
+ Developer.new("name" => "Aredridel").projects.create!
695
+ end
696
+ end
697
+
586
698
  def test_adding_a_mismatch_class
587
699
  assert_raises(ActiveRecord::AssociationTypeMismatch) { companies(:first_firm).clients_of_firm << nil }
588
700
  assert_raises(ActiveRecord::AssociationTypeMismatch) { companies(:first_firm).clients_of_firm << 1 }
589
701
  assert_raises(ActiveRecord::AssociationTypeMismatch) { companies(:first_firm).clients_of_firm << Topic.find(1) }
590
702
  end
591
-
703
+
592
704
  def test_adding_a_collection
593
705
  force_signal37_to_load_all_clients_of_firm
594
706
  companies(:first_firm).clients_of_firm.concat([Client.new("name" => "Natural Company"), Client.new("name" => "Apple")])
@@ -599,12 +711,15 @@ class HasManyAssociationsTest < Test::Unit::TestCase
599
711
  def test_adding_before_save
600
712
  no_of_firms = Firm.count
601
713
  no_of_clients = Client.count
714
+
602
715
  new_firm = Firm.new("name" => "A New Firm, Inc")
716
+ c = Client.new("name" => "Apple")
717
+
603
718
  new_firm.clients_of_firm.push Client.new("name" => "Natural Company")
604
- new_firm.clients_of_firm << (c = Client.new("name" => "Apple"))
605
- assert new_firm.new_record?
606
- assert c.new_record?
719
+ assert_equal 1, new_firm.clients_of_firm.size
720
+ new_firm.clients_of_firm << c
607
721
  assert_equal 2, new_firm.clients_of_firm.size
722
+
608
723
  assert_equal no_of_firms, Firm.count # Firm was not saved to database.
609
724
  assert_equal no_of_clients, Client.count # Clients were not saved to database.
610
725
  assert new_firm.save
@@ -613,6 +728,7 @@ class HasManyAssociationsTest < Test::Unit::TestCase
613
728
  assert_equal new_firm, c.firm
614
729
  assert_equal no_of_firms+1, Firm.count # Firm was saved to database.
615
730
  assert_equal no_of_clients+2, Client.count # Clients were saved to database.
731
+
616
732
  assert_equal 2, new_firm.clients_of_firm.size
617
733
  assert_equal 2, new_firm.clients_of_firm(true).size
618
734
  end
@@ -662,7 +778,7 @@ class HasManyAssociationsTest < Test::Unit::TestCase
662
778
  Reply.column_names
663
779
 
664
780
  assert_equal 1, first_topic.replies.length
665
-
781
+
666
782
  assert_no_queries do
667
783
  first_topic.replies.build(:title => "Not saved", :content => "Superstars")
668
784
  assert_equal 2, first_topic.replies.size
@@ -678,11 +794,11 @@ class HasManyAssociationsTest < Test::Unit::TestCase
678
794
 
679
795
  assert_equal 1, first_firm.clients_of_firm.size
680
796
  first_firm.clients_of_firm.reset
681
-
797
+
682
798
  assert_queries(1) do
683
799
  first_firm.clients_of_firm.create(:name => "Superstars")
684
800
  end
685
-
801
+
686
802
  assert_equal 2, first_firm.clients_of_firm.size
687
803
  end
688
804
 
@@ -695,7 +811,7 @@ class HasManyAssociationsTest < Test::Unit::TestCase
695
811
  assert new_client.new_record?
696
812
  assert_equal 1, companies(:first_firm).clients_of_firm(true).size
697
813
  end
698
-
814
+
699
815
  def test_create
700
816
  force_signal37_to_load_all_clients_of_firm
701
817
  new_client = companies(:first_firm).clients_of_firm.create("name" => "Another Client")
@@ -703,18 +819,25 @@ class HasManyAssociationsTest < Test::Unit::TestCase
703
819
  assert_equal new_client, companies(:first_firm).clients_of_firm.last
704
820
  assert_equal new_client, companies(:first_firm).clients_of_firm(true).last
705
821
  end
706
-
822
+
707
823
  def test_create_many
708
824
  companies(:first_firm).clients_of_firm.create([{"name" => "Another Client"}, {"name" => "Another Client II"}])
709
825
  assert_equal 3, companies(:first_firm).clients_of_firm(true).size
710
826
  end
711
827
 
828
+ def test_find_or_initialize
829
+ the_client = companies(:first_firm).clients.find_or_initialize_by_name("Yet another client")
830
+ assert_equal companies(:first_firm).id, the_client.firm_id
831
+ assert_equal "Yet another client", the_client.name
832
+ assert the_client.new_record?
833
+ end
834
+
712
835
  def test_find_or_create
713
836
  number_of_clients = companies(:first_firm).clients.size
714
837
  the_client = companies(:first_firm).clients.find_or_create_by_name("Yet another client")
715
- assert_equal number_of_clients + 1, companies(:first_firm, :refresh).clients.size
838
+ assert_equal number_of_clients + 1, companies(:first_firm, :reload).clients.size
716
839
  assert_equal the_client, companies(:first_firm).clients.find_or_create_by_name("Yet another client")
717
- assert_equal number_of_clients + 1, companies(:first_firm, :refresh).clients.size
840
+ assert_equal number_of_clients + 1, companies(:first_firm, :reload).clients.size
718
841
  end
719
842
 
720
843
  def test_deleting
@@ -740,7 +863,7 @@ class HasManyAssociationsTest < Test::Unit::TestCase
740
863
  assert_equal 0, companies(:first_firm).clients_of_firm.size
741
864
  assert_equal 0, companies(:first_firm).clients_of_firm(true).size
742
865
  end
743
-
866
+
744
867
  def test_delete_all
745
868
  force_signal37_to_load_all_clients_of_firm
746
869
  companies(:first_firm).clients_of_firm.create("name" => "Another Client")
@@ -806,11 +929,36 @@ class HasManyAssociationsTest < Test::Unit::TestCase
806
929
 
807
930
  assert_equal 0, firm.exclusively_dependent_clients_of_firm.size
808
931
  assert_equal 0, firm.exclusively_dependent_clients_of_firm(true).size
809
- assert_equal [3], Client.destroyed_client_ids[firm.id]
932
+ # no destroy-filters should have been called
933
+ assert_equal [], Client.destroyed_client_ids[firm.id]
810
934
 
811
935
  # Should be destroyed since the association is exclusively dependent.
812
936
  assert Client.find_by_id(client_id).nil?
813
- end
937
+ end
938
+
939
+ def test_dependent_association_respects_optional_conditions_on_delete
940
+ firm = companies(:odegy)
941
+ Client.create(:client_of => firm.id, :name => "BigShot Inc.")
942
+ Client.create(:client_of => firm.id, :name => "SmallTime Inc.")
943
+ # only one of two clients is included in the association due to the :conditions key
944
+ assert_equal 2, Client.find_all_by_client_of(firm.id).size
945
+ assert_equal 1, firm.dependent_conditional_clients_of_firm.size
946
+ firm.destroy
947
+ # only the correctly associated client should have been deleted
948
+ assert_equal 1, Client.find_all_by_client_of(firm.id).size
949
+ end
950
+
951
+ def test_dependent_association_respects_optional_sanitized_conditions_on_delete
952
+ firm = companies(:odegy)
953
+ Client.create(:client_of => firm.id, :name => "BigShot Inc.")
954
+ Client.create(:client_of => firm.id, :name => "SmallTime Inc.")
955
+ # only one of two clients is included in the association due to the :conditions key
956
+ assert_equal 2, Client.find_all_by_client_of(firm.id).size
957
+ assert_equal 1, firm.dependent_sanitized_conditional_clients_of_firm.size
958
+ firm.destroy
959
+ # only the correctly associated client should have been deleted
960
+ assert_equal 1, Client.find_all_by_client_of(firm.id).size
961
+ end
814
962
 
815
963
  def test_clearing_without_initial_access
816
964
  firm = companies(:first_firm)
@@ -873,7 +1021,7 @@ class HasManyAssociationsTest < Test::Unit::TestCase
873
1021
  topic = Topic.create "title" => "neat and simple"
874
1022
  reply = topic.replies.create "title" => "neat and simple", "content" => "still digging it"
875
1023
  silly_reply = reply.replies.create "title" => "neat and simple", "content" => "ain't complaining"
876
-
1024
+
877
1025
  assert_nothing_raised { topic.destroy }
878
1026
  end
879
1027
 
@@ -898,16 +1046,16 @@ class HasManyAssociationsTest < Test::Unit::TestCase
898
1046
  def test_depends_and_nullify
899
1047
  num_accounts = Account.count
900
1048
  num_companies = Company.count
901
-
1049
+
902
1050
  core = companies(:rails_core)
903
1051
  assert_equal accounts(:rails_core_account), core.account
904
- assert_equal [companies(:leetsoft), companies(:jadedpixel)], core.companies
905
- core.destroy
1052
+ assert_equal companies(:leetsoft, :jadedpixel), core.companies
1053
+ core.destroy
906
1054
  assert_nil accounts(:rails_core_account).reload.firm_id
907
1055
  assert_nil companies(:leetsoft).reload.client_of
908
1056
  assert_nil companies(:jadedpixel).reload.client_of
909
-
910
-
1057
+
1058
+
911
1059
  assert_equal num_accounts, Account.count
912
1060
  end
913
1061
 
@@ -930,19 +1078,23 @@ class HasManyAssociationsTest < Test::Unit::TestCase
930
1078
  assert firm.save, "Could not save firm"
931
1079
  firm.reload
932
1080
  assert_equal 1, firm.clients.length
933
- end
934
-
935
-
1081
+ end
1082
+
1083
+ def test_replace_with_less_and_dependent_nullify
1084
+ num_companies = Company.count
1085
+ companies(:rails_core).companies = []
1086
+ assert_equal num_companies, Company.count
1087
+ end
1088
+
936
1089
  def test_replace_with_new
937
1090
  firm = Firm.find(:first)
938
- new_client = Client.new("name" => "New Client")
939
- firm.clients = [companies(:second_client),new_client]
1091
+ firm.clients = [companies(:second_client), Client.new("name" => "New Client")]
940
1092
  firm.save
941
1093
  firm.reload
942
1094
  assert_equal 2, firm.clients.length
943
1095
  assert !firm.clients.include?(:first_client)
944
1096
  end
945
-
1097
+
946
1098
  def test_replace_on_new_object
947
1099
  firm = Firm.new("name" => "New Firm")
948
1100
  firm.clients = [companies(:second_client), Client.new("name" => "New Client")]
@@ -951,11 +1103,11 @@ class HasManyAssociationsTest < Test::Unit::TestCase
951
1103
  assert_equal 2, firm.clients.length
952
1104
  assert firm.clients.include?(Client.find_by_name("New Client"))
953
1105
  end
954
-
1106
+
955
1107
  def test_get_ids
956
1108
  assert_equal [companies(:first_client).id, companies(:second_client).id], companies(:first_firm).client_ids
957
1109
  end
958
-
1110
+
959
1111
  def test_assign_ids
960
1112
  firm = Firm.new("name" => "Apple")
961
1113
  firm.client_ids = [companies(:first_client).id, companies(:second_client).id]
@@ -966,24 +1118,62 @@ class HasManyAssociationsTest < Test::Unit::TestCase
966
1118
  end
967
1119
 
968
1120
  def test_assign_ids_ignoring_blanks
969
- firm = Firm.new("name" => "Apple")
1121
+ firm = Firm.create!(:name => 'Apple')
970
1122
  firm.client_ids = [companies(:first_client).id, nil, companies(:second_client).id, '']
971
- firm.save
972
- firm.reload
973
- assert_equal 2, firm.clients.length
1123
+ firm.save!
1124
+
1125
+ assert_equal 2, firm.clients(true).size
974
1126
  assert firm.clients.include?(companies(:second_client))
975
1127
  end
976
1128
 
1129
+ def test_get_ids_for_through
1130
+ assert_equal [comments(:eager_other_comment1).id], authors(:mary).comment_ids
1131
+ end
1132
+
1133
+ def test_assign_ids_for_through
1134
+ assert_raise(NoMethodError) { authors(:mary).comment_ids = [123] }
1135
+ end
1136
+
1137
+ def test_dynamic_find_should_respect_association_order_for_through
1138
+ assert_equal Comment.find(10), authors(:david).comments_desc.find(:first, :conditions => "comments.type = 'SpecialComment'")
1139
+ assert_equal Comment.find(10), authors(:david).comments_desc.find_by_type('SpecialComment')
1140
+ end
1141
+
1142
+ def test_dynamic_find_order_should_override_association_order_for_through
1143
+ assert_equal Comment.find(3), authors(:david).comments_desc.find(:first, :conditions => "comments.type = 'SpecialComment'", :order => 'comments.id')
1144
+ assert_equal Comment.find(3), authors(:david).comments_desc.find_by_type('SpecialComment', :order => 'comments.id')
1145
+ end
1146
+
1147
+ def test_dynamic_find_all_should_respect_association_order_for_through
1148
+ assert_equal [Comment.find(10), Comment.find(7), Comment.find(6), Comment.find(3)], authors(:david).comments_desc.find(:all, :conditions => "comments.type = 'SpecialComment'")
1149
+ assert_equal [Comment.find(10), Comment.find(7), Comment.find(6), Comment.find(3)], authors(:david).comments_desc.find_all_by_type('SpecialComment')
1150
+ end
1151
+
1152
+ def test_dynamic_find_all_order_should_override_association_order_for_through
1153
+ assert_equal [Comment.find(3), Comment.find(6), Comment.find(7), Comment.find(10)], authors(:david).comments_desc.find(:all, :conditions => "comments.type = 'SpecialComment'", :order => 'comments.id')
1154
+ assert_equal [Comment.find(3), Comment.find(6), Comment.find(7), Comment.find(10)], authors(:david).comments_desc.find_all_by_type('SpecialComment', :order => 'comments.id')
1155
+ end
1156
+
1157
+ def test_dynamic_find_all_should_respect_association_limit_for_through
1158
+ assert_equal 1, authors(:david).limited_comments.find(:all, :conditions => "comments.type = 'SpecialComment'").length
1159
+ assert_equal 1, authors(:david).limited_comments.find_all_by_type('SpecialComment').length
1160
+ end
1161
+
1162
+ def test_dynamic_find_all_order_should_override_association_limit_for_through
1163
+ assert_equal 4, authors(:david).limited_comments.find(:all, :conditions => "comments.type = 'SpecialComment'", :limit => 9_000).length
1164
+ assert_equal 4, authors(:david).limited_comments.find_all_by_type('SpecialComment', :limit => 9_000).length
1165
+ end
1166
+
977
1167
  end
978
1168
 
979
- class BelongsToAssociationsTest < Test::Unit::TestCase
1169
+ class IBMDBBelongsToAssociationsTest < Test::Unit::TestCase
980
1170
  fixtures :accounts, :companies, :developers, :projects, :topics,
981
- :developers_projects, :computers, :authors, :posts
982
-
1171
+ :developers_projects, :computers, :authors, :posts, :tags, :taggings
1172
+
983
1173
  def test_belongs_to
984
1174
  Client.find(3).firm.name
985
1175
  assert_equal companies(:first_firm).name, Client.find(3).firm.name
986
- assert !Client.find(3).firm.nil?, "Microsoft should have a firm"
1176
+ assert !Client.find(3).firm.nil?, "Microsoft should have a firm"
987
1177
  end
988
1178
 
989
1179
  def test_proxy_assignment
@@ -1007,7 +1197,20 @@ class BelongsToAssociationsTest < Test::Unit::TestCase
1007
1197
  citibank.firm = apple
1008
1198
  assert_equal apple.id, citibank.firm_id
1009
1199
  end
1010
-
1200
+
1201
+ def test_no_unexpected_aliasing
1202
+ first_firm = companies(:first_firm)
1203
+ another_firm = companies(:another_firm)
1204
+
1205
+ citibank = Account.create("credit_limit" => 10)
1206
+ citibank.firm = first_firm
1207
+ original_proxy = citibank.firm
1208
+ citibank.firm = another_firm
1209
+
1210
+ assert_equal first_firm.object_id, original_proxy.object_id
1211
+ assert_equal another_firm.object_id, citibank.firm.object_id
1212
+ end
1213
+
1011
1214
  def test_creating_the_belonging_object
1012
1215
  citibank = Account.create("credit_limit" => 10)
1013
1216
  apple = citibank.create_firm("name" => "Apple")
@@ -1023,7 +1226,7 @@ class BelongsToAssociationsTest < Test::Unit::TestCase
1023
1226
  citibank.save
1024
1227
  assert_equal apple.id, citibank.firm_id
1025
1228
  end
1026
-
1229
+
1027
1230
  def test_natural_assignment_to_nil
1028
1231
  client = Client.find(3)
1029
1232
  client.firm = nil
@@ -1031,7 +1234,7 @@ class BelongsToAssociationsTest < Test::Unit::TestCase
1031
1234
  assert_nil client.firm(true)
1032
1235
  assert_nil client.client_of
1033
1236
  end
1034
-
1237
+
1035
1238
  def test_with_different_class_name
1036
1239
  assert_equal Company.find(1).name, Company.find(3).firm_with_other_name.name
1037
1240
  assert_not_nil Company.find(3).firm_with_other_name, "Microsoft should have a firm"
@@ -1041,7 +1244,7 @@ class BelongsToAssociationsTest < Test::Unit::TestCase
1041
1244
  assert_equal Company.find(1).name, Company.find(3).firm_with_condition.name
1042
1245
  assert_not_nil Company.find(3).firm_with_condition, "Microsoft should have a firm"
1043
1246
  end
1044
-
1247
+
1045
1248
  def test_belongs_to_counter
1046
1249
  debate = Topic.create("title" => "debate")
1047
1250
  assert_equal 0, debate.send(:read_attribute, "replies_count"), "No replies yet"
@@ -1085,6 +1288,42 @@ class BelongsToAssociationsTest < Test::Unit::TestCase
1085
1288
  assert_equal 0, Topic.find(t2.id).replies.size
1086
1289
  end
1087
1290
 
1291
+ def test_belongs_to_counter_after_save
1292
+ topic = Topic.create!(:title => "monday night")
1293
+ topic.replies.create!(:title => "re: monday night", :content => "football")
1294
+ assert_equal 1, Topic.find(topic.id)[:replies_count]
1295
+
1296
+ topic.save!
1297
+ assert_equal 1, Topic.find(topic.id)[:replies_count]
1298
+ end
1299
+
1300
+ def test_belongs_to_counter_after_update_attributes
1301
+ topic = Topic.create!(:title => "37s")
1302
+ topic.replies.create!(:title => "re: 37s", :content => "rails")
1303
+ assert_equal 1, Topic.find(topic.id)[:replies_count]
1304
+
1305
+ topic.update_attributes(:title => "37signals")
1306
+ assert_equal 1, Topic.find(topic.id)[:replies_count]
1307
+ end
1308
+
1309
+ def test_belongs_to_counter_after_save
1310
+ topic = Topic.create("title" => "monday night")
1311
+ topic.replies.create("title" => "re: monday night", "content" => "football")
1312
+ assert_equal 1, Topic.find(topic.id).send(:read_attribute, "replies_count")
1313
+
1314
+ topic.save
1315
+ assert_equal 1, Topic.find(topic.id).send(:read_attribute, "replies_count")
1316
+ end
1317
+
1318
+ def test_belongs_to_counter_after_update_attributes
1319
+ topic = Topic.create("title" => "37s")
1320
+ topic.replies.create("title" => "re: 37s", "content" => "rails")
1321
+ assert_equal 1, Topic.find(topic.id).send(:read_attribute, "replies_count")
1322
+
1323
+ topic.update_attributes("title" => "37signals")
1324
+ assert_equal 1, Topic.find(topic.id).send(:read_attribute, "replies_count")
1325
+ end
1326
+
1088
1327
  def test_assignment_before_parent_saved
1089
1328
  client = Client.find(:first)
1090
1329
  apple = Firm.new("name" => "Apple")
@@ -1144,7 +1383,7 @@ class BelongsToAssociationsTest < Test::Unit::TestCase
1144
1383
  def test_counter_cache
1145
1384
  topic = Topic.create :title => "Zoom-zoom-zoom"
1146
1385
  assert_equal 0, topic[:replies_count]
1147
-
1386
+
1148
1387
  reply = Reply.create(:title => "re: zoom", :content => "speedy quick!")
1149
1388
  reply.topic = topic
1150
1389
 
@@ -1172,10 +1411,10 @@ class BelongsToAssociationsTest < Test::Unit::TestCase
1172
1411
  def test_store_two_association_with_one_save
1173
1412
  num_orders = Order.count
1174
1413
  num_customers = Customer.count
1175
- order = Order.new
1414
+ order = Order.new
1176
1415
 
1177
1416
  customer1 = order.billing = Customer.new
1178
- customer2 = order.shipping = Customer.new
1417
+ customer2 = order.shipping = Customer.new
1179
1418
  assert order.save
1180
1419
  assert_equal customer1, order.billing
1181
1420
  assert_equal customer2, order.shipping
@@ -1183,28 +1422,28 @@ class BelongsToAssociationsTest < Test::Unit::TestCase
1183
1422
  order.reload
1184
1423
 
1185
1424
  assert_equal customer1, order.billing
1186
- assert_equal customer2, order.shipping
1425
+ assert_equal customer2, order.shipping
1187
1426
 
1188
1427
  assert_equal num_orders +1, Order.count
1189
1428
  assert_equal num_customers +2, Customer.count
1190
1429
  end
1191
1430
 
1192
-
1431
+
1193
1432
  def test_store_association_in_two_relations_with_one_save
1194
1433
  num_orders = Order.count
1195
1434
  num_customers = Customer.count
1196
- order = Order.new
1197
-
1198
- customer = order.billing = order.shipping = Customer.new
1435
+ order = Order.new
1436
+
1437
+ customer = order.billing = order.shipping = Customer.new
1199
1438
  assert order.save
1200
1439
  assert_equal customer, order.billing
1201
1440
  assert_equal customer, order.shipping
1202
-
1441
+
1203
1442
  order.reload
1204
-
1443
+
1205
1444
  assert_equal customer, order.billing
1206
- assert_equal customer, order.shipping
1207
-
1445
+ assert_equal customer, order.shipping
1446
+
1208
1447
  assert_equal num_orders +1, Order.count
1209
1448
  assert_equal num_customers +1, Customer.count
1210
1449
  end
@@ -1213,46 +1452,46 @@ class BelongsToAssociationsTest < Test::Unit::TestCase
1213
1452
  num_orders = Order.count
1214
1453
  num_customers = Customer.count
1215
1454
  order = Order.create
1216
-
1217
- customer = order.billing = order.shipping = Customer.new
1455
+
1456
+ customer = order.billing = order.shipping = Customer.new
1218
1457
  assert order.save
1219
1458
  assert_equal customer, order.billing
1220
1459
  assert_equal customer, order.shipping
1221
-
1460
+
1222
1461
  order.reload
1223
-
1462
+
1224
1463
  assert_equal customer, order.billing
1225
- assert_equal customer, order.shipping
1226
-
1464
+ assert_equal customer, order.shipping
1465
+
1227
1466
  assert_equal num_orders +1, Order.count
1228
1467
  assert_equal num_customers +1, Customer.count
1229
1468
  end
1230
-
1469
+
1231
1470
  def test_store_association_in_two_relations_with_one_save_in_existing_object_with_values
1232
1471
  num_orders = Order.count
1233
1472
  num_customers = Customer.count
1234
1473
  order = Order.create
1235
-
1236
- customer = order.billing = order.shipping = Customer.new
1474
+
1475
+ customer = order.billing = order.shipping = Customer.new
1237
1476
  assert order.save
1238
1477
  assert_equal customer, order.billing
1239
1478
  assert_equal customer, order.shipping
1240
-
1479
+
1241
1480
  order.reload
1242
-
1243
- customer = order.billing = order.shipping = Customer.new
1244
-
1481
+
1482
+ customer = order.billing = order.shipping = Customer.new
1483
+
1245
1484
  assert order.save
1246
- order.reload
1247
-
1485
+ order.reload
1486
+
1248
1487
  assert_equal customer, order.billing
1249
- assert_equal customer, order.shipping
1250
-
1488
+ assert_equal customer, order.shipping
1489
+
1251
1490
  assert_equal num_orders +1, Order.count
1252
1491
  assert_equal num_customers +2, Customer.count
1253
1492
  end
1254
-
1255
-
1493
+
1494
+
1256
1495
  def test_association_assignment_sticks
1257
1496
  post = Post.find(:first)
1258
1497
 
@@ -1273,7 +1512,7 @@ class BelongsToAssociationsTest < Test::Unit::TestCase
1273
1512
  # the author id of the post should be the id we set
1274
1513
  assert_equal post.author_id, author2.id
1275
1514
  end
1276
-
1515
+
1277
1516
  end
1278
1517
 
1279
1518
 
@@ -1303,9 +1542,9 @@ class DeveloperForProjectWithAfterCreateHook < ActiveRecord::Base
1303
1542
  end
1304
1543
 
1305
1544
 
1306
- class HasAndBelongsToManyAssociationsTest < Test::Unit::TestCase
1545
+ class IBMDBHasAndBelongsToManyAssociationsTest < Test::Unit::TestCase
1307
1546
  fixtures :accounts, :companies, :categories, :posts, :categories_posts, :developers, :projects, :developers_projects
1308
-
1547
+
1309
1548
  def test_has_and_belongs_to_many
1310
1549
  david = Developer.find(1)
1311
1550
 
@@ -1325,11 +1564,11 @@ class HasAndBelongsToManyAssociationsTest < Test::Unit::TestCase
1325
1564
 
1326
1565
  def test_adding_single
1327
1566
  jamis = Developer.find(2)
1328
- jamis.projects.reload # causing the collection to load
1567
+ jamis.projects.reload # causing the collection to load
1329
1568
  action_controller = Project.find(2)
1330
1569
  assert_equal 1, jamis.projects.size
1331
- assert_equal 1, action_controller.developers.size
1332
-
1570
+ assert_equal 1, action_controller.developers.size
1571
+
1333
1572
  jamis.projects << action_controller
1334
1573
 
1335
1574
  assert_equal 2, jamis.projects.size
@@ -1350,8 +1589,8 @@ class HasAndBelongsToManyAssociationsTest < Test::Unit::TestCase
1350
1589
  assert_equal 1, jamis.projects.size
1351
1590
  assert_equal 1, action_controller.developers.size
1352
1591
 
1353
- action_controller.developers << jamis
1354
-
1592
+ action_controller.developers << jamis
1593
+
1355
1594
  assert_equal 2, jamis.projects(true).size
1356
1595
  assert_equal 2, action_controller.developers.size
1357
1596
  assert_equal 2, action_controller.developers(true).size
@@ -1401,19 +1640,7 @@ class HasAndBelongsToManyAssociationsTest < Test::Unit::TestCase
1401
1640
  assert_equal 1, project.access_level.to_i
1402
1641
  end
1403
1642
 
1404
- def test_adding_uses_explicit_values_on_join_table
1405
- ac = projects(:action_controller)
1406
- assert !developers(:jamis).projects.include?(ac)
1407
- assert_deprecated do
1408
- developers(:jamis).projects.push_with_attributes(ac, :access_level => 3)
1409
- end
1410
-
1411
- assert developers(:jamis, :reload).projects.include?(ac)
1412
- project = developers(:jamis).projects.detect { |p| p == ac }
1413
- assert_equal 3, project.access_level.to_i
1414
- end
1415
-
1416
- def test_hatbm_attribute_access_and_respond_to
1643
+ def test_habtm_attribute_access_and_respond_to
1417
1644
  project = developers(:jamis).projects[0]
1418
1645
  assert project.has_attribute?("name")
1419
1646
  assert project.has_attribute?("joined_on")
@@ -1422,10 +1649,12 @@ class HasAndBelongsToManyAssociationsTest < Test::Unit::TestCase
1422
1649
  assert project.respond_to?("name=")
1423
1650
  assert project.respond_to?("name?")
1424
1651
  assert project.respond_to?("joined_on")
1425
- assert project.respond_to?("joined_on=")
1652
+ # given that the 'join attribute' won't be persisted, I don't
1653
+ # think we should define the mutators
1654
+ #assert project.respond_to?("joined_on=")
1426
1655
  assert project.respond_to?("joined_on?")
1427
1656
  assert project.respond_to?("access_level")
1428
- assert project.respond_to?("access_level=")
1657
+ #assert project.respond_to?("access_level=")
1429
1658
  assert project.respond_to?("access_level?")
1430
1659
  end
1431
1660
 
@@ -1444,31 +1673,6 @@ class HasAndBelongsToManyAssociationsTest < Test::Unit::TestCase
1444
1673
  assert_equal 2, aredridel.projects(true).size
1445
1674
  end
1446
1675
 
1447
- def test_habtm_adding_before_save_with_join_attributes
1448
- no_of_devels = Developer.count
1449
- no_of_projects = Project.count
1450
- now = Date.today
1451
- ken = Developer.new("name" => "Ken")
1452
- assert_deprecated do
1453
- ken.projects.push_with_attributes( Project.find(1), :joined_on => now )
1454
- end
1455
- p = Project.new("name" => "Foomatic")
1456
- assert_deprecated do
1457
- ken.projects.push_with_attributes( p, :joined_on => now )
1458
- end
1459
- assert ken.new_record?
1460
- assert p.new_record?
1461
- assert ken.save
1462
- assert !ken.new_record?
1463
- assert_equal no_of_devels+1, Developer.count
1464
- assert_equal no_of_projects+1, Project.count
1465
- assert_equal 2, ken.projects.size
1466
- assert_equal 2, ken.projects(true).size
1467
-
1468
- kenReloaded = Developer.find_by_name 'Ken'
1469
- kenReloaded.projects.each {|prj| assert_date_from_db(now, prj.joined_on)}
1470
- end
1471
-
1472
1676
  def test_habtm_saving_multiple_relationships
1473
1677
  new_project = Project.new("name" => "Grimetime")
1474
1678
  amount_of_developers = 4
@@ -1484,8 +1688,8 @@ class HasAndBelongsToManyAssociationsTest < Test::Unit::TestCase
1484
1688
  end
1485
1689
 
1486
1690
  def test_habtm_unique_order_preserved
1487
- assert_equal [developers(:poor_jamis), developers(:jamis), developers(:david)], projects(:active_record).non_unique_developers
1488
- assert_equal [developers(:poor_jamis), developers(:jamis), developers(:david)], projects(:active_record).developers
1691
+ assert_equal developers(:poor_jamis, :jamis, :david), projects(:active_record).non_unique_developers
1692
+ assert_equal developers(:poor_jamis, :jamis, :david), projects(:active_record).developers
1489
1693
  end
1490
1694
 
1491
1695
  def test_build
@@ -1498,7 +1702,7 @@ class HasAndBelongsToManyAssociationsTest < Test::Unit::TestCase
1498
1702
  assert_equal devel.projects.last, proj
1499
1703
  assert_equal Developer.find(1).projects.sort_by(&:id).last, proj # prove join table is updated
1500
1704
  end
1501
-
1705
+
1502
1706
  def test_build_by_new_record
1503
1707
  devel = Developer.new(:name => "Marcel", :salary => 75000)
1504
1708
  proj1 = devel.projects.build(:name => "Make bed")
@@ -1511,7 +1715,7 @@ class HasAndBelongsToManyAssociationsTest < Test::Unit::TestCase
1511
1715
  assert_equal devel.projects.last, proj2
1512
1716
  assert_equal Developer.find_by_name("Marcel").projects.last, proj2 # prove join table is updated
1513
1717
  end
1514
-
1718
+
1515
1719
  def test_create
1516
1720
  devel = Developer.find(1)
1517
1721
  proj = devel.projects.create("name" => "Projekt")
@@ -1519,18 +1723,20 @@ class HasAndBelongsToManyAssociationsTest < Test::Unit::TestCase
1519
1723
  assert !proj.new_record?
1520
1724
  assert_equal Developer.find(1).projects.sort_by(&:id).last, proj # prove join table is updated
1521
1725
  end
1522
-
1523
- def test_create_by_new_record
1524
- devel = Developer.new(:name => "Marcel", :salary => 75000)
1525
- proj1 = devel.projects.create(:name => "Make bed")
1526
- proj2 = devel.projects.create(:name => "Lie in it")
1527
- assert_equal devel.projects.last, proj2
1528
- assert proj2.new_record?
1529
- devel.save
1530
- assert !devel.new_record?
1531
- assert !proj2.new_record?
1532
- assert_equal devel.projects.last, proj2
1533
- assert_equal Developer.find_by_name("Marcel").projects.last, proj2 # prove join table is updated
1726
+
1727
+ unless current_adapter?(:IBM_DBAdapter)#same as test case test_build_by_new_record
1728
+ def test_create_by_new_record
1729
+ devel = Developer.new(:name => "Marcel", :salary => 75000)
1730
+ proj1 = devel.projects.build(:name => "Make bed")
1731
+ proj2 = devel.projects.build(:name => "Lie in it")
1732
+ assert_equal devel.projects.last, proj2
1733
+ assert proj2.new_record?
1734
+ devel.save
1735
+ assert !devel.new_record?
1736
+ assert !proj2.new_record?
1737
+ assert_equal devel.projects.last, proj2
1738
+ assert_equal Developer.find_by_name("Marcel").projects.last, proj2 # prove join table is updated
1739
+ end
1534
1740
  end
1535
1741
 
1536
1742
  def test_uniq_after_the_fact
@@ -1545,7 +1751,7 @@ class HasAndBelongsToManyAssociationsTest < Test::Unit::TestCase
1545
1751
  projects(:active_record).developers << developers(:david)
1546
1752
  assert_equal 3, projects(:active_record, :reload).developers.size
1547
1753
  end
1548
-
1754
+
1549
1755
  def test_deleting
1550
1756
  david = Developer.find(1)
1551
1757
  active_record = Project.find(1)
@@ -1554,7 +1760,7 @@ class HasAndBelongsToManyAssociationsTest < Test::Unit::TestCase
1554
1760
  assert_equal 3, active_record.developers.size
1555
1761
 
1556
1762
  david.projects.delete(active_record)
1557
-
1763
+
1558
1764
  assert_equal 1, david.projects.size
1559
1765
  assert_equal 1, david.projects(true).size
1560
1766
  assert_equal 2, active_record.developers(true).size
@@ -1573,7 +1779,7 @@ class HasAndBelongsToManyAssociationsTest < Test::Unit::TestCase
1573
1779
  active_record = Project.find(1)
1574
1780
  active_record.developers.reload
1575
1781
  assert_equal 3, active_record.developers_by_sql.size
1576
-
1782
+
1577
1783
  active_record.developers_by_sql.delete(david)
1578
1784
  assert_equal 2, active_record.developers_by_sql(true).size
1579
1785
  end
@@ -1582,7 +1788,7 @@ class HasAndBelongsToManyAssociationsTest < Test::Unit::TestCase
1582
1788
  active_record = Project.find(1)
1583
1789
  active_record.developers.reload
1584
1790
  assert_equal 3, active_record.developers_by_sql.size
1585
-
1791
+
1586
1792
  active_record.developers_by_sql.delete(Developer.find(:all))
1587
1793
  assert_equal 0, active_record.developers_by_sql(true).size
1588
1794
  end
@@ -1604,9 +1810,9 @@ class HasAndBelongsToManyAssociationsTest < Test::Unit::TestCase
1604
1810
  end
1605
1811
 
1606
1812
  def test_additional_columns_from_join_table
1607
- assert_date_from_db Date.new(2004, 10, 10), Developer.find(1).projects.first.joined_on
1813
+ assert_date_from_db Date.new(2004, 10, 10), Developer.find(1).projects.first.joined_on.to_date
1608
1814
  end
1609
-
1815
+
1610
1816
  def test_destroy_all
1611
1817
  david = Developer.find(1)
1612
1818
  david.projects.reload
@@ -1616,14 +1822,11 @@ class HasAndBelongsToManyAssociationsTest < Test::Unit::TestCase
1616
1822
  assert david.projects(true).empty?
1617
1823
  end
1618
1824
 
1619
- def test_rich_association
1825
+ def test_deprecated_push_with_attributes_was_removed
1620
1826
  jamis = developers(:jamis)
1621
- assert_deprecated 'push_with_attributes' do
1827
+ assert_raise(NoMethodError) do
1622
1828
  jamis.projects.push_with_attributes(projects(:action_controller), :joined_on => Date.today)
1623
1829
  end
1624
-
1625
- assert_date_from_db Date.today, jamis.projects.select { |p| p.name == projects(:action_controller).name }.first.joined_on
1626
- assert_date_from_db Date.today, developers(:jamis).projects.select { |p| p.name == projects(:action_controller).name }.first.joined_on
1627
1830
  end
1628
1831
 
1629
1832
  def test_associations_with_conditions
@@ -1638,11 +1841,11 @@ class HasAndBelongsToManyAssociationsTest < Test::Unit::TestCase
1638
1841
  projects(:active_record).developers_named_david.clear
1639
1842
  assert_equal 2, projects(:active_record, :reload).developers.size
1640
1843
  end
1641
-
1844
+
1642
1845
  def test_find_in_association
1643
1846
  # Using sql
1644
1847
  assert_equal developers(:david), projects(:active_record).developers.find(developers(:david).id), "SQL find"
1645
-
1848
+
1646
1849
  # Using ruby
1647
1850
  active_record = projects(:active_record)
1648
1851
  active_record.developers.reload
@@ -1651,7 +1854,7 @@ class HasAndBelongsToManyAssociationsTest < Test::Unit::TestCase
1651
1854
 
1652
1855
  def test_find_in_association_with_custom_finder_sql
1653
1856
  assert_equal developers(:david), projects(:active_record).developers_with_finder_sql.find(developers(:david).id), "SQL find"
1654
-
1857
+
1655
1858
  active_record = projects(:active_record)
1656
1859
  active_record.developers_with_finder_sql.reload
1657
1860
  assert_equal developers(:david), active_record.developers_with_finder_sql.find(developers(:david).id), "Ruby find"
@@ -1667,6 +1870,56 @@ class HasAndBelongsToManyAssociationsTest < Test::Unit::TestCase
1667
1870
  assert_equal 3, projects(:active_record).limited_developers.find(:all, :limit => nil).size
1668
1871
  end
1669
1872
 
1873
+ def test_dynamic_find_should_respect_association_order
1874
+ # Developers are ordered 'name DESC, id DESC'
1875
+ low_id_jamis = developers(:jamis)
1876
+ middle_id_jamis = developers(:poor_jamis)
1877
+ high_id_jamis = projects(:active_record).developers.create(:name => 'Jamis')
1878
+
1879
+ assert_equal high_id_jamis, projects(:active_record).developers.find(:first, :conditions => "name = 'Jamis'")
1880
+ assert_equal high_id_jamis, projects(:active_record).developers.find_by_name('Jamis')
1881
+ end
1882
+
1883
+ def test_dynamic_find_order_should_override_association_order
1884
+ # Developers are ordered 'name DESC, id DESC'
1885
+ low_id_jamis = developers(:jamis)
1886
+ middle_id_jamis = developers(:poor_jamis)
1887
+ high_id_jamis = projects(:active_record).developers.create(:name => 'Jamis')
1888
+
1889
+ assert_equal low_id_jamis, projects(:active_record).developers.find(:first, :conditions => "name = 'Jamis'", :order => 'id')
1890
+ assert_equal low_id_jamis, projects(:active_record).developers.find_by_name('Jamis', :order => 'id')
1891
+ end
1892
+
1893
+ def test_dynamic_find_all_should_respect_association_order
1894
+ # Developers are ordered 'name DESC, id DESC'
1895
+ low_id_jamis = developers(:jamis)
1896
+ middle_id_jamis = developers(:poor_jamis)
1897
+ high_id_jamis = projects(:active_record).developers.create(:name => 'Jamis')
1898
+
1899
+ assert_equal [high_id_jamis, middle_id_jamis, low_id_jamis], projects(:active_record).developers.find(:all, :conditions => "name = 'Jamis'")
1900
+ assert_equal [high_id_jamis, middle_id_jamis, low_id_jamis], projects(:active_record).developers.find_all_by_name('Jamis')
1901
+ end
1902
+
1903
+ def test_dynamic_find_all_order_should_override_association_order
1904
+ # Developers are ordered 'name DESC, id DESC'
1905
+ low_id_jamis = developers(:jamis)
1906
+ middle_id_jamis = developers(:poor_jamis)
1907
+ high_id_jamis = projects(:active_record).developers.create(:name => 'Jamis')
1908
+
1909
+ assert_equal [low_id_jamis, middle_id_jamis, high_id_jamis], projects(:active_record).developers.find(:all, :conditions => "name = 'Jamis'", :order => 'id')
1910
+ assert_equal [low_id_jamis, middle_id_jamis, high_id_jamis], projects(:active_record).developers.find_all_by_name('Jamis', :order => 'id')
1911
+ end
1912
+
1913
+ def test_dynamic_find_all_should_respect_association_limit
1914
+ assert_equal 1, projects(:active_record).limited_developers.find(:all, :conditions => "name = 'Jamis'").length
1915
+ assert_equal 1, projects(:active_record).limited_developers.find_all_by_name('Jamis').length
1916
+ end
1917
+
1918
+ def test_dynamic_find_all_order_should_override_association_limit
1919
+ assert_equal 2, projects(:active_record).limited_developers.find(:all, :conditions => "name = 'Jamis'", :limit => 9_000).length
1920
+ assert_equal 2, projects(:active_record).limited_developers.find_all_by_name('Jamis', :limit => 9_000).length
1921
+ end
1922
+
1670
1923
  def test_new_with_values_in_collection
1671
1924
  jamis = DeveloperForProjectWithAfterCreateHook.find_by_name('Jamis')
1672
1925
  david = DeveloperForProjectWithAfterCreateHook.find_by_name('David')
@@ -1682,11 +1935,11 @@ class HasAndBelongsToManyAssociationsTest < Test::Unit::TestCase
1682
1935
  def test_find_in_association_with_options
1683
1936
  developers = projects(:active_record).developers.find(:all)
1684
1937
  assert_equal 3, developers.size
1685
-
1938
+
1686
1939
  assert_equal developers(:poor_jamis), projects(:active_record).developers.find(:first, :conditions => "salary < 10000")
1687
1940
  assert_equal developers(:jamis), projects(:active_record).developers.find(:first, :order => "salary DESC")
1688
1941
  end
1689
-
1942
+
1690
1943
  def test_replace_with_less
1691
1944
  david = developers(:david)
1692
1945
  david.projects = [projects(:action_controller)]
@@ -1701,7 +1954,7 @@ class HasAndBelongsToManyAssociationsTest < Test::Unit::TestCase
1701
1954
  assert_equal 2, david.projects.length
1702
1955
  assert !david.projects.include?(projects(:active_record))
1703
1956
  end
1704
-
1957
+
1705
1958
  def test_replace_on_new_object
1706
1959
  new_developer = Developer.new("name" => "Matz")
1707
1960
  new_developer.projects = [projects(:action_controller), Project.new("name" => "ActionWebSearch")]
@@ -1712,16 +1965,16 @@ class HasAndBelongsToManyAssociationsTest < Test::Unit::TestCase
1712
1965
  def test_consider_type
1713
1966
  developer = Developer.find(:first)
1714
1967
  special_project = SpecialProject.create("name" => "Special Project")
1715
-
1968
+
1716
1969
  other_project = developer.projects.first
1717
1970
  developer.special_projects << special_project
1718
1971
  developer.reload
1719
-
1972
+
1720
1973
  assert developer.projects.include?(special_project)
1721
1974
  assert developer.special_projects.include?(special_project)
1722
1975
  assert !developer.special_projects.include?(other_project)
1723
1976
  end
1724
-
1977
+
1725
1978
  def test_update_attributes_after_push_without_duplicate_join_table_rows
1726
1979
  developer = Developer.new("name" => "Kano")
1727
1980
  project = SpecialProject.create("name" => "Special Project")
@@ -1734,20 +1987,33 @@ class HasAndBelongsToManyAssociationsTest < Test::Unit::TestCase
1734
1987
  AND developer_id = #{developer.id}
1735
1988
  end_sql
1736
1989
  end
1737
-
1990
+
1738
1991
  def test_updating_attributes_on_non_rich_associations
1739
1992
  welcome = categories(:technology).posts.first
1740
1993
  welcome.title = "Something else"
1741
1994
  assert welcome.save!
1742
1995
  end
1743
-
1996
+
1997
+ def test_habtm_respects_select
1998
+ categories(:technology).select_testing_posts(true).each do |o|
1999
+ assert_respond_to o, :correctness_marker
2000
+ end
2001
+ assert_respond_to categories(:technology).select_testing_posts.find(:first), :correctness_marker
2002
+ end
2003
+
1744
2004
  def test_updating_attributes_on_rich_associations
1745
2005
  david = projects(:action_controller).developers.first
1746
2006
  david.name = "DHH"
1747
2007
  assert_raises(ActiveRecord::ReadOnlyRecord) { david.save! }
1748
2008
  end
1749
2009
 
1750
-
2010
+ def test_updating_attributes_on_rich_associations_with_limited_find_from_reflection
2011
+ david = projects(:action_controller).selected_developers.first
2012
+ david.name = "DHH"
2013
+ assert_nothing_raised { david.save! }
2014
+ end
2015
+
2016
+
1751
2017
  def test_updating_attributes_on_rich_associations_with_limited_find
1752
2018
  david = projects(:action_controller).developers.find(:all, :select => "developers.*").first
1753
2019
  david.name = "DHH"
@@ -1757,7 +2023,7 @@ class HasAndBelongsToManyAssociationsTest < Test::Unit::TestCase
1757
2023
  def test_join_table_alias
1758
2024
  assert_equal 3, Developer.find(:all, :include => {:projects => :developers}, :conditions => 'developers_projects_join.joined_on IS NOT NULL').size
1759
2025
  end
1760
-
2026
+
1761
2027
  def test_join_with_group
1762
2028
  group = Developer.columns.inject([]) do |g, c|
1763
2029
  g << "developers.#{c.name}"
@@ -1769,18 +2035,18 @@ class HasAndBelongsToManyAssociationsTest < Test::Unit::TestCase
1769
2035
  end
1770
2036
 
1771
2037
  def test_get_ids
1772
- assert_equal [projects(:active_record).id, projects(:action_controller).id], developers(:david).project_ids
2038
+ assert_equal projects(:active_record, :action_controller).map(&:id), developers(:david).project_ids
1773
2039
  assert_equal [projects(:active_record).id], developers(:jamis).project_ids
1774
2040
  end
1775
2041
 
1776
2042
  def test_assign_ids
1777
2043
  developer = Developer.new("name" => "Joe")
1778
- developer.project_ids = [projects(:active_record).id, projects(:action_controller).id]
2044
+ developer.project_ids = projects(:active_record, :action_controller).map(&:id)
1779
2045
  developer.save
1780
2046
  developer.reload
1781
2047
  assert_equal 2, developer.projects.length
1782
- assert_equal projects(:active_record), developer.projects[0]
1783
- assert_equal projects(:action_controller), developer.projects[1]
2048
+ assert_equal projects(:active_record), developer.projects[0]
2049
+ assert_equal projects(:action_controller), developer.projects[1]
1784
2050
  end
1785
2051
 
1786
2052
  def test_assign_ids_ignoring_blanks
@@ -1789,8 +2055,8 @@ class HasAndBelongsToManyAssociationsTest < Test::Unit::TestCase
1789
2055
  developer.save
1790
2056
  developer.reload
1791
2057
  assert_equal 2, developer.projects.length
1792
- assert_equal projects(:active_record), developer.projects[0]
1793
- assert_equal projects(:action_controller), developer.projects[1]
2058
+ assert_equal projects(:active_record), developer.projects[0]
2059
+ assert_equal projects(:action_controller), developer.projects[1]
1794
2060
  end
1795
2061
 
1796
2062
  def test_select_limited_ids_list
@@ -1803,37 +2069,83 @@ class HasAndBelongsToManyAssociationsTest < Test::Unit::TestCase
1803
2069
 
1804
2070
  join_base = ActiveRecord::Associations::ClassMethods::JoinDependency::JoinBase.new(Project)
1805
2071
  join_dep = ActiveRecord::Associations::ClassMethods::JoinDependency.new(join_base, :developers, nil)
1806
- unless current_adapter?(:IBM_DBAdapter)
1807
- projects = Project.send(:select_limited_ids_list, {:order => 'developers.created_at'}, join_dep)
1808
- assert_equal %w(1 2), projects.scan(/\d/).sort
1809
- else
1810
- # LUW: [IBM][CLI Driver][DB2/LINUX] SQL0214N
1811
- # An expression in the ORDER BY clause in the following position,
1812
- # or starting with "DEVELOPERS" in the "ORDER BY" clause is not valid.
1813
- # Reason code = "2". SQLSTATE=42822 SQLCODE=-214:
1814
- # SELECT DISTINCT projects.id FROM projects
1815
- # LEFT OUTER JOIN developers_projects ON developers_projects.project_id = projects.id
1816
- # LEFT OUTER JOIN developers ON developers.id = developers_projects.developer_id
1817
- # ORDER BY developers.created_at
1818
- #
1819
- # i5: [IBM][CLI Driver][AS] SQL0214N
1820
- # An expression in the ORDER BY clause in the following position,
1821
- # or starting with "1" in the "CREATED_AT" clause is not valid.
1822
- # Reason code = "2". SQLSTATE=42822 SQLCODE=-214:
1823
- # SELECT DISTINCT projects.id FROM projects
1824
- # LEFT OUTER JOIN developers_projects ON developers_projects.project_id = projects.id
1825
- # LEFT OUTER JOIN developers ON developers.id = developers_projects.developer_id
1826
- # ORDER BY developers.created_at
1827
- #
1828
- # zOS 9:[IBM][CLI Driver][DB2] SQL0214N
1829
- # An expression in the ORDER BY clause in the following position,
1830
- # or starting with "CREATED_AT" in the "ORDER BY" clause is not valid.
1831
- # Reason code = "2". SQLSTATE=42822 SQLCODE=-214:
1832
- # SELECT DISTINCT projects.id FROM projects
1833
- # LEFT OUTER JOIN developers_projects ON developers_projects.project_id = projects.id
1834
- # LEFT OUTER JOIN developers ON developers.id = developers_projects.developer_id
1835
- # ORDER BY developers.created_at
1836
- #
2072
+ unless current_adapter?(:IBM_DBAdapter)
2073
+ projects = Project.send(:select_limited_ids_list, {:order => 'developers.created_at'}, join_dep)
2074
+ assert !projects.include?("'"), projects
2075
+ assert_equal %w(1 2), projects.scan(/\d/).sort
2076
+ end
2077
+ end
2078
+
2079
+ def test_scoped_find_on_through_association_doesnt_return_read_only_records
2080
+ tag = Post.find(1).tags.find_by_name("General")
2081
+
2082
+ assert_nothing_raised do
2083
+ tag.save!
1837
2084
  end
1838
2085
  end
1839
2086
  end
2087
+
2088
+
2089
+ class IBMDBOverridingAssociationsTest < Test::Unit::TestCase
2090
+ class Person < ActiveRecord::Base; end
2091
+ class DifferentPerson < ActiveRecord::Base; end
2092
+
2093
+ class PeopleList < ActiveRecord::Base
2094
+ has_and_belongs_to_many :has_and_belongs_to_many, :before_add => :enlist
2095
+ has_many :has_many, :before_add => :enlist
2096
+ belongs_to :belongs_to
2097
+ has_one :has_one
2098
+ end
2099
+
2100
+ class DifferentPeopleList < PeopleList
2101
+ # Different association with the same name, callbacks should be omitted here.
2102
+ has_and_belongs_to_many :has_and_belongs_to_many, :class_name => 'DifferentPerson'
2103
+ has_many :has_many, :class_name => 'DifferentPerson'
2104
+ belongs_to :belongs_to, :class_name => 'DifferentPerson'
2105
+ has_one :has_one, :class_name => 'DifferentPerson'
2106
+ end
2107
+
2108
+ def test_habtm_association_redefinition_callbacks_should_differ_and_not_inherited
2109
+ # redeclared association on AR descendant should not inherit callbacks from superclass
2110
+ callbacks = PeopleList.read_inheritable_attribute(:before_add_for_has_and_belongs_to_many)
2111
+ assert_equal([:enlist], callbacks)
2112
+ callbacks = DifferentPeopleList.read_inheritable_attribute(:before_add_for_has_and_belongs_to_many)
2113
+ assert_equal([], callbacks)
2114
+ end
2115
+
2116
+ def test_has_many_association_redefinition_callbacks_should_differ_and_not_inherited
2117
+ # redeclared association on AR descendant should not inherit callbacks from superclass
2118
+ callbacks = PeopleList.read_inheritable_attribute(:before_add_for_has_many)
2119
+ assert_equal([:enlist], callbacks)
2120
+ callbacks = DifferentPeopleList.read_inheritable_attribute(:before_add_for_has_many)
2121
+ assert_equal([], callbacks)
2122
+ end
2123
+
2124
+ def test_habtm_association_redefinition_reflections_should_differ_and_not_inherited
2125
+ assert_not_equal(
2126
+ PeopleList.reflect_on_association(:has_and_belongs_to_many),
2127
+ DifferentPeopleList.reflect_on_association(:has_and_belongs_to_many)
2128
+ )
2129
+ end
2130
+
2131
+ def test_has_many_association_redefinition_reflections_should_differ_and_not_inherited
2132
+ assert_not_equal(
2133
+ PeopleList.reflect_on_association(:has_many),
2134
+ DifferentPeopleList.reflect_on_association(:has_many)
2135
+ )
2136
+ end
2137
+
2138
+ def test_belongs_to_association_redefinition_reflections_should_differ_and_not_inherited
2139
+ assert_not_equal(
2140
+ PeopleList.reflect_on_association(:belongs_to),
2141
+ DifferentPeopleList.reflect_on_association(:belongs_to)
2142
+ )
2143
+ end
2144
+
2145
+ def test_has_one_association_redefinition_reflections_should_differ_and_not_inherited
2146
+ assert_not_equal(
2147
+ PeopleList.reflect_on_association(:has_one),
2148
+ DifferentPeopleList.reflect_on_association(:has_one)
2149
+ )
2150
+ end
2151
+ end