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
@@ -177,7 +177,7 @@ module ActiveRecord
|
|
177
177
|
end
|
178
178
|
|
179
179
|
pstmt = connection.prepare(statement, "#{self.class.name} Create")
|
180
|
-
self.id = connection.prepared_insert(pstmt, quoted_attributes.values)
|
180
|
+
self.id = connection.prepared_insert(pstmt, quoted_attributes.values, self.id)
|
181
181
|
|
182
182
|
@new_record = false
|
183
183
|
id
|
data/test/cases/adapter_test.rb
CHANGED
@@ -1,202 +1,207 @@
|
|
1
1
|
require "cases/helper"
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
3
|
+
module ActiveRecord
|
4
|
+
class AdapterTest < ActiveRecord::TestCase
|
5
|
+
def setup
|
6
|
+
@connection = ActiveRecord::Base.connection
|
7
|
+
end
|
7
8
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
9
|
+
if current_adapter?(:IBM_DBAdapter)
|
10
|
+
def test_a_connection_attributes
|
11
|
+
if @connection.servertype.class.name.include?('::IBM_IDS')
|
12
|
+
return
|
13
|
+
end
|
14
|
+
if @connection.respond_to?(:schema)
|
15
|
+
previous_schema = ActiveRecord::Base.connection.schema
|
16
|
+
ActiveRecord::Base.connection.schema = 'SYSCAT'
|
17
|
+
assert_equal 'SYSCAT', ActiveRecord::Base.connection.schema
|
18
|
+
ActiveRecord::Base.connection.schema = previous_schema
|
19
|
+
else
|
20
|
+
warn "#{@connection.class} does not support client connection attribute schema_name"
|
21
|
+
end
|
22
|
+
|
23
|
+
if @connection.respond_to?(:app_user)
|
24
|
+
ActiveRecord::Base.connection.app_user = 'new_user'
|
25
|
+
assert_equal 'new_user', ActiveRecord::Base.connection.app_user
|
26
|
+
else
|
27
|
+
warn "#{@connection.class} does not support client connection attribute SQL_ATTR_INFO_USER"
|
28
|
+
end
|
29
|
+
|
30
|
+
if @connection.respond_to?(:account)
|
31
|
+
ActiveRecord::Base.connection.account = 'new_acct'
|
32
|
+
assert_equal 'new_acct', ActiveRecord::Base.connection.account
|
33
|
+
else
|
34
|
+
warn "#{@connection.class} does not support client connection attribute SQL_ATTR_INFO_ACCTSTR"
|
35
|
+
end
|
36
|
+
|
37
|
+
if @connection.respond_to?(:application)
|
38
|
+
ActiveRecord::Base.connection.application = 'new_app'
|
39
|
+
assert_equal 'new_app', ActiveRecord::Base.connection.application
|
40
|
+
else
|
41
|
+
warn "#{@connection.class} does not support client connection attribute SQL_ATTR_INFO_APPLNAME"
|
42
|
+
end
|
43
|
+
|
44
|
+
if @connection.respond_to?(:workstation)
|
45
|
+
ActiveRecord::Base.connection.workstation = 'new_wrkst'
|
46
|
+
assert_equal 'new_wrkst', ActiveRecord::Base.connection.workstation
|
47
|
+
else
|
48
|
+
warn "#{@connection.class} does not support client connection attribute SQL_ATTR_INFO_WRKSTNNAME"
|
49
|
+
end
|
41
50
|
end
|
51
|
+
end
|
42
52
|
|
43
|
-
|
44
|
-
|
45
|
-
|
53
|
+
def test_tables
|
54
|
+
tables = @connection.tables
|
55
|
+
assert tables.include?("accounts")
|
56
|
+
assert tables.include?("authors")
|
57
|
+
assert tables.include?("tasks")
|
58
|
+
assert tables.include?("topics")
|
59
|
+
end
|
60
|
+
|
61
|
+
def test_table_exists?
|
62
|
+
assert @connection.table_exists?("accounts")
|
63
|
+
assert !@connection.table_exists?("nonexistingtable")
|
64
|
+
assert !@connection.table_exists?(nil)
|
65
|
+
end
|
66
|
+
|
67
|
+
def test_indexes
|
68
|
+
idx_name = "accounts_idx"
|
69
|
+
|
70
|
+
if @connection.respond_to?(:indexes)
|
71
|
+
indexes = @connection.indexes("accounts")
|
72
|
+
assert indexes.empty?
|
73
|
+
|
74
|
+
@connection.add_index :accounts, :firm_id, :name => idx_name
|
75
|
+
indexes = @connection.indexes("accounts")
|
76
|
+
assert_equal "accounts", indexes.first.table
|
77
|
+
# OpenBase does not have the concept of a named index
|
78
|
+
# Indexes are merely properties of columns.
|
79
|
+
assert_equal idx_name, indexes.first.name unless current_adapter?(:OpenBaseAdapter)
|
80
|
+
assert !indexes.first.unique
|
81
|
+
assert_equal ["firm_id"], indexes.first.columns
|
46
82
|
else
|
47
|
-
warn "#{@connection.class} does not
|
83
|
+
warn "#{@connection.class} does not respond to #indexes"
|
48
84
|
end
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
def test_tables
|
53
|
-
tables = @connection.tables
|
54
|
-
assert tables.include?("accounts")
|
55
|
-
assert tables.include?("authors")
|
56
|
-
assert tables.include?("tasks")
|
57
|
-
assert tables.include?("topics")
|
58
|
-
end
|
59
85
|
|
60
|
-
|
61
|
-
|
62
|
-
assert !@connection.table_exists?("nonexistingtable")
|
63
|
-
end
|
64
|
-
|
65
|
-
def test_indexes
|
66
|
-
idx_name = "accounts_idx"
|
67
|
-
|
68
|
-
if @connection.respond_to?(:indexes)
|
69
|
-
indexes = @connection.indexes("accounts")
|
70
|
-
assert indexes.empty?
|
71
|
-
|
72
|
-
@connection.add_index :accounts, :firm_id, :name => idx_name
|
73
|
-
indexes = @connection.indexes("accounts")
|
74
|
-
assert_equal "accounts", indexes.first.table
|
75
|
-
# OpenBase does not have the concept of a named index
|
76
|
-
# Indexes are merely properties of columns.
|
77
|
-
assert_equal idx_name, indexes.first.name unless current_adapter?(:OpenBaseAdapter)
|
78
|
-
assert !indexes.first.unique
|
79
|
-
assert_equal ["firm_id"], indexes.first.columns
|
80
|
-
else
|
81
|
-
warn "#{@connection.class} does not respond to #indexes"
|
86
|
+
ensure
|
87
|
+
@connection.remove_index(:accounts, :name => idx_name) rescue nil
|
82
88
|
end
|
83
89
|
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
def test_current_database
|
89
|
-
if @connection.respond_to?(:current_database)
|
90
|
-
assert_equal ENV['ARUNIT_DB_NAME'] || "activerecord_unittest", @connection.current_database
|
90
|
+
def test_current_database
|
91
|
+
if @connection.respond_to?(:current_database)
|
92
|
+
assert_equal ARTest.connection_config['arunit']['database'], @connection.current_database
|
93
|
+
end
|
91
94
|
end
|
92
|
-
end
|
93
95
|
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
96
|
+
if current_adapter?(:MysqlAdapter)
|
97
|
+
def test_charset
|
98
|
+
assert_not_nil @connection.charset
|
99
|
+
assert_not_equal 'character_set_database', @connection.charset
|
100
|
+
assert_equal @connection.show_variable('character_set_database'), @connection.charset
|
101
|
+
end
|
100
102
|
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
103
|
+
def test_collation
|
104
|
+
assert_not_nil @connection.collation
|
105
|
+
assert_not_equal 'collation_database', @connection.collation
|
106
|
+
assert_equal @connection.show_variable('collation_database'), @connection.collation
|
107
|
+
end
|
106
108
|
|
107
|
-
|
108
|
-
|
109
|
-
|
109
|
+
def test_show_nonexistent_variable_returns_nil
|
110
|
+
assert_nil @connection.show_variable('foo_bar_baz')
|
111
|
+
end
|
110
112
|
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
113
|
+
def test_not_specifying_database_name_for_cross_database_selects
|
114
|
+
begin
|
115
|
+
assert_nothing_raised do
|
116
|
+
ActiveRecord::Base.establish_connection(ActiveRecord::Base.configurations['arunit'].except(:database))
|
117
|
+
|
118
|
+
config = ARTest.connection_config
|
119
|
+
ActiveRecord::Base.connection.execute(
|
120
|
+
"SELECT #{config['arunit']['database']}.pirates.*, #{config['arunit2']['database']}.courses.* " \
|
121
|
+
"FROM #{config['arunit']['database']}.pirates, #{config['arunit2']['database']}.courses"
|
122
|
+
)
|
123
|
+
end
|
124
|
+
ensure
|
125
|
+
ActiveRecord::Base.establish_connection 'arunit'
|
116
126
|
end
|
117
|
-
ensure
|
118
|
-
ActiveRecord::Base.establish_connection 'arunit'
|
119
127
|
end
|
120
128
|
end
|
121
|
-
end
|
122
|
-
|
123
|
-
if current_adapter?(:PostgreSQLAdapter)
|
124
|
-
def test_encoding
|
125
|
-
assert_not_nil @connection.encoding
|
126
|
-
end
|
127
|
-
end
|
128
129
|
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
130
|
+
def test_table_alias
|
131
|
+
def @connection.test_table_alias_length() 10; end
|
132
|
+
class << @connection
|
133
|
+
alias_method :old_table_alias_length, :table_alias_length
|
134
|
+
alias_method :table_alias_length, :test_table_alias_length
|
135
|
+
end
|
135
136
|
|
136
|
-
|
137
|
-
|
138
|
-
|
137
|
+
assert_equal 'posts', @connection.table_alias_for('posts')
|
138
|
+
assert_equal 'posts_comm', @connection.table_alias_for('posts_comments')
|
139
|
+
assert_equal 'dbo_posts', @connection.table_alias_for('dbo.posts')
|
139
140
|
|
140
|
-
|
141
|
-
|
142
|
-
|
141
|
+
class << @connection
|
142
|
+
remove_method :table_alias_length
|
143
|
+
alias_method :table_alias_length, :old_table_alias_length
|
144
|
+
end
|
143
145
|
end
|
144
|
-
end
|
145
146
|
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
147
|
+
# test resetting sequences in odd tables in postgreSQL
|
148
|
+
if ActiveRecord::Base.connection.respond_to?(:reset_pk_sequence!)
|
149
|
+
require 'models/movie'
|
150
|
+
require 'models/subscriber'
|
150
151
|
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
152
|
+
def test_reset_empty_table_with_custom_pk
|
153
|
+
Movie.delete_all
|
154
|
+
Movie.connection.reset_pk_sequence! 'movies'
|
155
|
+
assert_equal 1, Movie.create(:name => 'fight club').id
|
156
|
+
end
|
156
157
|
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
158
|
+
if ActiveRecord::Base.connection.adapter_name != "FrontBase"
|
159
|
+
def test_reset_table_with_non_integer_pk
|
160
|
+
Subscriber.delete_all
|
161
|
+
Subscriber.connection.reset_pk_sequence! 'subscribers'
|
162
|
+
sub = Subscriber.new(:name => 'robert drake')
|
163
|
+
sub.id = 'bob drake'
|
164
|
+
assert_nothing_raised { sub.save! }
|
165
|
+
end
|
164
166
|
end
|
165
167
|
end
|
166
|
-
end
|
167
168
|
|
168
|
-
|
169
|
-
@connection.execute "INSERT INTO subscribers(nick) VALUES('me')"
|
170
|
-
assert_raises(ActiveRecord::RecordNotUnique) do
|
169
|
+
def test_uniqueness_violations_are_translated_to_specific_exception
|
171
170
|
@connection.execute "INSERT INTO subscribers(nick) VALUES('me')"
|
171
|
+
assert_raises(ActiveRecord::RecordNotUnique) do
|
172
|
+
@connection.execute "INSERT INTO subscribers(nick) VALUES('me')"
|
173
|
+
end
|
172
174
|
end
|
173
|
-
end
|
174
175
|
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
176
|
+
def test_foreign_key_violations_are_translated_to_specific_exception
|
177
|
+
unless @connection.adapter_name == 'SQLite'
|
178
|
+
assert_raises(ActiveRecord::InvalidForeignKey) do
|
179
|
+
# Oracle adapter uses prefetched primary key values from sequence and passes them to connection adapter insert method
|
180
|
+
if @connection.prefetch_primary_key?
|
181
|
+
id_value = @connection.next_sequence_value(@connection.default_sequence_name("fk_test_has_fk", "id"))
|
182
|
+
@connection.execute "INSERT INTO fk_test_has_fk (id, fk_id) VALUES (#{id_value},0)"
|
183
|
+
else
|
184
|
+
@connection.execute "INSERT INTO fk_test_has_fk (fk_id) VALUES (0)"
|
185
|
+
end
|
184
186
|
end
|
185
187
|
end
|
186
188
|
end
|
187
|
-
end
|
188
|
-
|
189
|
-
unless current_adapter?(:IBM_DBAdapter)
|
190
|
-
def test_add_limit_offset_should_sanitize_sql_injection_for_limit_without_comas
|
191
|
-
sql_inject = "1 select * from schema"
|
192
|
-
assert_no_match(/schema/, @connection.add_limit_offset!("", :limit=>sql_inject))
|
193
|
-
assert_no_match(/schema/, @connection.add_limit_offset!("", :limit=>sql_inject, :offset=>7))
|
194
|
-
end
|
195
189
|
|
196
|
-
def
|
197
|
-
|
198
|
-
|
199
|
-
|
190
|
+
def test_disable_referential_integrity
|
191
|
+
assert_nothing_raised do
|
192
|
+
@connection.disable_referential_integrity do
|
193
|
+
# Oracle adapter uses prefetched primary key values from sequence and passes them to connection adapter insert method
|
194
|
+
if @connection.prefetch_primary_key?
|
195
|
+
id_value = @connection.next_sequence_value(@connection.default_sequence_name("fk_test_has_fk", "id"))
|
196
|
+
@connection.execute "INSERT INTO fk_test_has_fk (id, fk_id) VALUES (#{id_value},0)"
|
197
|
+
else
|
198
|
+
@connection.execute "INSERT INTO fk_test_has_fk (fk_id) VALUES (0)"
|
199
|
+
end
|
200
|
+
# should deleted created record as otherwise disable_referential_integrity will try to enable contraints after executed block
|
201
|
+
# and will fail (at least on Oracle)
|
202
|
+
@connection.execute "DELETE FROM fk_test_has_fk"
|
203
|
+
end
|
204
|
+
end
|
200
205
|
end
|
201
206
|
end
|
202
207
|
end
|
@@ -13,11 +13,12 @@ require 'models/comment'
|
|
13
13
|
require 'models/sponsor'
|
14
14
|
require 'models/member'
|
15
15
|
require 'models/essay'
|
16
|
+
require 'models/toy'
|
16
17
|
|
17
18
|
class BelongsToAssociationsTest < ActiveRecord::TestCase
|
18
19
|
fixtures :accounts, :companies, :developers, :projects, :topics,
|
19
20
|
:developers_projects, :computers, :authors, :author_addresses,
|
20
|
-
:posts, :tags, :taggings, :comments
|
21
|
+
:posts, :tags, :taggings, :comments, :sponsors, :members
|
21
22
|
|
22
23
|
def test_belongs_to
|
23
24
|
Client.find(3).firm.name
|
@@ -54,11 +55,6 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase
|
|
54
55
|
assert_nothing_raised { account.firm = account.firm }
|
55
56
|
end
|
56
57
|
|
57
|
-
def test_triple_equality
|
58
|
-
assert Client.find(3).firm === Firm
|
59
|
-
assert Firm === Client.find(3).firm
|
60
|
-
end
|
61
|
-
|
62
58
|
def test_type_mismatch
|
63
59
|
assert_raise(ActiveRecord::AssociationTypeMismatch) { Account.find(1).firm = 1 }
|
64
60
|
assert_raise(ActiveRecord::AssociationTypeMismatch) { Account.find(1).firm = Project.find(1) }
|
@@ -79,23 +75,17 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase
|
|
79
75
|
end
|
80
76
|
|
81
77
|
def test_eager_loading_with_primary_key
|
82
|
-
|
83
|
-
|
78
|
+
Firm.create("name" => "Apple")
|
79
|
+
Client.create("name" => "Citibank", :firm_name => "Apple")
|
84
80
|
citibank_result = Client.find(:first, :conditions => {:name => "Citibank"}, :include => :firm_with_primary_key)
|
85
|
-
|
81
|
+
assert citibank_result.association_cache.key?(:firm_with_primary_key)
|
86
82
|
end
|
87
83
|
|
88
|
-
def
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
citibank.firm = first_firm
|
94
|
-
original_proxy = citibank.firm
|
95
|
-
citibank.firm = another_firm
|
96
|
-
|
97
|
-
assert_equal first_firm.object_id, original_proxy.target.object_id
|
98
|
-
assert_equal another_firm.object_id, citibank.firm.target.object_id
|
84
|
+
def test_eager_loading_with_primary_key_as_symbol
|
85
|
+
Firm.create("name" => "Apple")
|
86
|
+
Client.create("name" => "Citibank", :firm_name => "Apple")
|
87
|
+
citibank_result = Client.find(:first, :conditions => {:name => "Citibank"}, :include => :firm_with_primary_key_symbols)
|
88
|
+
assert citibank_result.association_cache.key?(:firm_with_primary_key_symbols)
|
99
89
|
end
|
100
90
|
|
101
91
|
def test_creating_the_belonging_object
|
@@ -130,6 +120,23 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase
|
|
130
120
|
assert_equal apple.name, client.firm_name
|
131
121
|
end
|
132
122
|
|
123
|
+
def test_create!
|
124
|
+
client = Client.create!(:name => "Jimmy")
|
125
|
+
account = client.create_account!(:credit_limit => 10)
|
126
|
+
assert_equal account, client.account
|
127
|
+
assert account.persisted?
|
128
|
+
client.save
|
129
|
+
client.reload
|
130
|
+
assert_equal account, client.account
|
131
|
+
end
|
132
|
+
|
133
|
+
def test_failing_create!
|
134
|
+
client = Client.create!(:name => "Jimmy")
|
135
|
+
assert_raise(ActiveRecord::RecordInvalid) { client.create_account! }
|
136
|
+
assert_not_nil client.account
|
137
|
+
assert client.account.new_record?
|
138
|
+
end
|
139
|
+
|
133
140
|
def test_natural_assignment_to_nil
|
134
141
|
client = Client.find(3)
|
135
142
|
client.firm = nil
|
@@ -156,6 +163,26 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase
|
|
156
163
|
assert_not_nil Company.find(3).firm_with_condition, "Microsoft should have a firm"
|
157
164
|
end
|
158
165
|
|
166
|
+
def test_polymorphic_association_class
|
167
|
+
sponsor = Sponsor.new
|
168
|
+
assert_nil sponsor.association(:sponsorable).send(:klass)
|
169
|
+
|
170
|
+
sponsor.sponsorable_type = '' # the column doesn't have to be declared NOT NULL
|
171
|
+
assert_nil sponsor.association(:sponsorable).send(:klass)
|
172
|
+
|
173
|
+
sponsor.sponsorable = Member.new :name => "Bert"
|
174
|
+
assert_equal Member, sponsor.association(:sponsorable).send(:klass)
|
175
|
+
end
|
176
|
+
|
177
|
+
def test_with_polymorphic_and_condition
|
178
|
+
sponsor = Sponsor.create
|
179
|
+
member = Member.create :name => "Bert"
|
180
|
+
sponsor.sponsorable = member
|
181
|
+
|
182
|
+
assert_equal member, sponsor.sponsorable
|
183
|
+
assert_nil sponsor.sponsorable_with_conditions
|
184
|
+
end
|
185
|
+
|
159
186
|
def test_with_select
|
160
187
|
assert_equal Company.find(2).firm_with_select.attributes.size, 1
|
161
188
|
assert_equal Company.find(2, :include => :firm_with_select ).firm_with_select.attributes.size, 1
|
@@ -172,17 +199,6 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase
|
|
172
199
|
assert_equal 0, Topic.find(debate.id).send(:read_attribute, "replies_count"), "First reply deleted"
|
173
200
|
end
|
174
201
|
|
175
|
-
def test_belongs_to_with_primary_key_counter
|
176
|
-
debate = Topic.create("title" => "debate")
|
177
|
-
assert_equal 0, debate.send(:read_attribute, "replies_count"), "No replies yet"
|
178
|
-
|
179
|
-
trash = debate.replies_with_primary_key.create("title" => "blah!", "content" => "world around!")
|
180
|
-
assert_equal 1, Topic.find(debate.id).send(:read_attribute, "replies_count"), "First reply created"
|
181
|
-
|
182
|
-
trash.destroy
|
183
|
-
assert_equal 0, Topic.find(debate.id).send(:read_attribute, "replies_count"), "First reply deleted"
|
184
|
-
end
|
185
|
-
|
186
202
|
def test_belongs_to_counter_with_assigning_nil
|
187
203
|
p = Post.find(1)
|
188
204
|
c = Comment.find(1)
|
@@ -195,16 +211,23 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase
|
|
195
211
|
assert_equal 1, Post.find(p.id).comments.size
|
196
212
|
end
|
197
213
|
|
198
|
-
def
|
199
|
-
debate
|
200
|
-
|
214
|
+
def test_belongs_to_with_primary_key_counter
|
215
|
+
debate = Topic.create("title" => "debate")
|
216
|
+
debate2 = Topic.create("title" => "debate2")
|
217
|
+
reply = Reply.create("title" => "blah!", "content" => "world around!", "parent_title" => "debate")
|
218
|
+
|
219
|
+
assert_equal 1, debate.reload.replies_count
|
220
|
+
assert_equal 0, debate2.reload.replies_count
|
201
221
|
|
202
|
-
|
203
|
-
|
222
|
+
reply.topic_with_primary_key = debate2
|
223
|
+
|
224
|
+
assert_equal 0, debate.reload.replies_count
|
225
|
+
assert_equal 1, debate2.reload.replies_count
|
204
226
|
|
205
227
|
reply.topic_with_primary_key = nil
|
206
228
|
|
207
|
-
assert_equal 0,
|
229
|
+
assert_equal 0, debate.reload.replies_count
|
230
|
+
assert_equal 0, debate2.reload.replies_count
|
208
231
|
end
|
209
232
|
|
210
233
|
def test_belongs_to_counter_with_reassigning
|
@@ -278,6 +301,15 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase
|
|
278
301
|
assert_equal 1, Topic.find(topic.id)[:replies_count]
|
279
302
|
end
|
280
303
|
|
304
|
+
def test_belongs_to_counter_when_update_column
|
305
|
+
topic = Topic.create!(:title => "37s")
|
306
|
+
topic.replies.create!(:title => "re: 37s", :content => "rails")
|
307
|
+
assert_equal 1, Topic.find(topic.id)[:replies_count]
|
308
|
+
|
309
|
+
topic.update_column(:content, "rails is wonderfull")
|
310
|
+
assert_equal 1, Topic.find(topic.id)[:replies_count]
|
311
|
+
end
|
312
|
+
|
281
313
|
def test_assignment_before_child_saved
|
282
314
|
final_cut = Client.new("name" => "Final Cut")
|
283
315
|
firm = Firm.find(1)
|
@@ -308,13 +340,27 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase
|
|
308
340
|
assert_equal Firm.find(:first, :order => "id"), c.firm_with_basic_id
|
309
341
|
end
|
310
342
|
|
311
|
-
def
|
312
|
-
|
313
|
-
|
343
|
+
def test_setting_foreign_key_after_nil_target_loaded
|
344
|
+
client = Client.new
|
345
|
+
client.firm_with_basic_id
|
346
|
+
client.firm_id = 1
|
314
347
|
|
315
|
-
|
316
|
-
|
317
|
-
|
348
|
+
assert_equal companies(:first_firm), client.firm_with_basic_id
|
349
|
+
end
|
350
|
+
|
351
|
+
def test_polymorphic_setting_foreign_key_after_nil_target_loaded
|
352
|
+
sponsor = Sponsor.new
|
353
|
+
sponsor.sponsorable
|
354
|
+
sponsor.sponsorable_id = 1
|
355
|
+
sponsor.sponsorable_type = "Member"
|
356
|
+
|
357
|
+
assert_equal members(:groucho), sponsor.sponsorable
|
358
|
+
end
|
359
|
+
|
360
|
+
def test_dont_find_target_when_foreign_key_is_null
|
361
|
+
tagging = taggings(:thinking_general)
|
362
|
+
queries = assert_sql { tagging.super_tag }
|
363
|
+
assert_equal 0, queries.length
|
318
364
|
end
|
319
365
|
|
320
366
|
def test_field_name_same_as_foreign_key
|
@@ -416,6 +462,18 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase
|
|
416
462
|
assert_nil sponsor.sponsorable_id
|
417
463
|
end
|
418
464
|
|
465
|
+
def test_assignment_updates_foreign_id_field_for_new_and_saved_records
|
466
|
+
client = Client.new
|
467
|
+
saved_firm = Firm.create :name => "Saved"
|
468
|
+
new_firm = Firm.new
|
469
|
+
|
470
|
+
client.firm = saved_firm
|
471
|
+
assert_equal saved_firm.id, client.client_of
|
472
|
+
|
473
|
+
client.firm = new_firm
|
474
|
+
assert_nil client.client_of
|
475
|
+
end
|
476
|
+
|
419
477
|
def test_polymorphic_assignment_with_primary_key_updates_foreign_id_field_for_new_and_saved_records
|
420
478
|
essay = Essay.new
|
421
479
|
saved_writer = Author.create(:name => "David")
|
@@ -483,4 +541,171 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase
|
|
483
541
|
new_firm = accounts(:signals37).build_firm(:name => 'Apple')
|
484
542
|
assert_equal new_firm.name, "Apple"
|
485
543
|
end
|
544
|
+
|
545
|
+
def test_reassigning_the_parent_id_updates_the_object
|
546
|
+
client = companies(:second_client)
|
547
|
+
|
548
|
+
client.firm
|
549
|
+
client.firm_with_condition
|
550
|
+
firm_proxy = client.send(:association_instance_get, :firm)
|
551
|
+
firm_with_condition_proxy = client.send(:association_instance_get, :firm_with_condition)
|
552
|
+
|
553
|
+
assert !firm_proxy.stale_target?
|
554
|
+
assert !firm_with_condition_proxy.stale_target?
|
555
|
+
assert_equal companies(:first_firm), client.firm
|
556
|
+
assert_equal companies(:first_firm), client.firm_with_condition
|
557
|
+
|
558
|
+
client.client_of = companies(:another_firm).id
|
559
|
+
|
560
|
+
assert firm_proxy.stale_target?
|
561
|
+
assert firm_with_condition_proxy.stale_target?
|
562
|
+
assert_equal companies(:another_firm), client.firm
|
563
|
+
assert_equal companies(:another_firm), client.firm_with_condition
|
564
|
+
end
|
565
|
+
|
566
|
+
def test_polymorphic_reassignment_of_associated_id_updates_the_object
|
567
|
+
sponsor = sponsors(:moustache_club_sponsor_for_groucho)
|
568
|
+
|
569
|
+
sponsor.sponsorable
|
570
|
+
proxy = sponsor.send(:association_instance_get, :sponsorable)
|
571
|
+
|
572
|
+
assert !proxy.stale_target?
|
573
|
+
assert_equal members(:groucho), sponsor.sponsorable
|
574
|
+
|
575
|
+
sponsor.sponsorable_id = members(:some_other_guy).id
|
576
|
+
|
577
|
+
assert proxy.stale_target?
|
578
|
+
assert_equal members(:some_other_guy), sponsor.sponsorable
|
579
|
+
end
|
580
|
+
|
581
|
+
def test_polymorphic_reassignment_of_associated_type_updates_the_object
|
582
|
+
sponsor = sponsors(:moustache_club_sponsor_for_groucho)
|
583
|
+
|
584
|
+
sponsor.sponsorable
|
585
|
+
proxy = sponsor.send(:association_instance_get, :sponsorable)
|
586
|
+
|
587
|
+
assert !proxy.stale_target?
|
588
|
+
assert_equal members(:groucho), sponsor.sponsorable
|
589
|
+
|
590
|
+
sponsor.sponsorable_type = 'Firm'
|
591
|
+
|
592
|
+
assert proxy.stale_target?
|
593
|
+
assert_equal companies(:first_firm), sponsor.sponsorable
|
594
|
+
end
|
595
|
+
|
596
|
+
def test_reloading_association_with_key_change
|
597
|
+
client = companies(:second_client)
|
598
|
+
firm = client.association(:firm)
|
599
|
+
|
600
|
+
client.firm = companies(:another_firm)
|
601
|
+
firm.reload
|
602
|
+
assert_equal companies(:another_firm), firm.target
|
603
|
+
|
604
|
+
client.client_of = companies(:first_firm).id
|
605
|
+
firm.reload
|
606
|
+
assert_equal companies(:first_firm), firm.target
|
607
|
+
end
|
608
|
+
|
609
|
+
def test_polymorphic_counter_cache
|
610
|
+
tagging = taggings(:welcome_general)
|
611
|
+
post = posts(:welcome)
|
612
|
+
comment = comments(:greetings)
|
613
|
+
|
614
|
+
assert_difference lambda { post.reload.taggings_count }, -1 do
|
615
|
+
assert_difference 'comment.reload.taggings_count', +1 do
|
616
|
+
tagging.taggable = comment
|
617
|
+
end
|
618
|
+
end
|
619
|
+
end
|
620
|
+
|
621
|
+
def test_polymorphic_with_custom_foreign_type
|
622
|
+
sponsor = sponsors(:moustache_club_sponsor_for_groucho)
|
623
|
+
groucho = members(:groucho)
|
624
|
+
other = members(:some_other_guy)
|
625
|
+
|
626
|
+
assert_equal groucho, sponsor.sponsorable
|
627
|
+
assert_equal groucho, sponsor.thing
|
628
|
+
|
629
|
+
sponsor.thing = other
|
630
|
+
|
631
|
+
assert_equal other, sponsor.sponsorable
|
632
|
+
assert_equal other, sponsor.thing
|
633
|
+
|
634
|
+
sponsor.sponsorable = groucho
|
635
|
+
|
636
|
+
assert_equal groucho, sponsor.sponsorable
|
637
|
+
assert_equal groucho, sponsor.thing
|
638
|
+
end
|
639
|
+
|
640
|
+
def test_build_with_conditions
|
641
|
+
client = companies(:second_client)
|
642
|
+
firm = client.build_bob_firm
|
643
|
+
|
644
|
+
assert_equal "Bob", firm.name
|
645
|
+
end
|
646
|
+
|
647
|
+
def test_create_with_conditions
|
648
|
+
client = companies(:second_client)
|
649
|
+
firm = client.create_bob_firm
|
650
|
+
|
651
|
+
assert_equal "Bob", firm.name
|
652
|
+
end
|
653
|
+
|
654
|
+
def test_create_bang_with_conditions
|
655
|
+
client = companies(:second_client)
|
656
|
+
firm = client.create_bob_firm!
|
657
|
+
|
658
|
+
assert_equal "Bob", firm.name
|
659
|
+
end
|
660
|
+
|
661
|
+
def test_build_with_block
|
662
|
+
client = Client.create(:name => 'Client Company')
|
663
|
+
|
664
|
+
firm = client.build_firm{ |f| f.name = 'Agency Company' }
|
665
|
+
assert_equal 'Agency Company', firm.name
|
666
|
+
end
|
667
|
+
|
668
|
+
def test_create_with_block
|
669
|
+
client = Client.create(:name => 'Client Company')
|
670
|
+
|
671
|
+
firm = client.create_firm{ |f| f.name = 'Agency Company' }
|
672
|
+
assert_equal 'Agency Company', firm.name
|
673
|
+
end
|
674
|
+
|
675
|
+
def test_create_bang_with_block
|
676
|
+
client = Client.create(:name => 'Client Company')
|
677
|
+
|
678
|
+
firm = client.create_firm!{ |f| f.name = 'Agency Company' }
|
679
|
+
assert_equal 'Agency Company', firm.name
|
680
|
+
end
|
681
|
+
|
682
|
+
def test_should_set_foreign_key_on_create_association
|
683
|
+
client = Client.create! :name => "fuu"
|
684
|
+
|
685
|
+
firm = client.create_firm :name => "baa"
|
686
|
+
assert_equal firm.id, client.client_of
|
687
|
+
end
|
688
|
+
|
689
|
+
def test_should_set_foreign_key_on_create_association!
|
690
|
+
client = Client.create! :name => "fuu"
|
691
|
+
|
692
|
+
firm = client.create_firm! :name => "baa"
|
693
|
+
assert_equal firm.id, client.client_of
|
694
|
+
end
|
695
|
+
|
696
|
+
def test_self_referential_belongs_to_with_counter_cache_assigning_nil
|
697
|
+
comment = Comment.create! :post => posts(:thinking), :body => "fuu"
|
698
|
+
comment.parent = nil
|
699
|
+
comment.save!
|
700
|
+
|
701
|
+
assert_equal nil, comment.reload.parent
|
702
|
+
assert_equal 0, comments(:greetings).reload.children_count
|
703
|
+
end
|
704
|
+
|
705
|
+
def test_polymorphic_with_custom_primary_key
|
706
|
+
toy = Toy.create!
|
707
|
+
sponsor = Sponsor.create!(:sponsorable => toy)
|
708
|
+
|
709
|
+
assert_equal toy, sponsor.reload.sponsorable
|
710
|
+
end
|
486
711
|
end
|