db2 2.6.2 → 2.7.0
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/CHANGES +17 -0
- data/README +79 -141
- data/ext/Makefile.nt32 +3 -3
- data/ext/Makefile.nt32.191 +212 -0
- data/ext/extconf.rb +75 -14
- data/ext/ibm_db.c +504 -47
- data/ext/ruby_ibm_db.h +4 -1
- data/ext/ruby_ibm_db_cli.c +108 -1
- data/ext/ruby_ibm_db_cli.h +54 -1
- data/lib/active_record/connection_adapters/ibm_db_adapter.rb +423 -124
- data/lib/active_record/connection_adapters/ibm_db_pstmt.rb +1 -1
- data/test/cases/adapter_test.rb +169 -164
- data/test/cases/associations/belongs_to_associations_test.rb +268 -43
- data/test/cases/associations/cascaded_eager_loading_test.rb +31 -33
- data/test/cases/associations/has_and_belongs_to_many_associations_test.rb +90 -156
- data/test/cases/associations/join_model_test.rb +100 -150
- data/test/cases/attribute_methods_test.rb +259 -58
- data/test/cases/base_test.rb +785 -138
- data/test/cases/calculations_test.rb +128 -8
- data/test/cases/migration_test.rb +680 -286
- data/test/cases/persistence_test.rb +642 -0
- data/test/cases/query_cache_test.rb +257 -0
- data/test/cases/relations_test.rb +1182 -0
- data/test/cases/schema_dumper_test.rb +41 -17
- data/test/cases/transaction_callbacks_test.rb +300 -0
- data/test/cases/validations/uniqueness_validation_test.rb +38 -22
- data/test/cases/xml_serialization_test.rb +408 -0
- data/test/config.yml +154 -0
- data/test/connections/native_ibm_db/connection.rb +2 -0
- data/test/models/warehouse_thing.rb +4 -4
- data/test/schema/i5/ibm_db_specific_schema.rb +3 -1
- data/test/schema/ids/ibm_db_specific_schema.rb +3 -1
- data/test/schema/luw/ibm_db_specific_schema.rb +2 -0
- data/test/schema/schema.rb +196 -92
- data/test/schema/zOS/ibm_db_specific_schema.rb +3 -1
- metadata +73 -68
- data/.gitignore +0 -1
- data/test/cases/associations/eager_test.rb +0 -862
- data/test/cases/associations/has_many_through_associations_test.rb +0 -461
- data/test/cases/finder_test.rb +0 -1088
- data/test/cases/fixtures_test.rb +0 -684
@@ -8,25 +8,27 @@ require 'models/company'
|
|
8
8
|
require 'models/topic'
|
9
9
|
require 'models/reply'
|
10
10
|
require 'models/person'
|
11
|
+
require 'models/vertex'
|
12
|
+
require 'models/edge'
|
11
13
|
|
12
14
|
class CascadedEagerLoadingTest < ActiveRecord::TestCase
|
13
15
|
fixtures :authors, :mixins, :companies, :posts, :topics, :accounts, :comments,
|
14
|
-
:categorizations, :people, :categories
|
16
|
+
:categorizations, :people, :categories, :edges, :vertices
|
15
17
|
|
16
18
|
def test_eager_association_loading_with_cascaded_two_levels
|
17
19
|
authors = Author.find(:all, :include=>{:posts=>:comments}, :order=>"authors.id")
|
18
|
-
assert_equal
|
20
|
+
assert_equal 3, authors.size
|
19
21
|
assert_equal 5, authors[0].posts.size
|
20
|
-
assert_equal
|
21
|
-
assert_equal
|
22
|
+
assert_equal 3, authors[1].posts.size
|
23
|
+
assert_equal 10, authors[0].posts.collect{|post| post.comments.size }.inject(0){|sum,i| sum+i}
|
22
24
|
end
|
23
25
|
|
24
26
|
def test_eager_association_loading_with_cascaded_two_levels_and_one_level
|
25
27
|
authors = Author.find(:all, :include=>[{:posts=>:comments}, :categorizations], :order=>"authors.id")
|
26
|
-
assert_equal
|
28
|
+
assert_equal 3, authors.size
|
27
29
|
assert_equal 5, authors[0].posts.size
|
28
|
-
assert_equal
|
29
|
-
assert_equal
|
30
|
+
assert_equal 3, authors[1].posts.size
|
31
|
+
assert_equal 10, authors[0].posts.collect{|post| post.comments.size }.inject(0){|sum,i| sum+i}
|
30
32
|
assert_equal 1, authors[0].categorizations.size
|
31
33
|
assert_equal 2, authors[1].categorizations.size
|
32
34
|
end
|
@@ -37,7 +39,7 @@ class CascadedEagerLoadingTest < ActiveRecord::TestCase
|
|
37
39
|
end
|
38
40
|
authors = Author.joins(:posts).eager_load(:comments).where(:posts => {:taggings_count => 1}).all
|
39
41
|
assert_equal 1, assert_no_queries { authors.size }
|
40
|
-
assert_equal
|
42
|
+
assert_equal 10, assert_no_queries { authors[0].comments.size }
|
41
43
|
end
|
42
44
|
|
43
45
|
def test_eager_association_loading_grafts_stashed_associations_to_correct_parent
|
@@ -51,24 +53,26 @@ class CascadedEagerLoadingTest < ActiveRecord::TestCase
|
|
51
53
|
categories = Category.joins(:categorizations).includes([{:posts=>:comments}, :authors])
|
52
54
|
|
53
55
|
assert_nothing_raised do
|
54
|
-
assert_equal
|
55
|
-
assert_equal
|
56
|
+
assert_equal 4, categories.count
|
57
|
+
assert_equal 4, categories.all.count
|
58
|
+
assert_equal 3, categories.count(:distinct => true)
|
59
|
+
assert_equal 3, categories.all.uniq.size # Must uniq since instantiating with inner joins will get dupes
|
56
60
|
end
|
57
61
|
end
|
58
62
|
|
59
63
|
def test_cascaded_eager_association_loading_with_duplicated_includes
|
60
64
|
categories = Category.includes(:categorizations).includes(:categorizations => :author).where("categorizations.id is not null")
|
61
65
|
assert_nothing_raised do
|
62
|
-
assert_equal
|
63
|
-
assert_equal
|
66
|
+
assert_equal 3, categories.count
|
67
|
+
assert_equal 3, categories.all.size
|
64
68
|
end
|
65
69
|
end
|
66
70
|
|
67
71
|
def test_cascaded_eager_association_loading_with_twice_includes_edge_cases
|
68
72
|
categories = Category.includes(:categorizations => :author).includes(:categorizations => :post).where("posts.id is not null")
|
69
73
|
assert_nothing_raised do
|
70
|
-
assert_equal
|
71
|
-
assert_equal
|
74
|
+
assert_equal 3, categories.count
|
75
|
+
assert_equal 3, categories.all.size
|
72
76
|
end
|
73
77
|
end
|
74
78
|
|
@@ -81,15 +85,15 @@ class CascadedEagerLoadingTest < ActiveRecord::TestCase
|
|
81
85
|
|
82
86
|
def test_eager_association_loading_with_cascaded_two_levels_with_two_has_many_associations
|
83
87
|
authors = Author.find(:all, :include=>{:posts=>[:comments, :categorizations]}, :order=>"authors.id")
|
84
|
-
assert_equal
|
88
|
+
assert_equal 3, authors.size
|
85
89
|
assert_equal 5, authors[0].posts.size
|
86
|
-
assert_equal
|
87
|
-
assert_equal
|
90
|
+
assert_equal 3, authors[1].posts.size
|
91
|
+
assert_equal 10, authors[0].posts.collect{|post| post.comments.size }.inject(0){|sum,i| sum+i}
|
88
92
|
end
|
89
93
|
|
90
94
|
def test_eager_association_loading_with_cascaded_two_levels_and_self_table_reference
|
91
95
|
authors = Author.find(:all, :include=>{:posts=>[:comments, :author]}, :order=>"authors.id")
|
92
|
-
assert_equal
|
96
|
+
assert_equal 3, authors.size
|
93
97
|
assert_equal 5, authors[0].posts.size
|
94
98
|
assert_equal authors(:david).name, authors[0].name
|
95
99
|
assert_equal [authors(:david).name], authors[0].posts.collect{|post| post.author.name}.uniq
|
@@ -139,14 +143,14 @@ class CascadedEagerLoadingTest < ActiveRecord::TestCase
|
|
139
143
|
|
140
144
|
unless current_adapter?(:IBM_DBAdapter)
|
141
145
|
def test_eager_association_loading_with_multiple_stis_and_order
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
146
|
+
author = Author.find(:first, :include => { :posts => [ :special_comments , :very_special_comment ] }, :order => ['authors.name', 'comments.body', 'very_special_comments_posts.body'], :conditions => 'posts.id = 4')
|
147
|
+
assert_equal authors(:david), author
|
148
|
+
assert_no_queries do
|
149
|
+
author.posts.first.special_comments
|
150
|
+
author.posts.first.very_special_comment
|
151
|
+
end
|
148
152
|
end
|
149
|
-
end
|
153
|
+
end
|
150
154
|
|
151
155
|
def test_eager_association_loading_of_stis_with_multiple_references
|
152
156
|
authors = Author.find(:all, :include => { :posts => { :special_comments => { :post => [ :special_comments, :very_special_comment ] } } }, :order => 'comments.body, very_special_comments_posts.body', :conditions => 'posts.id = 4')
|
@@ -159,17 +163,11 @@ class CascadedEagerLoadingTest < ActiveRecord::TestCase
|
|
159
163
|
|
160
164
|
def test_eager_association_loading_where_first_level_returns_nil
|
161
165
|
authors = Author.find(:all, :include => {:post_about_thinking => :comments}, :order => 'authors.id DESC')
|
162
|
-
assert_equal [authors(:mary), authors(:david)], authors
|
166
|
+
assert_equal [authors(:bob), authors(:mary), authors(:david)], authors
|
163
167
|
assert_no_queries do
|
164
|
-
authors[
|
168
|
+
authors[2].post_about_thinking.comments.first
|
165
169
|
end
|
166
170
|
end
|
167
|
-
end
|
168
|
-
|
169
|
-
require 'models/vertex'
|
170
|
-
require 'models/edge'
|
171
|
-
class CascadedEagerLoadingTest < ActiveRecord::TestCase
|
172
|
-
fixtures :edges, :vertices
|
173
171
|
|
174
172
|
def test_eager_association_loading_with_recursive_cascading_four_levels_has_many_through
|
175
173
|
source = Vertex.find(:first, :include=>{:sinks=>{:sinks=>{:sinks=>:sinks}}}, :order => 'vertices.id')
|
@@ -23,7 +23,7 @@ require 'models/treaty'
|
|
23
23
|
require 'active_support/core_ext/string/conversions'
|
24
24
|
|
25
25
|
class ProjectWithAfterCreateHook < ActiveRecord::Base
|
26
|
-
|
26
|
+
self.table_name = 'projects'
|
27
27
|
has_and_belongs_to_many :developers,
|
28
28
|
:class_name => "DeveloperForProjectWithAfterCreateHook",
|
29
29
|
:join_table => "developers_projects",
|
@@ -39,7 +39,7 @@ class ProjectWithAfterCreateHook < ActiveRecord::Base
|
|
39
39
|
end
|
40
40
|
|
41
41
|
class DeveloperForProjectWithAfterCreateHook < ActiveRecord::Base
|
42
|
-
|
42
|
+
self.table_name = 'developers'
|
43
43
|
has_and_belongs_to_many :projects,
|
44
44
|
:class_name => "ProjectWithAfterCreateHook",
|
45
45
|
:join_table => "developers_projects",
|
@@ -48,7 +48,7 @@ class DeveloperForProjectWithAfterCreateHook < ActiveRecord::Base
|
|
48
48
|
end
|
49
49
|
|
50
50
|
class ProjectWithSymbolsForKeys < ActiveRecord::Base
|
51
|
-
|
51
|
+
self.table_name = 'projects'
|
52
52
|
has_and_belongs_to_many :developers,
|
53
53
|
:class_name => "DeveloperWithSymbolsForKeys",
|
54
54
|
:join_table => :developers_projects,
|
@@ -57,7 +57,7 @@ class ProjectWithSymbolsForKeys < ActiveRecord::Base
|
|
57
57
|
end
|
58
58
|
|
59
59
|
class DeveloperWithSymbolsForKeys < ActiveRecord::Base
|
60
|
-
|
60
|
+
self.table_name = 'developers'
|
61
61
|
has_and_belongs_to_many :projects,
|
62
62
|
:class_name => "ProjectWithSymbolsForKeys",
|
63
63
|
:join_table => :developers_projects,
|
@@ -66,33 +66,18 @@ class DeveloperWithSymbolsForKeys < ActiveRecord::Base
|
|
66
66
|
end
|
67
67
|
|
68
68
|
class DeveloperWithCounterSQL < ActiveRecord::Base
|
69
|
-
|
69
|
+
self.table_name = 'developers'
|
70
70
|
has_and_belongs_to_many :projects,
|
71
71
|
:class_name => "DeveloperWithCounterSQL",
|
72
72
|
:join_table => "developers_projects",
|
73
73
|
:association_foreign_key => "project_id",
|
74
74
|
:foreign_key => "developer_id",
|
75
|
-
:counter_sql =>
|
76
|
-
end
|
77
|
-
|
78
|
-
if current_adapter?(:IBM_DBAdapter)
|
79
|
-
class Novel < ActiveRecord::Base
|
80
|
-
has_and_belongs_to_many :writers
|
81
|
-
end
|
82
|
-
|
83
|
-
class Writer < ActiveRecord::Base
|
84
|
-
has_and_belongs_to_many :novels
|
85
|
-
end
|
86
|
-
|
87
|
-
class NovelsWriter < ActiveRecord::Base
|
88
|
-
belongs_to :writers
|
89
|
-
belongs_to :novels
|
90
|
-
end
|
75
|
+
:counter_sql => proc { "SELECT COUNT(*) AS count_all FROM projects INNER JOIN developers_projects ON projects.id = developers_projects.project_id WHERE developers_projects.developer_id =#{id}" }
|
91
76
|
end
|
92
77
|
|
93
78
|
class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase
|
94
79
|
fixtures :accounts, :companies, :categories, :posts, :categories_posts, :developers, :projects, :developers_projects,
|
95
|
-
:parrots, :pirates, :treasures, :price_estimates, :tags, :taggings
|
80
|
+
:parrots, :pirates, :parrots_pirates, :treasures, :price_estimates, :tags, :taggings
|
96
81
|
|
97
82
|
def setup_data_for_habtm_case
|
98
83
|
ActiveRecord::Base.connection.execute('delete from countries_treaties')
|
@@ -116,36 +101,14 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase
|
|
116
101
|
assert_equal 't1', record[1]
|
117
102
|
end
|
118
103
|
|
119
|
-
def
|
104
|
+
def test_proper_usage_of_primary_keys_and_join_table
|
120
105
|
setup_data_for_habtm_case
|
121
106
|
|
122
|
-
|
123
|
-
|
124
|
-
record = con.select_rows(sql).last
|
125
|
-
assert_not_nil record[2]
|
126
|
-
assert_not_nil record[3]
|
127
|
-
if current_adapter?(:Mysql2Adapter, :OracleAdapter)
|
128
|
-
assert_match %r{\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}}, record[2].to_s(:db)
|
129
|
-
assert_match %r{\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}}, record[3].to_s(:db)
|
130
|
-
else
|
131
|
-
assert_match %r{\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}}, record[2]
|
132
|
-
assert_match %r{\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}}, record[3]
|
133
|
-
end
|
134
|
-
end
|
107
|
+
assert_equal 'country_id', Country.primary_key
|
108
|
+
assert_equal 'treaty_id', Treaty.primary_key
|
135
109
|
|
136
|
-
|
137
|
-
|
138
|
-
Treaty.record_timestamps = false
|
139
|
-
setup_data_for_habtm_case
|
140
|
-
|
141
|
-
con = ActiveRecord::Base.connection
|
142
|
-
sql = 'select * from countries_treaties'
|
143
|
-
record = con.select_rows(sql).last
|
144
|
-
assert_nil record[2]
|
145
|
-
assert_nil record[3]
|
146
|
-
ensure
|
147
|
-
Treaty.record_timestamps = true
|
148
|
-
end
|
110
|
+
country = Country.first
|
111
|
+
assert_equal 1, country.treaties.count
|
149
112
|
end
|
150
113
|
|
151
114
|
def test_has_and_belongs_to_many
|
@@ -233,34 +196,6 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase
|
|
233
196
|
assert_equal 2, aredridel.projects(true).size
|
234
197
|
end
|
235
198
|
|
236
|
-
def test_adding_uses_default_values_on_join_table
|
237
|
-
ac = projects(:action_controller)
|
238
|
-
assert !developers(:jamis).projects.include?(ac)
|
239
|
-
developers(:jamis).projects << ac
|
240
|
-
|
241
|
-
assert developers(:jamis, :reload).projects.include?(ac)
|
242
|
-
project = developers(:jamis).projects.detect { |p| p == ac }
|
243
|
-
assert_equal 1, project.access_level.to_i
|
244
|
-
end
|
245
|
-
|
246
|
-
def test_habtm_attribute_access_and_respond_to
|
247
|
-
project = developers(:jamis).projects[0]
|
248
|
-
assert project.has_attribute?("name")
|
249
|
-
assert project.has_attribute?("joined_on")
|
250
|
-
assert project.has_attribute?("access_level")
|
251
|
-
assert project.respond_to?("name")
|
252
|
-
assert project.respond_to?("name=")
|
253
|
-
assert project.respond_to?("name?")
|
254
|
-
assert project.respond_to?("joined_on")
|
255
|
-
# given that the 'join attribute' won't be persisted, I don't
|
256
|
-
# think we should define the mutators
|
257
|
-
#assert project.respond_to?("joined_on=")
|
258
|
-
assert project.respond_to?("joined_on?")
|
259
|
-
assert project.respond_to?("access_level")
|
260
|
-
#assert project.respond_to?("access_level=")
|
261
|
-
assert project.respond_to?("access_level?")
|
262
|
-
end
|
263
|
-
|
264
199
|
def test_habtm_adding_before_save
|
265
200
|
no_of_devels = Developer.count
|
266
201
|
no_of_projects = Project.count
|
@@ -310,9 +245,24 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase
|
|
310
245
|
assert_equal Developer.find(1).projects.sort_by(&:id).last, proj # prove join table is updated
|
311
246
|
end
|
312
247
|
|
248
|
+
def test_new_aliased_to_build
|
249
|
+
devel = Developer.find(1)
|
250
|
+
proj = assert_no_queries { devel.projects.new("name" => "Projekt") }
|
251
|
+
assert !devel.projects.loaded?
|
252
|
+
|
253
|
+
assert_equal devel.projects.last, proj
|
254
|
+
assert devel.projects.loaded?
|
255
|
+
|
256
|
+
assert !proj.persisted?
|
257
|
+
devel.save
|
258
|
+
assert proj.persisted?
|
259
|
+
assert_equal devel.projects.last, proj
|
260
|
+
assert_equal Developer.find(1).projects.sort_by(&:id).last, proj # prove join table is updated
|
261
|
+
end
|
262
|
+
|
313
263
|
def test_build_by_new_record
|
314
264
|
devel = Developer.new(:name => "Marcel", :salary => 75000)
|
315
|
-
|
265
|
+
devel.projects.build(:name => "Make bed")
|
316
266
|
proj2 = devel.projects.build(:name => "Lie in it")
|
317
267
|
assert_equal devel.projects.last, proj2
|
318
268
|
assert !proj2.persisted?
|
@@ -335,42 +285,9 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase
|
|
335
285
|
assert_equal Developer.find(1).projects.sort_by(&:id).last, proj # prove join table is updated
|
336
286
|
end
|
337
287
|
|
338
|
-
if current_adapter?(:IBM_DBAdapter)
|
339
|
-
def test_lob_handling
|
340
|
-
assert_nothing_raised do
|
341
|
-
Novel.connection.create_table 'novels' do |t|
|
342
|
-
t.text :story
|
343
|
-
t.string :title
|
344
|
-
end
|
345
|
-
Writer.connection.create_table 'writers' do |t|
|
346
|
-
t.string :name
|
347
|
-
end
|
348
|
-
NovelsWriter.connection.create_table 'novels_writers' do |t|
|
349
|
-
t.belongs_to :novels
|
350
|
-
t.belongs_to :writers
|
351
|
-
end
|
352
|
-
end
|
353
|
-
|
354
|
-
w = Writer.new :name => 'Praveen'
|
355
|
-
w.save!
|
356
|
-
|
357
|
-
novel_story = "This is a short and sweet story"
|
358
|
-
|
359
|
-
novel = Novel.new :story => novel_story,:title => "Cool isn't it"
|
360
|
-
novel.writers << w
|
361
|
-
novel.save!
|
362
|
-
|
363
|
-
assert_equal novel_story,Novel.find(novel.id).story
|
364
|
-
ensure
|
365
|
-
Novel.connection.drop_table 'novels' rescue nil
|
366
|
-
Writer.connection.drop_table 'writers' rescue nil
|
367
|
-
NovelsWriter.connection.drop_table 'novels_writers' rescue nil
|
368
|
-
end
|
369
|
-
end
|
370
|
-
|
371
288
|
def test_create_by_new_record
|
372
289
|
devel = Developer.new(:name => "Marcel", :salary => 75000)
|
373
|
-
|
290
|
+
devel.projects.build(:name => "Make bed")
|
374
291
|
proj2 = devel.projects.build(:name => "Lie in it")
|
375
292
|
assert_equal devel.projects.last, proj2
|
376
293
|
assert !proj2.persisted?
|
@@ -473,38 +390,41 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase
|
|
473
390
|
def test_removing_associations_on_destroy
|
474
391
|
david = DeveloperWithBeforeDestroyRaise.find(1)
|
475
392
|
assert !david.projects.empty?
|
476
|
-
|
393
|
+
david.destroy
|
477
394
|
assert david.projects.empty?
|
478
395
|
assert DeveloperWithBeforeDestroyRaise.connection.select_all("SELECT * FROM developers_projects WHERE developer_id = 1").empty?
|
479
396
|
end
|
480
397
|
|
481
|
-
def test_additional_columns_from_join_table
|
482
|
-
assert_date_from_db Date.new(2004, 10, 10), Developer.find(1).projects.first.joined_on.to_date
|
483
|
-
end
|
484
|
-
|
485
398
|
def test_destroying
|
486
399
|
david = Developer.find(1)
|
487
|
-
|
400
|
+
project = Project.find(1)
|
488
401
|
david.projects.reload
|
489
402
|
assert_equal 2, david.projects.size
|
490
|
-
assert_equal 3,
|
403
|
+
assert_equal 3, project.developers.size
|
491
404
|
|
492
|
-
|
493
|
-
david.projects.destroy(
|
405
|
+
assert_no_difference "Project.count" do
|
406
|
+
david.projects.destroy(project)
|
494
407
|
end
|
495
408
|
|
409
|
+
join_records = Developer.connection.select_all("SELECT * FROM developers_projects WHERE developer_id = #{david.id} AND project_id = #{project.id}")
|
410
|
+
assert join_records.empty?
|
411
|
+
|
496
412
|
assert_equal 1, david.reload.projects.size
|
497
413
|
assert_equal 1, david.projects(true).size
|
498
414
|
end
|
499
415
|
|
500
|
-
def
|
416
|
+
def test_destroying_many
|
501
417
|
david = Developer.find(1)
|
502
418
|
david.projects.reload
|
419
|
+
projects = Project.all
|
503
420
|
|
504
|
-
|
505
|
-
david.projects.destroy(
|
421
|
+
assert_no_difference "Project.count" do
|
422
|
+
david.projects.destroy(*projects)
|
506
423
|
end
|
507
424
|
|
425
|
+
join_records = Developer.connection.select_all("SELECT * FROM developers_projects WHERE developer_id = #{david.id}")
|
426
|
+
assert join_records.empty?
|
427
|
+
|
508
428
|
assert_equal 0, david.reload.projects.size
|
509
429
|
assert_equal 0, david.projects(true).size
|
510
430
|
end
|
@@ -513,11 +433,38 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase
|
|
513
433
|
david = Developer.find(1)
|
514
434
|
david.projects.reload
|
515
435
|
assert !david.projects.empty?
|
516
|
-
|
436
|
+
|
437
|
+
assert_no_difference "Project.count" do
|
438
|
+
david.projects.destroy_all
|
439
|
+
end
|
440
|
+
|
441
|
+
join_records = Developer.connection.select_all("SELECT * FROM developers_projects WHERE developer_id = #{david.id}")
|
442
|
+
assert join_records.empty?
|
443
|
+
|
517
444
|
assert david.projects.empty?
|
518
445
|
assert david.projects(true).empty?
|
519
446
|
end
|
520
447
|
|
448
|
+
def test_destroy_associations_destroys_multiple_associations
|
449
|
+
george = parrots(:george)
|
450
|
+
assert !george.pirates.empty?
|
451
|
+
assert !george.treasures.empty?
|
452
|
+
|
453
|
+
assert_no_difference "Pirate.count" do
|
454
|
+
assert_no_difference "Treasure.count" do
|
455
|
+
george.destroy_associations
|
456
|
+
end
|
457
|
+
end
|
458
|
+
|
459
|
+
join_records = Parrot.connection.select_all("SELECT * FROM parrots_pirates WHERE parrot_id = #{george.id}")
|
460
|
+
assert join_records.empty?
|
461
|
+
assert george.pirates(true).empty?
|
462
|
+
|
463
|
+
join_records = Parrot.connection.select_all("SELECT * FROM parrots_treasures WHERE parrot_id = #{george.id}")
|
464
|
+
assert join_records.empty?
|
465
|
+
assert george.treasures(true).empty?
|
466
|
+
end
|
467
|
+
|
521
468
|
def test_deprecated_push_with_attributes_was_removed
|
522
469
|
jamis = developers(:jamis)
|
523
470
|
assert_raise(NoMethodError) do
|
@@ -607,8 +554,6 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase
|
|
607
554
|
|
608
555
|
def test_dynamic_find_should_respect_association_order
|
609
556
|
# Developers are ordered 'name DESC, id DESC'
|
610
|
-
low_id_jamis = developers(:jamis)
|
611
|
-
middle_id_jamis = developers(:poor_jamis)
|
612
557
|
high_id_jamis = projects(:active_record).developers.create(:name => 'Jamis')
|
613
558
|
|
614
559
|
assert_equal high_id_jamis, projects(:active_record).developers.find(:first, :conditions => "name = 'Jamis'")
|
@@ -704,7 +649,7 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase
|
|
704
649
|
project = SpecialProject.create("name" => "Special Project")
|
705
650
|
assert developer.save
|
706
651
|
developer.projects << project
|
707
|
-
developer.
|
652
|
+
developer.update_column("name", "Bruza")
|
708
653
|
assert_equal 1, Developer.connection.select_value(<<-end_sql).to_i
|
709
654
|
SELECT count(*) FROM developers_projects
|
710
655
|
WHERE project_id = #{project.id}
|
@@ -725,23 +670,12 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase
|
|
725
670
|
assert_respond_to categories(:technology).select_testing_posts.find(:first), :correctness_marker
|
726
671
|
end
|
727
672
|
|
728
|
-
def
|
729
|
-
|
730
|
-
david.name = "DHH"
|
731
|
-
assert_raise(ActiveRecord::ReadOnlyRecord) { david.save! }
|
732
|
-
end
|
733
|
-
|
734
|
-
def test_updating_attributes_on_rich_associations_with_limited_find_from_reflection
|
735
|
-
david = projects(:action_controller).selected_developers.first
|
736
|
-
david.name = "DHH"
|
737
|
-
assert_nothing_raised { david.save! }
|
673
|
+
def test_habtm_selects_all_columns_by_default
|
674
|
+
assert_equal Project.column_names.sort, developers(:david).projects.first.attributes.keys.sort
|
738
675
|
end
|
739
676
|
|
740
|
-
|
741
|
-
|
742
|
-
david = projects(:action_controller).developers.find(:all, :select => "developers.*").first
|
743
|
-
david.name = "DHH"
|
744
|
-
assert david.save!
|
677
|
+
def test_habtm_respects_select_query_method
|
678
|
+
assert_equal ['id'], developers(:david).projects.select(:id).first.attributes.keys
|
745
679
|
end
|
746
680
|
|
747
681
|
def test_join_table_alias
|
@@ -761,12 +695,12 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase
|
|
761
695
|
def test_find_grouped
|
762
696
|
all_posts_from_category1 = Post.find(:all, :conditions => "category_id = 1", :joins => :categories)
|
763
697
|
grouped_posts_of_category1 = Post.find(:all, :conditions => "category_id = 1", :group => "author_id", :select => 'count(posts.id) as posts_count', :joins => :categories)
|
764
|
-
assert_equal
|
765
|
-
assert_equal
|
698
|
+
assert_equal 5, all_posts_from_category1.size
|
699
|
+
assert_equal 2, grouped_posts_of_category1.size
|
766
700
|
end
|
767
701
|
|
768
702
|
def test_find_scoped_grouped
|
769
|
-
assert_equal
|
703
|
+
assert_equal 5, categories(:general).posts_grouped_by_title.size
|
770
704
|
assert_equal 1, categories(:technology).posts_grouped_by_title.size
|
771
705
|
end
|
772
706
|
|
@@ -846,12 +780,10 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase
|
|
846
780
|
}
|
847
781
|
end
|
848
782
|
|
849
|
-
|
850
|
-
|
851
|
-
|
852
|
-
|
853
|
-
assert Category.find(1).posts_with_authors_sorted_by_author_id.find_by_title('Welcome to the weblog')
|
854
|
-
end
|
783
|
+
def test_dynamic_find_should_respect_association_include
|
784
|
+
# SQL error in sort clause if :include is not included
|
785
|
+
# due to Unknown column 'authors.id'
|
786
|
+
assert Category.find(1).posts_with_authors_sorted_by_author_id.find_by_title('Welcome to the weblog')
|
855
787
|
end
|
856
788
|
|
857
789
|
def test_counting_on_habtm_association_and_not_array
|
@@ -874,7 +806,7 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase
|
|
874
806
|
assert_equal 1, developer.projects.count
|
875
807
|
end
|
876
808
|
|
877
|
-
unless current_adapter?(:PostgreSQLAdapter)
|
809
|
+
unless current_adapter?(:PostgreSQLAdapter, :IBM_DBAdapter)
|
878
810
|
def test_count_with_finder_sql
|
879
811
|
assert_equal 3, projects(:active_record).developers_with_finder_sql.count
|
880
812
|
assert_equal 3, projects(:active_record).developers_with_multiline_finder_sql.count
|
@@ -892,10 +824,12 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase
|
|
892
824
|
david = Developer.find(1)
|
893
825
|
# clear cache possibly created by other tests
|
894
826
|
david.projects.reset_column_information
|
895
|
-
|
896
|
-
|
827
|
+
|
828
|
+
assert_queries(1) { david.projects.columns; david.projects.columns }
|
829
|
+
|
830
|
+
## and again to verify that reset_column_information clears the cache correctly
|
897
831
|
david.projects.reset_column_information
|
898
|
-
assert_queries(
|
832
|
+
assert_queries(1) { david.projects.columns; david.projects.columns }
|
899
833
|
end
|
900
834
|
|
901
835
|
def test_attributes_are_being_set_when_initialized_from_habm_association_with_where_clause
|