composite_primary_keys 12.0.5 → 13.0.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.
- checksums.yaml +4 -4
- data/History.rdoc +883 -862
- data/README.rdoc +181 -180
- data/lib/composite_primary_keys.rb +119 -118
- data/lib/composite_primary_keys/active_model/attribute_assignment.rb +19 -19
- data/lib/composite_primary_keys/associations/association_scope.rb +66 -68
- data/lib/composite_primary_keys/associations/join_dependency.rb +118 -103
- data/lib/composite_primary_keys/attribute_methods.rb +21 -9
- data/lib/composite_primary_keys/attribute_methods/primary_key.rb +0 -2
- data/lib/composite_primary_keys/attribute_methods/read.rb +30 -30
- data/lib/composite_primary_keys/attribute_methods/write.rb +35 -35
- data/lib/composite_primary_keys/base.rb +141 -141
- data/lib/composite_primary_keys/connection_adapters/abstract/database_statements.rb +37 -22
- data/lib/composite_primary_keys/connection_adapters/sqlserver/database_statements.rb +44 -44
- data/lib/composite_primary_keys/core.rb +48 -48
- data/lib/composite_primary_keys/nested_attributes.rb +1 -1
- data/lib/composite_primary_keys/persistence.rb +82 -81
- data/lib/composite_primary_keys/reflection.rb +91 -29
- data/lib/composite_primary_keys/relation.rb +197 -193
- data/lib/composite_primary_keys/relation/batches.rb +16 -8
- data/lib/composite_primary_keys/relation/calculations.rb +104 -81
- data/lib/composite_primary_keys/relation/finder_methods.rb +235 -235
- data/lib/composite_primary_keys/relation/predicate_builder/association_query_value.rb +39 -20
- data/lib/composite_primary_keys/relation/query_methods.rb +42 -42
- data/lib/composite_primary_keys/relation/where_clause.rb +18 -23
- data/lib/composite_primary_keys/table_metadata.rb +11 -0
- data/lib/composite_primary_keys/version.rb +8 -8
- data/test/abstract_unit.rb +114 -114
- data/test/connections/databases.ci.yml +22 -19
- data/test/fixtures/db_definitions/db2-create-tables.sql +112 -112
- data/test/fixtures/db_definitions/db2-drop-tables.sql +16 -16
- data/test/fixtures/db_definitions/mysql.sql +180 -180
- data/test/fixtures/db_definitions/oracle.drop.sql +41 -41
- data/test/fixtures/db_definitions/oracle.sql +199 -199
- data/test/fixtures/db_definitions/postgresql.sql +182 -182
- data/test/fixtures/db_definitions/sqlite.sql +169 -169
- data/test/fixtures/db_definitions/sqlserver.sql +176 -176
- data/test/fixtures/department.rb +16 -16
- data/test/fixtures/departments.yml +19 -15
- data/test/fixtures/employees.yml +33 -28
- data/test/fixtures/restaurants_suburbs.yml +10 -10
- data/test/fixtures/streets.yml +16 -16
- data/test/fixtures/suburbs.yml +14 -14
- data/test/fixtures/user.rb +11 -11
- data/test/test_associations.rb +364 -358
- data/test/test_attributes.rb +75 -60
- data/test/test_calculations.rb +49 -42
- data/test/test_create.rb +218 -180
- data/test/test_delete.rb +182 -179
- data/test/test_exists.rb +39 -39
- data/test/test_find.rb +170 -157
- data/test/test_ids.rb +112 -112
- data/test/test_nested_attributes.rb +67 -67
- data/test/test_update.rb +96 -96
- metadata +5 -5
- data/lib/composite_primary_keys/connection_adapters/mysql/database_statements.rb +0 -24
@@ -1,11 +1,11 @@
|
|
1
|
-
a:
|
2
|
-
franchise_id: 1
|
3
|
-
store_id: 1
|
4
|
-
city_id: 1
|
5
|
-
suburb_id: 1
|
6
|
-
|
7
|
-
b:
|
8
|
-
franchise_id: 1
|
9
|
-
store_id: 1
|
10
|
-
city_id: 2
|
1
|
+
a:
|
2
|
+
franchise_id: 1
|
3
|
+
store_id: 1
|
4
|
+
city_id: 1
|
5
|
+
suburb_id: 1
|
6
|
+
|
7
|
+
b:
|
8
|
+
franchise_id: 1
|
9
|
+
store_id: 1
|
10
|
+
city_id: 2
|
11
11
|
suburb_id: 2
|
data/test/fixtures/streets.yml
CHANGED
@@ -1,17 +1,17 @@
|
|
1
|
-
first:
|
2
|
-
id: 1
|
3
|
-
city_id: 1
|
4
|
-
suburb_id: 1
|
5
|
-
name: First Street
|
6
|
-
|
7
|
-
second1:
|
8
|
-
id: 2
|
9
|
-
city_id: 2
|
10
|
-
suburb_id: 2
|
11
|
-
name: First Street
|
12
|
-
|
13
|
-
second2:
|
14
|
-
id: 3
|
15
|
-
city_id: 2
|
16
|
-
suburb_id: 2
|
1
|
+
first:
|
2
|
+
id: 1
|
3
|
+
city_id: 1
|
4
|
+
suburb_id: 1
|
5
|
+
name: First Street
|
6
|
+
|
7
|
+
second1:
|
8
|
+
id: 2
|
9
|
+
city_id: 2
|
10
|
+
suburb_id: 2
|
11
|
+
name: First Street
|
12
|
+
|
13
|
+
second2:
|
14
|
+
id: 3
|
15
|
+
city_id: 2
|
16
|
+
suburb_id: 2
|
17
17
|
name: Second Street
|
data/test/fixtures/suburbs.yml
CHANGED
@@ -1,14 +1,14 @@
|
|
1
|
-
first:
|
2
|
-
city_id: 1
|
3
|
-
suburb_id: 1
|
4
|
-
name: First Suburb
|
5
|
-
|
6
|
-
second:
|
7
|
-
city_id: 2
|
8
|
-
suburb_id: 2
|
9
|
-
name: Second Suburb
|
10
|
-
|
11
|
-
no_mcdonalds:
|
12
|
-
city_id: 1
|
13
|
-
suburb_id: 3
|
14
|
-
name: Third Suburb
|
1
|
+
first:
|
2
|
+
city_id: 1
|
3
|
+
suburb_id: 1
|
4
|
+
name: First Suburb
|
5
|
+
|
6
|
+
second:
|
7
|
+
city_id: 2
|
8
|
+
suburb_id: 2
|
9
|
+
name: Second Suburb
|
10
|
+
|
11
|
+
no_mcdonalds:
|
12
|
+
city_id: 1
|
13
|
+
suburb_id: 3
|
14
|
+
name: Third Suburb
|
data/test/fixtures/user.rb
CHANGED
@@ -1,11 +1,11 @@
|
|
1
|
-
class User < ActiveRecord::Base
|
2
|
-
has_many :readings
|
3
|
-
has_many :articles, :through => :readings
|
4
|
-
|
5
|
-
has_many :comments, :as => :person
|
6
|
-
has_one :first_comment, :as => :person, :class_name => "Comment"
|
7
|
-
|
8
|
-
def find_custom_articles
|
9
|
-
articles.where("name = ?", "Article One")
|
10
|
-
end
|
11
|
-
end
|
1
|
+
class User < ActiveRecord::Base
|
2
|
+
has_many :readings
|
3
|
+
has_many :articles, :through => :readings
|
4
|
+
|
5
|
+
has_many :comments, :as => :person
|
6
|
+
has_one :first_comment, :as => :person, :class_name => "Comment"
|
7
|
+
|
8
|
+
def find_custom_articles
|
9
|
+
articles.where("name = ?", "Article One")
|
10
|
+
end
|
11
|
+
end
|
data/test/test_associations.rb
CHANGED
@@ -1,358 +1,364 @@
|
|
1
|
-
require File.expand_path('../abstract_unit', __FILE__)
|
2
|
-
|
3
|
-
class TestAssociations < ActiveSupport::TestCase
|
4
|
-
fixtures :articles, :products, :tariffs, :product_tariffs, :suburbs, :streets, :restaurants,
|
5
|
-
:dorms, :rooms, :room_attributes, :room_attribute_assignments, :students, :room_assignments, :users, :readings,
|
6
|
-
:departments, :employees, :memberships, :membership_statuses
|
7
|
-
|
8
|
-
def test_products
|
9
|
-
assert_not_nil products(:first_product).product_tariffs
|
10
|
-
assert_equal 2, products(:first_product).product_tariffs.length
|
11
|
-
assert_not_nil products(:first_product).tariffs
|
12
|
-
assert_equal 2, products(:first_product).tariffs.length
|
13
|
-
end
|
14
|
-
|
15
|
-
def test_product_tariffs
|
16
|
-
assert_not_nil product_tariffs(:first_flat).product
|
17
|
-
assert_not_nil product_tariffs(:first_flat).tariff
|
18
|
-
assert_equal Product, product_tariffs(:first_flat).product.class
|
19
|
-
assert_equal Tariff, product_tariffs(:first_flat).tariff.class
|
20
|
-
end
|
21
|
-
|
22
|
-
def test_tariffs
|
23
|
-
assert_not_nil tariffs(:flat).product_tariffs
|
24
|
-
assert_equal 1, tariffs(:flat).product_tariffs.length
|
25
|
-
assert_not_nil tariffs(:flat).products
|
26
|
-
assert_equal 1, tariffs(:flat).products.length
|
27
|
-
end
|
28
|
-
|
29
|
-
# Its not generating the instances of associated classes from the rows
|
30
|
-
def test_find_includes
|
31
|
-
products = Product.includes(:product_tariffs)
|
32
|
-
assert_equal(3, products.length)
|
33
|
-
assert_equal(3, products.inject(0) {|sum, product| sum + product.product_tariffs.length})
|
34
|
-
end
|
35
|
-
|
36
|
-
def test_find_includes_2
|
37
|
-
products = ProductTariff.where(:tariff_id => 2).order('product_id, tariff_id').includes(:tariff)
|
38
|
-
assert_equal(2, products.length)
|
39
|
-
end
|
40
|
-
|
41
|
-
def test_find_includes_eager_loading
|
42
|
-
product = products(:second_product)
|
43
|
-
product_tarrif = product_tariffs(:second_free)
|
44
|
-
|
45
|
-
# First get a legitimate product tarrif
|
46
|
-
products = Product.includes(:product_tariffs).where('product_tariffs.product_id = ?', product.id).references(:product_tariffs)
|
47
|
-
assert_equal(1, products.length)
|
48
|
-
assert_equal(product, products.first)
|
49
|
-
assert_equal([product_tarrif], products.first.product_tariffs)
|
50
|
-
end
|
51
|
-
|
52
|
-
def test_find_eager_loading_none
|
53
|
-
product = products(:third_product)
|
54
|
-
|
55
|
-
products = Product.includes(:product_tariffs).where(:id => product.id).references(:product_tariffs)
|
56
|
-
assert_equal(1, products.length)
|
57
|
-
assert_equal(product, products.first)
|
58
|
-
assert_empty(products.first.product_tariffs)
|
59
|
-
end
|
60
|
-
|
61
|
-
def test_find_includes_tariffs
|
62
|
-
tariffs = Tariff.includes(:product_tariffs)
|
63
|
-
assert_equal(3, tariffs.length)
|
64
|
-
assert_equal(3, tariffs.inject(0) {|sum, tariff| sum + tariff.product_tariffs.length})
|
65
|
-
end
|
66
|
-
|
67
|
-
def test_find_each_does_not_throw_error
|
68
|
-
tariffs = Tariff.includes(:product_tariffs)
|
69
|
-
worked = false
|
70
|
-
tariffs.first.product_tariffs.order(:tariff_id).find_each do |pt|
|
71
|
-
worked = true
|
72
|
-
end
|
73
|
-
assert worked
|
74
|
-
end
|
75
|
-
|
76
|
-
def test_association_with_composite_primary_key_can_be_autosaved
|
77
|
-
room = Room.new(dorm_id: 1000, room_id: 1001)
|
78
|
-
room_assignment = RoomAssignment.new(student_id: 1000)
|
79
|
-
room_assignment.room = room
|
80
|
-
room_assignment.save
|
81
|
-
room_assignment.reload
|
82
|
-
assert_equal(room_assignment.dorm_id, 1000)
|
83
|
-
assert_equal(room_assignment.room_id, 1001)
|
84
|
-
end
|
85
|
-
|
86
|
-
def test_has_one_association_is_not_cached_to_where_it_returns_the_wrong_one
|
87
|
-
engineering = departments(:engineering)
|
88
|
-
engineering_head = engineering.head
|
89
|
-
assert_equal(employees(:sarah), engineering_head)
|
90
|
-
|
91
|
-
accounting = departments(:accounting)
|
92
|
-
accounting_head = accounting.head
|
93
|
-
assert_equal(employees(:steve), accounting_head)
|
94
|
-
|
95
|
-
refute_equal accounting_head, engineering_head
|
96
|
-
end
|
97
|
-
|
98
|
-
def test_has_one_association_primary_key_and_foreign_key_are_present
|
99
|
-
# department = departments(:engineering)
|
100
|
-
# assert_equal(2, department.employees.count)
|
101
|
-
# assert_equal('Sarah', department.employees[0].name)
|
102
|
-
# assert_equal('Robert', department.employees[1].name)
|
103
|
-
# assert_equal('Sarah', department.head.name)
|
104
|
-
|
105
|
-
department = departments(:human_resources)
|
106
|
-
assert_equal(1, department.employees.count)
|
107
|
-
assert_equal('Mindy', department.employees[0].name)
|
108
|
-
assert_equal('Mindy', department.head.name)
|
109
|
-
|
110
|
-
head = department.create_head(name: 'Rick')
|
111
|
-
assert_equal(department, head.department)
|
112
|
-
assert_equal('Rick', department.head.name)
|
113
|
-
|
114
|
-
department.reload
|
115
|
-
assert_equal(1, department.employees.count)
|
116
|
-
end
|
117
|
-
|
118
|
-
def test_has_one_autosave
|
119
|
-
department = departments(:engineering)
|
120
|
-
assert_equal('Sarah', department.head.name)
|
121
|
-
|
122
|
-
department.head.name = 'Sarah1'
|
123
|
-
department.save!
|
124
|
-
assert_equal('Sarah1', department.head.name)
|
125
|
-
end
|
126
|
-
|
127
|
-
def test_has_many_association_is_not_cached_to_where_it_returns_the_wrong_ones
|
128
|
-
engineering = departments(:engineering)
|
129
|
-
engineering_employees = engineering.employees
|
130
|
-
|
131
|
-
accounting = departments(:accounting)
|
132
|
-
accounting_employees = accounting.employees
|
133
|
-
|
134
|
-
refute_equal accounting_employees, engineering_employees
|
135
|
-
end
|
136
|
-
|
137
|
-
def test_has_many_association_primary_key_and_foreign_key_are_present
|
138
|
-
department = departments(:accounting)
|
139
|
-
assert_equal(2, department.employees.count)
|
140
|
-
assert_equal('Steve', department.employees[0].name)
|
141
|
-
assert_equal('Jill', department.employees[1].name)
|
142
|
-
|
143
|
-
department.employees.create(name: 'Rick')
|
144
|
-
|
145
|
-
department.reload
|
146
|
-
assert_equal(3, department.employees.count)
|
147
|
-
employees = department.employees.sort_by(&:name)
|
148
|
-
assert_equal('Jill', employees[0].name)
|
149
|
-
assert_equal('Rick', employees[1].name)
|
150
|
-
assert_equal('Steve', employees[2].name)
|
151
|
-
end
|
152
|
-
|
153
|
-
def test_find_includes_product_tariffs_product
|
154
|
-
# Old style
|
155
|
-
product_tariffs = ProductTariff.includes(:product)
|
156
|
-
assert_not_nil(product_tariffs)
|
157
|
-
assert_equal(3, product_tariffs.length)
|
158
|
-
|
159
|
-
# New style
|
160
|
-
product_tariffs = ProductTariff.includes(:product)
|
161
|
-
assert_not_nil(product_tariffs)
|
162
|
-
assert_equal(3, product_tariffs.length)
|
163
|
-
end
|
164
|
-
|
165
|
-
def test_find_includes_product_tariffs_tariff
|
166
|
-
# Old style
|
167
|
-
product_tariffs = ProductTariff.includes(:tariff)
|
168
|
-
assert_equal(3, product_tariffs.length)
|
169
|
-
|
170
|
-
# New style
|
171
|
-
product_tariffs = ProductTariff.includes(:tariff)
|
172
|
-
assert_equal(3, product_tariffs.length)
|
173
|
-
end
|
174
|
-
|
175
|
-
def test_has_many_through
|
176
|
-
products = Product.includes(:tariffs)
|
177
|
-
assert_equal(3, products.length)
|
178
|
-
|
179
|
-
tarrifs_length = products.inject(0) {|sum, product| sum + product.tariffs.length}
|
180
|
-
assert_equal(3, tarrifs_length)
|
181
|
-
end
|
182
|
-
|
183
|
-
def test_has_many_through_2
|
184
|
-
assert_equal(3, Article.count)
|
185
|
-
user = users(:santiago)
|
186
|
-
article_names = user.articles.map(&:name).sort
|
187
|
-
assert_equal(['Article One', 'Article Two'], article_names)
|
188
|
-
end
|
189
|
-
|
190
|
-
def test_new_style_includes_with_conditions
|
191
|
-
product_tariff = ProductTariff.includes(:tariff).where('tariffs.amount < 5').references(:tariffs).first
|
192
|
-
assert_equal(0, product_tariff.tariff.amount)
|
193
|
-
end
|
194
|
-
|
195
|
-
def test_find_product_includes
|
196
|
-
products = Product.includes(:product_tariffs => :tariff)
|
197
|
-
assert_equal(3, products.length)
|
198
|
-
|
199
|
-
product_tariffs_length = products.inject(0) {|sum, product| sum + product.product_tariffs.length}
|
200
|
-
assert_equal(3, product_tariffs_length)
|
201
|
-
end
|
202
|
-
|
203
|
-
def test_has_many_through_when_not_pre_loaded
|
204
|
-
student = Student.first
|
205
|
-
rooms = student.rooms
|
206
|
-
assert_equal(1, rooms.size)
|
207
|
-
assert_equal(1, rooms.first.dorm_id)
|
208
|
-
assert_equal(1, rooms.first.room_id)
|
209
|
-
end
|
210
|
-
|
211
|
-
def test_has_many_through_when_through_association_is_composite
|
212
|
-
dorm = Dorm.first
|
213
|
-
assert_equal(3, dorm.rooms.length)
|
214
|
-
assert_equal(1, dorm.rooms.first.room_attributes.length)
|
215
|
-
assert_equal('type', dorm.rooms.first.room_attributes.first.name)
|
216
|
-
end
|
217
|
-
|
218
|
-
def test_associations_with_conditions
|
219
|
-
suburb = Suburb.find([2, 2])
|
220
|
-
assert_equal 2, suburb.streets.size
|
221
|
-
assert_equal 1, suburb.first_streets.size
|
222
|
-
end
|
223
|
-
|
224
|
-
def test_composite_has_many_composites
|
225
|
-
room = rooms(:branner_room_1)
|
226
|
-
assert_equal(2, room.room_assignments.length)
|
227
|
-
assert_equal(room_assignments(:jacksons_room), room.room_assignments[0])
|
228
|
-
assert_equal(room_assignments(:bobs_room), room.room_assignments[1])
|
229
|
-
end
|
230
|
-
|
231
|
-
def test_composite_belongs_to_composite
|
232
|
-
room_assignment = room_assignments(:jacksons_room)
|
233
|
-
assert_equal(rooms(:branner_room_1), room_assignment.room)
|
234
|
-
end
|
235
|
-
|
236
|
-
def test_composite_belongs_to_changes
|
237
|
-
room_assignment = room_assignments(:jacksons_room)
|
238
|
-
room_assignment.room = rooms(:branner_room_2)
|
239
|
-
# This was raising an error before:
|
240
|
-
# TypeError: [:dorm_id, :room_id] is not a symbol
|
241
|
-
# changes returns HashWithIndifferentAccess
|
242
|
-
assert_equal({"room_id"=>[1, 2]}, room_assignment.changes)
|
243
|
-
|
244
|
-
steve = employees(:steve)
|
245
|
-
steve.department = departments(:engineering)
|
246
|
-
# It was returning this before:
|
247
|
-
# {"[:id, :location_id]"=>[nil, [2, 1]]}
|
248
|
-
assert_equal({"department_id"=>[1, 2]}, steve.changes)
|
249
|
-
end
|
250
|
-
|
251
|
-
def test_composite_belongs_to_setting_to_nil
|
252
|
-
room_assignment = room_assignments(:jacksons_room)
|
253
|
-
# This was raising an error before:
|
254
|
-
# NoMethodError: undefined method `length' for nil:NilClass
|
255
|
-
assert_nothing_raised { room_assignment.room = nil }
|
256
|
-
end
|
257
|
-
|
258
|
-
def test_has_one_with_composite
|
259
|
-
# In this case a regular model has_one composite model
|
260
|
-
department = departments(:engineering)
|
261
|
-
assert_not_nil(department.head)
|
262
|
-
end
|
263
|
-
|
264
|
-
def test_has_many_build_simple_key
|
265
|
-
user = users(:santiago)
|
266
|
-
reading = user.readings.build
|
267
|
-
assert_equal user.id, reading.user_id
|
268
|
-
assert_equal user, reading.user
|
269
|
-
end
|
270
|
-
|
271
|
-
def test_has_many_build_composite_key
|
272
|
-
department = departments(:engineering)
|
273
|
-
employee = department.employees.build
|
274
|
-
assert_equal(department[:id], employee.department_id)
|
275
|
-
assert_equal(department.location_id, employee.location_id)
|
276
|
-
assert_equal(department, employee.department)
|
277
|
-
end
|
278
|
-
|
279
|
-
def test_has_many_with_primary_key
|
280
|
-
@membership = Membership.find([1, 1])
|
281
|
-
assert_equal 2, @membership.readings.size
|
282
|
-
end
|
283
|
-
|
284
|
-
def test_has_many_with_composite_key
|
285
|
-
# In this case a regular model (Dorm) has_many composite models (Rooms)
|
286
|
-
dorm = dorms(:branner)
|
287
|
-
assert_equal(3, dorm.rooms.length)
|
288
|
-
assert_equal(1, dorm.rooms[0].room_id)
|
289
|
-
assert_equal(2, dorm.rooms[1].room_id)
|
290
|
-
assert_equal(3, dorm.rooms[2].room_id)
|
291
|
-
end
|
292
|
-
|
293
|
-
def test_has_many_with_foreign_composite_key
|
294
|
-
tariff = Tariff.find_by('tariff_id = ?', 2)
|
295
|
-
assert_equal(2, tariff.product_tariffs.length)
|
296
|
-
end
|
297
|
-
|
298
|
-
def test_joins_has_many_with_primary_key
|
299
|
-
#@membership = Membership.find(:first, :joins => :readings, :conditions => { :readings => { :id => 1 } })
|
300
|
-
@membership = Membership.joins(:readings).where(readings: { id: 1 }).first
|
301
|
-
|
302
|
-
assert_equal [1, 1], @membership.id
|
303
|
-
end
|
304
|
-
|
305
|
-
def test_joins_has_one_with_primary_key
|
306
|
-
@membership = Membership.joins(:readings).where(readings: { id: 2 }).first
|
307
|
-
|
308
|
-
assert_equal [1, 1], @membership.id
|
309
|
-
end
|
310
|
-
|
311
|
-
def test_has_many_through_with_conditions_when_through_association_is_not_composite
|
312
|
-
user = User.first
|
313
|
-
assert_equal 1, user.articles.where("articles.name = ?", "Article One").size
|
314
|
-
end
|
315
|
-
|
316
|
-
def test_has_many_through_with_conditions_when_through_association_is_composite
|
317
|
-
room = Room.first
|
318
|
-
assert_equal 0, room.room_attributes.where("room_attributes.name != ?", "type").size
|
319
|
-
end
|
320
|
-
|
321
|
-
def test_has_many_through_on_custom_finder_when_through_association_is_composite_finder_when_through_association_is_not_composite
|
322
|
-
user = User.first
|
323
|
-
assert_equal(1, user.find_custom_articles.size)
|
324
|
-
end
|
325
|
-
|
326
|
-
def test_has_many_through_on_custom_finder_when_through_association_is_composite
|
327
|
-
room = Room.first
|
328
|
-
assert_equal(0, room.find_custom_room_attributes.size)
|
329
|
-
end
|
330
|
-
|
331
|
-
def test_has_many_with_primary_key_with_associations
|
332
|
-
memberships = Membership.includes(:statuses).where("membership_statuses.status = ?", 'Active').references(:membership_statuses)
|
333
|
-
assert_equal(2, memberships.length)
|
334
|
-
assert_equal([1,1], memberships[0].id)
|
335
|
-
assert_equal([3,2], memberships[1].id)
|
336
|
-
end
|
337
|
-
|
338
|
-
def test_limitable_reflections
|
339
|
-
memberships = Membership.includes(:statuses).where("membership_statuses.status = ?", 'Active').references(:membership_statuses)
|
340
|
-
assert_equal(2, memberships.length)
|
341
|
-
|
342
|
-
assert_equal([1,1], memberships[0].id)
|
343
|
-
assert_equal([3,2], memberships[1].id)
|
344
|
-
end
|
345
|
-
|
346
|
-
def test_foreign_key_present_with_null_association_ids
|
347
|
-
group = Group.new
|
348
|
-
group.memberships.build
|
349
|
-
associations = group.association(:memberships)
|
350
|
-
assert_equal(false, associations.send('foreign_key_present?'))
|
351
|
-
end
|
352
|
-
|
353
|
-
def test_ids_equals_for_non_CPK_case
|
354
|
-
article = Article.new
|
355
|
-
article.reading_ids = Reading.pluck(:id)
|
356
|
-
assert_equal article.reading_ids, Reading.pluck(:id)
|
357
|
-
end
|
358
|
-
|
1
|
+
require File.expand_path('../abstract_unit', __FILE__)
|
2
|
+
|
3
|
+
class TestAssociations < ActiveSupport::TestCase
|
4
|
+
fixtures :articles, :products, :tariffs, :product_tariffs, :suburbs, :streets, :restaurants,
|
5
|
+
:dorms, :rooms, :room_attributes, :room_attribute_assignments, :students, :room_assignments, :users, :readings,
|
6
|
+
:departments, :employees, :memberships, :membership_statuses
|
7
|
+
|
8
|
+
def test_products
|
9
|
+
assert_not_nil products(:first_product).product_tariffs
|
10
|
+
assert_equal 2, products(:first_product).product_tariffs.length
|
11
|
+
assert_not_nil products(:first_product).tariffs
|
12
|
+
assert_equal 2, products(:first_product).tariffs.length
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_product_tariffs
|
16
|
+
assert_not_nil product_tariffs(:first_flat).product
|
17
|
+
assert_not_nil product_tariffs(:first_flat).tariff
|
18
|
+
assert_equal Product, product_tariffs(:first_flat).product.class
|
19
|
+
assert_equal Tariff, product_tariffs(:first_flat).tariff.class
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_tariffs
|
23
|
+
assert_not_nil tariffs(:flat).product_tariffs
|
24
|
+
assert_equal 1, tariffs(:flat).product_tariffs.length
|
25
|
+
assert_not_nil tariffs(:flat).products
|
26
|
+
assert_equal 1, tariffs(:flat).products.length
|
27
|
+
end
|
28
|
+
|
29
|
+
# Its not generating the instances of associated classes from the rows
|
30
|
+
def test_find_includes
|
31
|
+
products = Product.includes(:product_tariffs)
|
32
|
+
assert_equal(3, products.length)
|
33
|
+
assert_equal(3, products.inject(0) {|sum, product| sum + product.product_tariffs.length})
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_find_includes_2
|
37
|
+
products = ProductTariff.where(:tariff_id => 2).order('product_id, tariff_id').includes(:tariff)
|
38
|
+
assert_equal(2, products.length)
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_find_includes_eager_loading
|
42
|
+
product = products(:second_product)
|
43
|
+
product_tarrif = product_tariffs(:second_free)
|
44
|
+
|
45
|
+
# First get a legitimate product tarrif
|
46
|
+
products = Product.includes(:product_tariffs).where('product_tariffs.product_id = ?', product.id).references(:product_tariffs)
|
47
|
+
assert_equal(1, products.length)
|
48
|
+
assert_equal(product, products.first)
|
49
|
+
assert_equal([product_tarrif], products.first.product_tariffs)
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_find_eager_loading_none
|
53
|
+
product = products(:third_product)
|
54
|
+
|
55
|
+
products = Product.includes(:product_tariffs).where(:id => product.id).references(:product_tariffs)
|
56
|
+
assert_equal(1, products.length)
|
57
|
+
assert_equal(product, products.first)
|
58
|
+
assert_empty(products.first.product_tariffs)
|
59
|
+
end
|
60
|
+
|
61
|
+
def test_find_includes_tariffs
|
62
|
+
tariffs = Tariff.includes(:product_tariffs)
|
63
|
+
assert_equal(3, tariffs.length)
|
64
|
+
assert_equal(3, tariffs.inject(0) {|sum, tariff| sum + tariff.product_tariffs.length})
|
65
|
+
end
|
66
|
+
|
67
|
+
def test_find_each_does_not_throw_error
|
68
|
+
tariffs = Tariff.includes(:product_tariffs)
|
69
|
+
worked = false
|
70
|
+
tariffs.first.product_tariffs.order(:tariff_id).find_each do |pt|
|
71
|
+
worked = true
|
72
|
+
end
|
73
|
+
assert worked
|
74
|
+
end
|
75
|
+
|
76
|
+
def test_association_with_composite_primary_key_can_be_autosaved
|
77
|
+
room = Room.new(dorm_id: 1000, room_id: 1001)
|
78
|
+
room_assignment = RoomAssignment.new(student_id: 1000)
|
79
|
+
room_assignment.room = room
|
80
|
+
room_assignment.save
|
81
|
+
room_assignment.reload
|
82
|
+
assert_equal(room_assignment.dorm_id, 1000)
|
83
|
+
assert_equal(room_assignment.room_id, 1001)
|
84
|
+
end
|
85
|
+
|
86
|
+
def test_has_one_association_is_not_cached_to_where_it_returns_the_wrong_one
|
87
|
+
engineering = departments(:engineering)
|
88
|
+
engineering_head = engineering.head
|
89
|
+
assert_equal(employees(:sarah), engineering_head)
|
90
|
+
|
91
|
+
accounting = departments(:accounting)
|
92
|
+
accounting_head = accounting.head
|
93
|
+
assert_equal(employees(:steve), accounting_head)
|
94
|
+
|
95
|
+
refute_equal accounting_head, engineering_head
|
96
|
+
end
|
97
|
+
|
98
|
+
def test_has_one_association_primary_key_and_foreign_key_are_present
|
99
|
+
# department = departments(:engineering)
|
100
|
+
# assert_equal(2, department.employees.count)
|
101
|
+
# assert_equal('Sarah', department.employees[0].name)
|
102
|
+
# assert_equal('Robert', department.employees[1].name)
|
103
|
+
# assert_equal('Sarah', department.head.name)
|
104
|
+
|
105
|
+
department = departments(:human_resources)
|
106
|
+
assert_equal(1, department.employees.count)
|
107
|
+
assert_equal('Mindy', department.employees[0].name)
|
108
|
+
assert_equal('Mindy', department.head.name)
|
109
|
+
|
110
|
+
head = department.create_head(name: 'Rick')
|
111
|
+
assert_equal(department, head.department)
|
112
|
+
assert_equal('Rick', department.head.name)
|
113
|
+
|
114
|
+
department.reload
|
115
|
+
assert_equal(1, department.employees.count)
|
116
|
+
end
|
117
|
+
|
118
|
+
def test_has_one_autosave
|
119
|
+
department = departments(:engineering)
|
120
|
+
assert_equal('Sarah', department.head.name)
|
121
|
+
|
122
|
+
department.head.name = 'Sarah1'
|
123
|
+
department.save!
|
124
|
+
assert_equal('Sarah1', department.head.name)
|
125
|
+
end
|
126
|
+
|
127
|
+
def test_has_many_association_is_not_cached_to_where_it_returns_the_wrong_ones
|
128
|
+
engineering = departments(:engineering)
|
129
|
+
engineering_employees = engineering.employees
|
130
|
+
|
131
|
+
accounting = departments(:accounting)
|
132
|
+
accounting_employees = accounting.employees
|
133
|
+
|
134
|
+
refute_equal accounting_employees, engineering_employees
|
135
|
+
end
|
136
|
+
|
137
|
+
def test_has_many_association_primary_key_and_foreign_key_are_present
|
138
|
+
department = departments(:accounting)
|
139
|
+
assert_equal(2, department.employees.count)
|
140
|
+
assert_equal('Steve', department.employees[0].name)
|
141
|
+
assert_equal('Jill', department.employees[1].name)
|
142
|
+
|
143
|
+
department.employees.create(name: 'Rick')
|
144
|
+
|
145
|
+
department.reload
|
146
|
+
assert_equal(3, department.employees.count)
|
147
|
+
employees = department.employees.sort_by(&:name)
|
148
|
+
assert_equal('Jill', employees[0].name)
|
149
|
+
assert_equal('Rick', employees[1].name)
|
150
|
+
assert_equal('Steve', employees[2].name)
|
151
|
+
end
|
152
|
+
|
153
|
+
def test_find_includes_product_tariffs_product
|
154
|
+
# Old style
|
155
|
+
product_tariffs = ProductTariff.includes(:product)
|
156
|
+
assert_not_nil(product_tariffs)
|
157
|
+
assert_equal(3, product_tariffs.length)
|
158
|
+
|
159
|
+
# New style
|
160
|
+
product_tariffs = ProductTariff.includes(:product)
|
161
|
+
assert_not_nil(product_tariffs)
|
162
|
+
assert_equal(3, product_tariffs.length)
|
163
|
+
end
|
164
|
+
|
165
|
+
def test_find_includes_product_tariffs_tariff
|
166
|
+
# Old style
|
167
|
+
product_tariffs = ProductTariff.includes(:tariff)
|
168
|
+
assert_equal(3, product_tariffs.length)
|
169
|
+
|
170
|
+
# New style
|
171
|
+
product_tariffs = ProductTariff.includes(:tariff)
|
172
|
+
assert_equal(3, product_tariffs.length)
|
173
|
+
end
|
174
|
+
|
175
|
+
def test_has_many_through
|
176
|
+
products = Product.includes(:tariffs)
|
177
|
+
assert_equal(3, products.length)
|
178
|
+
|
179
|
+
tarrifs_length = products.inject(0) {|sum, product| sum + product.tariffs.length}
|
180
|
+
assert_equal(3, tarrifs_length)
|
181
|
+
end
|
182
|
+
|
183
|
+
def test_has_many_through_2
|
184
|
+
assert_equal(3, Article.count)
|
185
|
+
user = users(:santiago)
|
186
|
+
article_names = user.articles.map(&:name).sort
|
187
|
+
assert_equal(['Article One', 'Article Two'], article_names)
|
188
|
+
end
|
189
|
+
|
190
|
+
def test_new_style_includes_with_conditions
|
191
|
+
product_tariff = ProductTariff.includes(:tariff).where('tariffs.amount < 5').references(:tariffs).first
|
192
|
+
assert_equal(0, product_tariff.tariff.amount)
|
193
|
+
end
|
194
|
+
|
195
|
+
def test_find_product_includes
|
196
|
+
products = Product.includes(:product_tariffs => :tariff)
|
197
|
+
assert_equal(3, products.length)
|
198
|
+
|
199
|
+
product_tariffs_length = products.inject(0) {|sum, product| sum + product.product_tariffs.length}
|
200
|
+
assert_equal(3, product_tariffs_length)
|
201
|
+
end
|
202
|
+
|
203
|
+
def test_has_many_through_when_not_pre_loaded
|
204
|
+
student = Student.first
|
205
|
+
rooms = student.rooms
|
206
|
+
assert_equal(1, rooms.size)
|
207
|
+
assert_equal(1, rooms.first.dorm_id)
|
208
|
+
assert_equal(1, rooms.first.room_id)
|
209
|
+
end
|
210
|
+
|
211
|
+
def test_has_many_through_when_through_association_is_composite
|
212
|
+
dorm = Dorm.first
|
213
|
+
assert_equal(3, dorm.rooms.length)
|
214
|
+
assert_equal(1, dorm.rooms.first.room_attributes.length)
|
215
|
+
assert_equal('type', dorm.rooms.first.room_attributes.first.name)
|
216
|
+
end
|
217
|
+
|
218
|
+
def test_associations_with_conditions
|
219
|
+
suburb = Suburb.find([2, 2])
|
220
|
+
assert_equal 2, suburb.streets.size
|
221
|
+
assert_equal 1, suburb.first_streets.size
|
222
|
+
end
|
223
|
+
|
224
|
+
def test_composite_has_many_composites
|
225
|
+
room = rooms(:branner_room_1)
|
226
|
+
assert_equal(2, room.room_assignments.length)
|
227
|
+
assert_equal(room_assignments(:jacksons_room), room.room_assignments[0])
|
228
|
+
assert_equal(room_assignments(:bobs_room), room.room_assignments[1])
|
229
|
+
end
|
230
|
+
|
231
|
+
def test_composite_belongs_to_composite
|
232
|
+
room_assignment = room_assignments(:jacksons_room)
|
233
|
+
assert_equal(rooms(:branner_room_1), room_assignment.room)
|
234
|
+
end
|
235
|
+
|
236
|
+
def test_composite_belongs_to_changes
|
237
|
+
room_assignment = room_assignments(:jacksons_room)
|
238
|
+
room_assignment.room = rooms(:branner_room_2)
|
239
|
+
# This was raising an error before:
|
240
|
+
# TypeError: [:dorm_id, :room_id] is not a symbol
|
241
|
+
# changes returns HashWithIndifferentAccess
|
242
|
+
assert_equal({"room_id"=>[1, 2]}, room_assignment.changes)
|
243
|
+
|
244
|
+
steve = employees(:steve)
|
245
|
+
steve.department = departments(:engineering)
|
246
|
+
# It was returning this before:
|
247
|
+
# {"[:id, :location_id]"=>[nil, [2, 1]]}
|
248
|
+
assert_equal({"department_id"=>[1, 2]}, steve.changes)
|
249
|
+
end
|
250
|
+
|
251
|
+
def test_composite_belongs_to_setting_to_nil
|
252
|
+
room_assignment = room_assignments(:jacksons_room)
|
253
|
+
# This was raising an error before:
|
254
|
+
# NoMethodError: undefined method `length' for nil:NilClass
|
255
|
+
assert_nothing_raised { room_assignment.room = nil }
|
256
|
+
end
|
257
|
+
|
258
|
+
def test_has_one_with_composite
|
259
|
+
# In this case a regular model has_one composite model
|
260
|
+
department = departments(:engineering)
|
261
|
+
assert_not_nil(department.head)
|
262
|
+
end
|
263
|
+
|
264
|
+
def test_has_many_build_simple_key
|
265
|
+
user = users(:santiago)
|
266
|
+
reading = user.readings.build
|
267
|
+
assert_equal user.id, reading.user_id
|
268
|
+
assert_equal user, reading.user
|
269
|
+
end
|
270
|
+
|
271
|
+
def test_has_many_build_composite_key
|
272
|
+
department = departments(:engineering)
|
273
|
+
employee = department.employees.build
|
274
|
+
assert_equal(department[:id], employee.department_id)
|
275
|
+
assert_equal(department.location_id, employee.location_id)
|
276
|
+
assert_equal(department, employee.department)
|
277
|
+
end
|
278
|
+
|
279
|
+
def test_has_many_with_primary_key
|
280
|
+
@membership = Membership.find([1, 1])
|
281
|
+
assert_equal 2, @membership.readings.size
|
282
|
+
end
|
283
|
+
|
284
|
+
def test_has_many_with_composite_key
|
285
|
+
# In this case a regular model (Dorm) has_many composite models (Rooms)
|
286
|
+
dorm = dorms(:branner)
|
287
|
+
assert_equal(3, dorm.rooms.length)
|
288
|
+
assert_equal(1, dorm.rooms[0].room_id)
|
289
|
+
assert_equal(2, dorm.rooms[1].room_id)
|
290
|
+
assert_equal(3, dorm.rooms[2].room_id)
|
291
|
+
end
|
292
|
+
|
293
|
+
def test_has_many_with_foreign_composite_key
|
294
|
+
tariff = Tariff.find_by('tariff_id = ?', 2)
|
295
|
+
assert_equal(2, tariff.product_tariffs.length)
|
296
|
+
end
|
297
|
+
|
298
|
+
def test_joins_has_many_with_primary_key
|
299
|
+
#@membership = Membership.find(:first, :joins => :readings, :conditions => { :readings => { :id => 1 } })
|
300
|
+
@membership = Membership.joins(:readings).where(readings: { id: 1 }).first
|
301
|
+
|
302
|
+
assert_equal [1, 1], @membership.id
|
303
|
+
end
|
304
|
+
|
305
|
+
def test_joins_has_one_with_primary_key
|
306
|
+
@membership = Membership.joins(:readings).where(readings: { id: 2 }).first
|
307
|
+
|
308
|
+
assert_equal [1, 1], @membership.id
|
309
|
+
end
|
310
|
+
|
311
|
+
def test_has_many_through_with_conditions_when_through_association_is_not_composite
|
312
|
+
user = User.first
|
313
|
+
assert_equal 1, user.articles.where("articles.name = ?", "Article One").size
|
314
|
+
end
|
315
|
+
|
316
|
+
def test_has_many_through_with_conditions_when_through_association_is_composite
|
317
|
+
room = Room.first
|
318
|
+
assert_equal 0, room.room_attributes.where("room_attributes.name != ?", "type").size
|
319
|
+
end
|
320
|
+
|
321
|
+
def test_has_many_through_on_custom_finder_when_through_association_is_composite_finder_when_through_association_is_not_composite
|
322
|
+
user = User.first
|
323
|
+
assert_equal(1, user.find_custom_articles.size)
|
324
|
+
end
|
325
|
+
|
326
|
+
def test_has_many_through_on_custom_finder_when_through_association_is_composite
|
327
|
+
room = Room.first
|
328
|
+
assert_equal(0, room.find_custom_room_attributes.size)
|
329
|
+
end
|
330
|
+
|
331
|
+
def test_has_many_with_primary_key_with_associations
|
332
|
+
memberships = Membership.includes(:statuses).where("membership_statuses.status = ?", 'Active').references(:membership_statuses)
|
333
|
+
assert_equal(2, memberships.length)
|
334
|
+
assert_equal([1,1], memberships[0].id)
|
335
|
+
assert_equal([3,2], memberships[1].id)
|
336
|
+
end
|
337
|
+
|
338
|
+
def test_limitable_reflections
|
339
|
+
memberships = Membership.includes(:statuses).where("membership_statuses.status = ?", 'Active').references(:membership_statuses)
|
340
|
+
assert_equal(2, memberships.length)
|
341
|
+
|
342
|
+
assert_equal([1,1], memberships[0].id)
|
343
|
+
assert_equal([3,2], memberships[1].id)
|
344
|
+
end
|
345
|
+
|
346
|
+
def test_foreign_key_present_with_null_association_ids
|
347
|
+
group = Group.new
|
348
|
+
group.memberships.build
|
349
|
+
associations = group.association(:memberships)
|
350
|
+
assert_equal(false, associations.send('foreign_key_present?'))
|
351
|
+
end
|
352
|
+
|
353
|
+
def test_ids_equals_for_non_CPK_case
|
354
|
+
article = Article.new
|
355
|
+
article.reading_ids = Reading.pluck(:id)
|
356
|
+
assert_equal article.reading_ids, Reading.pluck(:id)
|
357
|
+
end
|
358
|
+
|
359
|
+
def test_find_by_association
|
360
|
+
assert_equal Membership.where(user: '1').count, 1
|
361
|
+
assert_equal Membership.where(user_id: '1').count, 1
|
362
|
+
assert_equal Membership.where(user: User.find(1)).count, 1
|
363
|
+
end
|
364
|
+
end
|