@@ -1076,6 +1076,322 @@ class D
1076
1076
expect ( criteria ) . to eq ( [ person ] )
1077
1077
end
1078
1078
end
1079
+
1080
+ context "when including nested referenced associations" do
1081
+
1082
+ context "when using a has_one association" do
1083
+ before ( :all ) do
1084
+ class A
1085
+ include Mongoid ::Document
1086
+ has_one :b
1087
+ end
1088
+
1089
+ class B
1090
+ include Mongoid ::Document
1091
+ belongs_to :a
1092
+ has_one :c
1093
+ end
1094
+
1095
+ class C
1096
+ include Mongoid ::Document
1097
+ belongs_to :b
1098
+ has_one :d
1099
+ end
1100
+
1101
+ class D
1102
+ include Mongoid ::Document
1103
+ belongs_to :c
1104
+ end
1105
+ end
1106
+
1107
+ after ( :all ) do
1108
+ Object . send ( :remove_const , :A )
1109
+ Object . send ( :remove_const , :B )
1110
+ Object . send ( :remove_const , :C )
1111
+ Object . send ( :remove_const , :D )
1112
+ end
1113
+
1114
+ let! ( :a ) do
1115
+ A . create!
1116
+ end
1117
+
1118
+ let! ( :b ) do
1119
+ B . create!
1120
+ end
1121
+
1122
+ let! ( :c ) do
1123
+ C . create!
1124
+ end
1125
+
1126
+ let! ( :d ) do
1127
+ D . create!
1128
+ end
1129
+
1130
+ before do
1131
+ c . d = d
1132
+ b . c = c
1133
+ a . b = b
1134
+ end
1135
+
1136
+ context "when including the belongs_to assocation" do
1137
+ let! ( :result ) do
1138
+ C . includes ( b : :a ) . first
1139
+ end
1140
+
1141
+ it "finds the right document" do
1142
+ expect ( result ) . to eq ( c )
1143
+ expect ( result . b ) . to eq ( c . b )
1144
+ expect ( result . b . a ) . to eq ( c . b . a )
1145
+ end
1146
+
1147
+ it "does not execute a query" do
1148
+ expect_no_queries do
1149
+ result . b . a
1150
+ end
1151
+ end
1152
+ end
1153
+
1154
+ context "when including a doubly-nested belongs_to assocation" do
1155
+ let! ( :result ) do
1156
+ D . includes ( c : { b : :a } ) . first
1157
+ end
1158
+
1159
+ it "finds the right document" do
1160
+ expect ( result ) . to eq ( d )
1161
+ expect ( result . c ) . to eq ( d . c )
1162
+ expect ( result . c . b ) . to eq ( d . c . b )
1163
+ expect ( result . c . b . a ) . to eq ( d . c . b . a )
1164
+ end
1165
+
1166
+ it "does not execute a query" do
1167
+ expect_no_queries do
1168
+ result . c . b . a
1169
+ end
1170
+ end
1171
+ end
1172
+
1173
+ context "when including the has_many assocation" do
1174
+ let! ( :result ) do
1175
+ A . includes ( b : :c ) . first
1176
+ end
1177
+
1178
+ it "finds the right document" do
1179
+ expect ( result ) . to eq ( a )
1180
+ expect ( result . b ) . to eq ( a . b )
1181
+ expect ( result . b . c ) . to eq ( a . b . c )
1182
+ end
1183
+
1184
+ it "does not executes a query" do
1185
+ expect_no_queries do
1186
+ result . b . c
1187
+ end
1188
+ end
1189
+ end
1190
+
1191
+ context "when including a doubly-nested has_many assocation" do
1192
+ let! ( :result ) do
1193
+ A . includes ( b : { c : :d } ) . first
1194
+ end
1195
+
1196
+ it "finds the right document" do
1197
+ expect ( result ) . to eq ( a )
1198
+ expect ( result . b ) . to eq ( a . b )
1199
+ expect ( result . b . c ) . to eq ( a . b . c )
1200
+ expect ( result . b . c . d ) . to eq ( a . b . c . d )
1201
+ end
1202
+
1203
+ it "does not execute a query" do
1204
+ expect_no_queries do
1205
+ result . b . c . d
1206
+ end
1207
+ end
1208
+ end
1209
+
1210
+ context "when there are multiple documents" do
1211
+ let! ( :as ) do
1212
+ res = 9 . times . map do |i |
1213
+ A . create! . tap do |a |
1214
+ a . b = B . create! . tap do |b |
1215
+ b . c = C . create!
1216
+ end
1217
+ end
1218
+ end
1219
+ [ a , *res ]
1220
+ end
1221
+
1222
+ let! ( :results ) do
1223
+ A . includes ( b : :c ) . entries . sort
1224
+ end
1225
+
1226
+ it "finds the right document" do
1227
+ as . length . times do |i |
1228
+ expect ( as [ i ] ) . to eq ( results [ i ] )
1229
+ expect ( as [ i ] . b ) . to eq ( results [ i ] . b )
1230
+ expect ( as [ i ] . b . c ) . to eq ( results [ i ] . b . c )
1231
+ end
1232
+ end
1233
+
1234
+ it "does not execute a query" do
1235
+ expect_no_queries do
1236
+ results . each do |a |
1237
+ a . b . c
1238
+ end
1239
+ end
1240
+ end
1241
+ end
1242
+
1243
+ context "when there are multiple associations" do
1244
+ before ( :all ) do
1245
+ class A
1246
+ has_one :c
1247
+ end
1248
+
1249
+ class C
1250
+ belongs_to :a
1251
+ end
1252
+ end
1253
+
1254
+ let ( :c2 ) { C . create! }
1255
+ let ( :d2 ) { D . create! }
1256
+
1257
+ before do
1258
+ a . c = c2
1259
+ a . c . d = d2
1260
+ end
1261
+
1262
+ let! ( :results ) do
1263
+ A . includes ( b : { c : :d } , c : :d ) . first
1264
+ end
1265
+
1266
+ it "finds the right document" do
1267
+ expect ( results ) . to eq ( a )
1268
+ expect ( results . b ) . to eq ( a . b )
1269
+ expect ( results . b . c ) . to eq ( a . b . c )
1270
+ expect ( results . b . c . d ) . to eq ( a . b . c . d )
1271
+ expect ( results . c ) . to eq ( a . c )
1272
+ expect ( results . c . d ) . to eq ( a . c . d )
1273
+ end
1274
+
1275
+ it "does not execute a query" do
1276
+ expect_no_queries do
1277
+ results . c . d
1278
+ results . b . c . d
1279
+ end
1280
+ end
1281
+ end
1282
+ end
1283
+ end
1284
+
1285
+ context "when using a has_many association" do
1286
+ before ( :all ) do
1287
+ class IncUser
1288
+ include Mongoid ::Document
1289
+ has_many :posts , class_name : 'IncPost'
1290
+ has_many :comments , class_name : 'IncComment'
1291
+ end
1292
+
1293
+ class IncPost
1294
+ include Mongoid ::Document
1295
+ belongs_to :user , class_name : 'IncUser'
1296
+ has_many :comments , class_name : 'IncComment'
1297
+ end
1298
+
1299
+ class IncComment
1300
+ include Mongoid ::Document
1301
+ belongs_to :posts , class_name : 'IncPost'
1302
+ belongs_to :user , class_name : 'IncUser'
1303
+ belongs_to :thread , class_name : 'IncThread'
1304
+ end
1305
+
1306
+ class IncThread
1307
+ include Mongoid ::Document
1308
+ has_many :comments , class_name : 'IncComment'
1309
+ end
1310
+ end
1311
+
1312
+ after ( :all ) do
1313
+ Object . send ( :remove_const , :IncUser )
1314
+ Object . send ( :remove_const , :IncPost )
1315
+ Object . send ( :remove_const , :IncComment )
1316
+ Object . send ( :remove_const , :IncThread )
1317
+ end
1318
+
1319
+ let! ( :user ) do
1320
+ IncUser . create! ( posts : posts , comments : user_comments )
1321
+ end
1322
+
1323
+ let! ( :posts ) do
1324
+ [ IncPost . create! ( comments : post_comments ) ]
1325
+ end
1326
+
1327
+ let! ( :user_comments ) do
1328
+ 2 . times . map { IncComment . create! }
1329
+ end
1330
+
1331
+ let! ( :post_comments ) do
1332
+ 2 . times . map { IncComment . create! }
1333
+ end
1334
+
1335
+ context "when including the same class twice" do
1336
+ let! ( :results ) do
1337
+ IncPost . includes ( { user : :comments } , :comments ) . entries . sort
1338
+ end
1339
+
1340
+ it "finds the right documents" do
1341
+ posts . length . times do |i |
1342
+ expect ( posts [ i ] ) . to eq ( results [ i ] )
1343
+ expect ( posts [ i ] . user ) . to eq ( results [ i ] . user )
1344
+ expect ( posts [ i ] . user . comments ) . to eq ( results [ i ] . user . comments )
1345
+ expect ( posts [ i ] . comments ) . to eq ( results [ i ] . comments )
1346
+ end
1347
+ end
1348
+
1349
+ it "does not execute a query" do
1350
+ expect_no_queries do
1351
+ results . each do |res |
1352
+ res . user
1353
+ res . user . comments . to_a
1354
+ res . comments . to_a
1355
+ end
1356
+ end
1357
+ end
1358
+ end
1359
+
1360
+ context "when the association chain has a class name twice" do
1361
+ let! ( :thread ) { IncThread . create! ( comments : user_comments ) }
1362
+
1363
+ let! ( :result ) do
1364
+ IncThread . includes ( comments : { user : { posts : :comments } } ) . first
1365
+ end
1366
+
1367
+ it "finds the right document" do
1368
+ expect ( result ) . to eq ( thread )
1369
+ result . comments . length . times do |i |
1370
+ c1 = result . comments [ i ]
1371
+ c2 = thread . comments [ i ]
1372
+ expect ( c1 ) . to eq ( c2 )
1373
+ expect ( c1 . user ) . to eq ( c2 . user )
1374
+ c1 . user . posts . length . times do |i |
1375
+ p1 = c1 . user . posts [ i ]
1376
+ p2 = c2 . user . posts [ i ]
1377
+
1378
+ expect ( p1 ) . to eq ( p2 )
1379
+ expect ( p1 . comments ) . to eq ( p2 . comments )
1380
+ end
1381
+ end
1382
+ end
1383
+
1384
+ it "does not execute a query" do
1385
+ expect_no_queries do
1386
+ result . comments . each do |comment |
1387
+ comment . user . posts . each do |post |
1388
+ post . comments . to_a
1389
+ end
1390
+ end
1391
+ end
1392
+ end
1393
+ end
1394
+ end
1079
1395
end
1080
1396
1081
1397
describe "#inclusions" do
0 commit comments