mongoid 9.1.1 → 9.1.2
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/lib/config/locales/en.yml +31 -11
- data/lib/mongoid/association/accessors.rb +18 -4
- data/lib/mongoid/association/eager_load/discriminated_inclusion.rb +10 -10
- data/lib/mongoid/association/eager_load/embedded_distributor.rb +6 -6
- data/lib/mongoid/association/eager_load/lookup_pipeline.rb +1 -1
- data/lib/mongoid/association/eager_loadable.rb +8 -1
- data/lib/mongoid/association/embedded/batchable.rb +17 -1
- data/lib/mongoid/association/nested/many.rb +1 -1
- data/lib/mongoid/association/referenced/has_and_belongs_to_many/buildable.rb +6 -0
- data/lib/mongoid/association/relatable.rb +18 -0
- data/lib/mongoid/association.rb +8 -0
- data/lib/mongoid/atomic/modifiers.rb +100 -16
- data/lib/mongoid/clients/factory.rb +2 -0
- data/lib/mongoid/config/encryption.rb +148 -17
- data/lib/mongoid/document.rb +3 -0
- data/lib/mongoid/encryptable.rb +42 -15
- data/lib/mongoid/errors/invalid_encryption_schema.rb +27 -0
- data/lib/mongoid/errors/no_encryption_schema.rb +5 -3
- data/lib/mongoid/errors.rb +1 -0
- data/lib/mongoid/fields.rb +7 -0
- data/lib/mongoid/persistable/creatable.rb +120 -14
- data/lib/mongoid/persistable.rb +15 -15
- data/lib/mongoid/persistence_context.rb +46 -4
- data/lib/mongoid/search_indexable.rb +5 -1
- data/lib/mongoid/tasks/database.rb +10 -7
- data/lib/mongoid/touchable.rb +28 -1
- data/lib/mongoid/version.rb +1 -1
- data/lib/mongoid/warnings.rb +4 -0
- data/spec/integration/associations/embedded_delayed_atomic_sets_spec.rb +216 -0
- data/spec/integration/associations/has_and_belongs_to_many_spec.rb +14 -0
- data/spec/integration/atomic/modifiers_spec.rb +283 -0
- data/spec/integration/encryption_spec.rb +149 -0
- data/spec/mongoid/association/accessors_spec.rb +35 -0
- data/spec/mongoid/association/referenced/has_and_belongs_to_many/buildable_spec.rb +11 -0
- data/spec/mongoid/atomic/modifiers_spec.rb +347 -0
- data/spec/mongoid/attributes/nested_spec.rb +29 -0
- data/spec/mongoid/clients/factory_spec.rb +36 -0
- data/spec/mongoid/config/encryption_spec.rb +223 -0
- data/spec/mongoid/criteria/includable_spec.rb +346 -0
- data/spec/mongoid/encryptable_spec.rb +54 -0
- data/spec/mongoid/fields_spec.rb +8 -0
- data/spec/mongoid/search_indexable_spec.rb +26 -0
- data/spec/mongoid/tasks/database_spec.rb +13 -0
- data/spec/mongoid/touchable_spec.rb +217 -0
- data/spec/mongoid/touchable_spec_models.rb +37 -0
- data/spec/support/crypt/models.rb +96 -0
- data/spec/support/models/modifier_models.rb +65 -0
- metadata +5 -2
|
@@ -126,8 +126,11 @@ describe Mongoid::Criteria::Includable do
|
|
|
126
126
|
end
|
|
127
127
|
|
|
128
128
|
after(:all) do
|
|
129
|
+
Mongoid.deregister_model(A)
|
|
129
130
|
Object.send(:remove_const, :A)
|
|
131
|
+
Mongoid.deregister_model(B)
|
|
130
132
|
Object.send(:remove_const, :B)
|
|
133
|
+
Mongoid.deregister_model(C)
|
|
131
134
|
Object.send(:remove_const, :C)
|
|
132
135
|
end
|
|
133
136
|
|
|
@@ -186,9 +189,13 @@ describe Mongoid::Criteria::Includable do
|
|
|
186
189
|
end
|
|
187
190
|
|
|
188
191
|
after(:all) do
|
|
192
|
+
Mongoid.deregister_model(A)
|
|
189
193
|
Object.send(:remove_const, :A)
|
|
194
|
+
Mongoid.deregister_model(B)
|
|
190
195
|
Object.send(:remove_const, :B)
|
|
196
|
+
Mongoid.deregister_model(C)
|
|
191
197
|
Object.send(:remove_const, :C)
|
|
198
|
+
Mongoid.deregister_model(D)
|
|
192
199
|
Object.send(:remove_const, :D)
|
|
193
200
|
end
|
|
194
201
|
|
|
@@ -255,9 +262,13 @@ describe Mongoid::Criteria::Includable do
|
|
|
255
262
|
end
|
|
256
263
|
|
|
257
264
|
after(:all) do
|
|
265
|
+
Mongoid.deregister_model(A)
|
|
258
266
|
Object.send(:remove_const, :A)
|
|
267
|
+
Mongoid.deregister_model(B)
|
|
259
268
|
Object.send(:remove_const, :B)
|
|
269
|
+
Mongoid.deregister_model(C)
|
|
260
270
|
Object.send(:remove_const, :C)
|
|
271
|
+
Mongoid.deregister_model(D)
|
|
261
272
|
Object.send(:remove_const, :D)
|
|
262
273
|
end
|
|
263
274
|
|
|
@@ -1121,9 +1132,13 @@ describe Mongoid::Criteria::Includable do
|
|
|
1121
1132
|
end
|
|
1122
1133
|
|
|
1123
1134
|
after(:all) do
|
|
1135
|
+
Mongoid.deregister_model(A)
|
|
1124
1136
|
Object.send(:remove_const, :A)
|
|
1137
|
+
Mongoid.deregister_model(B)
|
|
1125
1138
|
Object.send(:remove_const, :B)
|
|
1139
|
+
Mongoid.deregister_model(C)
|
|
1126
1140
|
Object.send(:remove_const, :C)
|
|
1141
|
+
Mongoid.deregister_model(D)
|
|
1127
1142
|
Object.send(:remove_const, :D)
|
|
1128
1143
|
end
|
|
1129
1144
|
|
|
@@ -1408,6 +1423,106 @@ describe Mongoid::Criteria::Includable do
|
|
|
1408
1423
|
|
|
1409
1424
|
describe '#includes' do
|
|
1410
1425
|
it_behaves_like 'eager loading', :includes
|
|
1426
|
+
|
|
1427
|
+
context 'when a nested association sits behind a parent whose class_name is not the resolved class name' do
|
|
1428
|
+
before(:all) do
|
|
1429
|
+
class IncEagerGallery
|
|
1430
|
+
include Mongoid::Document
|
|
1431
|
+
|
|
1432
|
+
has_many :rooted_photos, class_name: '::IncEagerPhoto', inverse_of: :gallery
|
|
1433
|
+
end
|
|
1434
|
+
|
|
1435
|
+
class IncEagerPhoto
|
|
1436
|
+
include Mongoid::Document
|
|
1437
|
+
|
|
1438
|
+
belongs_to :gallery, class_name: 'IncEagerGallery', inverse_of: :rooted_photos
|
|
1439
|
+
belongs_to :author, class_name: '::IncEagerAuthor'
|
|
1440
|
+
end
|
|
1441
|
+
|
|
1442
|
+
class IncEagerAuthor
|
|
1443
|
+
include Mongoid::Document
|
|
1444
|
+
end
|
|
1445
|
+
|
|
1446
|
+
module IncEagerShop
|
|
1447
|
+
class Order
|
|
1448
|
+
include Mongoid::Document
|
|
1449
|
+
|
|
1450
|
+
has_many :items, class_name: 'Item', inverse_of: :order
|
|
1451
|
+
end
|
|
1452
|
+
|
|
1453
|
+
class Item
|
|
1454
|
+
include Mongoid::Document
|
|
1455
|
+
|
|
1456
|
+
belongs_to :order, class_name: 'Order', inverse_of: :items
|
|
1457
|
+
belongs_to :author, class_name: '::IncEagerAuthor'
|
|
1458
|
+
end
|
|
1459
|
+
end
|
|
1460
|
+
|
|
1461
|
+
class IncEagerAlbum
|
|
1462
|
+
include Mongoid::Document
|
|
1463
|
+
|
|
1464
|
+
has_many :poly_photos, class_name: '::IncEagerPolyPhoto', as: :imageable, inverse_of: :imageable
|
|
1465
|
+
end
|
|
1466
|
+
|
|
1467
|
+
class IncEagerPolyPhoto
|
|
1468
|
+
include Mongoid::Document
|
|
1469
|
+
|
|
1470
|
+
belongs_to :imageable, polymorphic: true, inverse_of: :poly_photos
|
|
1471
|
+
belongs_to :author, class_name: '::IncEagerAuthor'
|
|
1472
|
+
end
|
|
1473
|
+
end
|
|
1474
|
+
|
|
1475
|
+
after(:all) do
|
|
1476
|
+
Mongoid.deregister_model(IncEagerAlbum)
|
|
1477
|
+
Object.send(:remove_const, :IncEagerAlbum)
|
|
1478
|
+
Mongoid.deregister_model(IncEagerPolyPhoto)
|
|
1479
|
+
Object.send(:remove_const, :IncEagerPolyPhoto)
|
|
1480
|
+
Mongoid.deregister_model(IncEagerShop::Order)
|
|
1481
|
+
Mongoid.deregister_model(IncEagerShop::Item)
|
|
1482
|
+
Object.send(:remove_const, :IncEagerShop)
|
|
1483
|
+
Mongoid.deregister_model(IncEagerAuthor)
|
|
1484
|
+
Object.send(:remove_const, :IncEagerAuthor)
|
|
1485
|
+
Mongoid.deregister_model(IncEagerPhoto)
|
|
1486
|
+
Object.send(:remove_const, :IncEagerPhoto)
|
|
1487
|
+
Mongoid.deregister_model(IncEagerGallery)
|
|
1488
|
+
Object.send(:remove_const, :IncEagerGallery)
|
|
1489
|
+
end
|
|
1490
|
+
|
|
1491
|
+
let!(:gallery) { IncEagerGallery.create! }
|
|
1492
|
+
let!(:order) { IncEagerShop::Order.create! }
|
|
1493
|
+
|
|
1494
|
+
before do
|
|
1495
|
+
IncEagerPhoto.create!(gallery: gallery, author: IncEagerAuthor.create!)
|
|
1496
|
+
IncEagerShop::Item.create!(order: order, author: IncEagerAuthor.create!)
|
|
1497
|
+
end
|
|
1498
|
+
|
|
1499
|
+
it 'eager loads a nested association behind a class_name with a leading ::' do
|
|
1500
|
+
result = IncEagerGallery.includes(rooted_photos: :author).first
|
|
1501
|
+
|
|
1502
|
+
expect_query(0) do
|
|
1503
|
+
expect(result.rooted_photos.first.author).to be_a(IncEagerAuthor)
|
|
1504
|
+
end
|
|
1505
|
+
end
|
|
1506
|
+
|
|
1507
|
+
it 'eager loads a nested association behind a module-relative class_name' do
|
|
1508
|
+
result = IncEagerShop::Order.includes(items: :author).first
|
|
1509
|
+
|
|
1510
|
+
expect_query(0) do
|
|
1511
|
+
expect(result.items.first.author).to be_a(IncEagerAuthor)
|
|
1512
|
+
end
|
|
1513
|
+
end
|
|
1514
|
+
|
|
1515
|
+
it 'eager loads a nested association behind a polymorphic parent with a leading ::' do
|
|
1516
|
+
album = IncEagerAlbum.create!
|
|
1517
|
+
IncEagerPolyPhoto.create!(imageable: album, author: IncEagerAuthor.create!)
|
|
1518
|
+
|
|
1519
|
+
result = IncEagerAlbum.includes(poly_photos: :author).first
|
|
1520
|
+
|
|
1521
|
+
expect_query(0) do
|
|
1522
|
+
expect(result.poly_photos.first.author).to be_a(IncEagerAuthor)
|
|
1523
|
+
end
|
|
1524
|
+
end
|
|
1525
|
+
end
|
|
1411
1526
|
end
|
|
1412
1527
|
|
|
1413
1528
|
describe '#eager_load' do
|
|
@@ -1442,9 +1557,13 @@ describe Mongoid::Criteria::Includable do
|
|
|
1442
1557
|
end
|
|
1443
1558
|
|
|
1444
1559
|
after(:all) do
|
|
1560
|
+
Mongoid.deregister_model(Mouse)
|
|
1445
1561
|
Object.send(:remove_const, :Mouse)
|
|
1562
|
+
Mongoid.deregister_model(Webcam)
|
|
1446
1563
|
Object.send(:remove_const, :Webcam)
|
|
1564
|
+
Mongoid.deregister_model(Peripheral)
|
|
1447
1565
|
Object.send(:remove_const, :Peripheral)
|
|
1566
|
+
Mongoid.deregister_model(Machine)
|
|
1448
1567
|
Object.send(:remove_const, :Machine)
|
|
1449
1568
|
end
|
|
1450
1569
|
|
|
@@ -1484,10 +1603,15 @@ describe Mongoid::Criteria::Includable do
|
|
|
1484
1603
|
end
|
|
1485
1604
|
|
|
1486
1605
|
after(:all) do
|
|
1606
|
+
Mongoid.deregister_model(Mouse)
|
|
1487
1607
|
Object.send(:remove_const, :Mouse)
|
|
1608
|
+
Mongoid.deregister_model(Peripheral)
|
|
1488
1609
|
Object.send(:remove_const, :Peripheral)
|
|
1610
|
+
Mongoid.deregister_model(Laptop)
|
|
1489
1611
|
Object.send(:remove_const, :Laptop)
|
|
1612
|
+
Mongoid.deregister_model(Machine)
|
|
1490
1613
|
Object.send(:remove_const, :Machine)
|
|
1614
|
+
Mongoid.deregister_model(Brand)
|
|
1491
1615
|
Object.send(:remove_const, :Brand)
|
|
1492
1616
|
end
|
|
1493
1617
|
|
|
@@ -1522,8 +1646,11 @@ describe Mongoid::Criteria::Includable do
|
|
|
1522
1646
|
end
|
|
1523
1647
|
|
|
1524
1648
|
after(:all) do
|
|
1649
|
+
Mongoid.deregister_model(Cable)
|
|
1525
1650
|
Object.send(:remove_const, :Cable)
|
|
1651
|
+
Mongoid.deregister_model(Speaker)
|
|
1526
1652
|
Object.send(:remove_const, :Speaker)
|
|
1653
|
+
Mongoid.deregister_model(Gadget)
|
|
1527
1654
|
Object.send(:remove_const, :Gadget)
|
|
1528
1655
|
end
|
|
1529
1656
|
|
|
@@ -1556,8 +1683,11 @@ describe Mongoid::Criteria::Includable do
|
|
|
1556
1683
|
end
|
|
1557
1684
|
|
|
1558
1685
|
after(:all) do
|
|
1686
|
+
Mongoid.deregister_model(Cable)
|
|
1559
1687
|
Object.send(:remove_const, :Cable)
|
|
1688
|
+
Mongoid.deregister_model(Speaker)
|
|
1560
1689
|
Object.send(:remove_const, :Speaker)
|
|
1690
|
+
Mongoid.deregister_model(Gadget)
|
|
1561
1691
|
Object.send(:remove_const, :Gadget)
|
|
1562
1692
|
end
|
|
1563
1693
|
|
|
@@ -1590,8 +1720,11 @@ describe Mongoid::Criteria::Includable do
|
|
|
1590
1720
|
end
|
|
1591
1721
|
|
|
1592
1722
|
after(:all) do
|
|
1723
|
+
Mongoid.deregister_model(Speaker)
|
|
1593
1724
|
Object.send(:remove_const, :Speaker)
|
|
1725
|
+
Mongoid.deregister_model(Gadget)
|
|
1594
1726
|
Object.send(:remove_const, :Gadget)
|
|
1727
|
+
Mongoid.deregister_model(Cable)
|
|
1595
1728
|
Object.send(:remove_const, :Cable)
|
|
1596
1729
|
end
|
|
1597
1730
|
|
|
@@ -1627,8 +1760,11 @@ describe Mongoid::Criteria::Includable do
|
|
|
1627
1760
|
end
|
|
1628
1761
|
|
|
1629
1762
|
after(:all) do
|
|
1763
|
+
Mongoid.deregister_model(Computer)
|
|
1630
1764
|
Object.send(:remove_const, :Computer)
|
|
1765
|
+
Mongoid.deregister_model(Port)
|
|
1631
1766
|
Object.send(:remove_const, :Port)
|
|
1767
|
+
Mongoid.deregister_model(Device)
|
|
1632
1768
|
Object.send(:remove_const, :Device)
|
|
1633
1769
|
end
|
|
1634
1770
|
|
|
@@ -1675,8 +1811,11 @@ describe Mongoid::Criteria::Includable do
|
|
|
1675
1811
|
end
|
|
1676
1812
|
|
|
1677
1813
|
after(:all) do
|
|
1814
|
+
Mongoid.deregister_model(Computer)
|
|
1678
1815
|
Object.send(:remove_const, :Computer)
|
|
1816
|
+
Mongoid.deregister_model(Port)
|
|
1679
1817
|
Object.send(:remove_const, :Port)
|
|
1818
|
+
Mongoid.deregister_model(Device)
|
|
1680
1819
|
Object.send(:remove_const, :Device)
|
|
1681
1820
|
end
|
|
1682
1821
|
|
|
@@ -1726,9 +1865,13 @@ describe Mongoid::Criteria::Includable do
|
|
|
1726
1865
|
end
|
|
1727
1866
|
|
|
1728
1867
|
after(:all) do
|
|
1868
|
+
Mongoid.deregister_model(Computer)
|
|
1729
1869
|
Object.send(:remove_const, :Computer)
|
|
1870
|
+
Mongoid.deregister_model(Panel)
|
|
1730
1871
|
Object.send(:remove_const, :Panel)
|
|
1872
|
+
Mongoid.deregister_model(Port)
|
|
1731
1873
|
Object.send(:remove_const, :Port)
|
|
1874
|
+
Mongoid.deregister_model(Device)
|
|
1732
1875
|
Object.send(:remove_const, :Device)
|
|
1733
1876
|
end
|
|
1734
1877
|
|
|
@@ -1767,9 +1910,13 @@ describe Mongoid::Criteria::Includable do
|
|
|
1767
1910
|
end
|
|
1768
1911
|
|
|
1769
1912
|
after(:all) do
|
|
1913
|
+
Mongoid.deregister_model(Computer)
|
|
1770
1914
|
Object.send(:remove_const, :Computer)
|
|
1915
|
+
Mongoid.deregister_model(UsbPort)
|
|
1771
1916
|
Object.send(:remove_const, :UsbPort)
|
|
1917
|
+
Mongoid.deregister_model(Port)
|
|
1772
1918
|
Object.send(:remove_const, :Port)
|
|
1919
|
+
Mongoid.deregister_model(Device)
|
|
1773
1920
|
Object.send(:remove_const, :Device)
|
|
1774
1921
|
end
|
|
1775
1922
|
|
|
@@ -1805,8 +1952,11 @@ describe Mongoid::Criteria::Includable do
|
|
|
1805
1952
|
end
|
|
1806
1953
|
|
|
1807
1954
|
after(:all) do
|
|
1955
|
+
Mongoid.deregister_model(Computer)
|
|
1808
1956
|
Object.send(:remove_const, :Computer)
|
|
1957
|
+
Mongoid.deregister_model(Port)
|
|
1809
1958
|
Object.send(:remove_const, :Port)
|
|
1959
|
+
Mongoid.deregister_model(Device)
|
|
1810
1960
|
Object.send(:remove_const, :Device)
|
|
1811
1961
|
end
|
|
1812
1962
|
|
|
@@ -1843,8 +1993,11 @@ describe Mongoid::Criteria::Includable do
|
|
|
1843
1993
|
end
|
|
1844
1994
|
|
|
1845
1995
|
after(:all) do
|
|
1996
|
+
Mongoid.deregister_model(Computer)
|
|
1846
1997
|
Object.send(:remove_const, :Computer)
|
|
1998
|
+
Mongoid.deregister_model(Port)
|
|
1847
1999
|
Object.send(:remove_const, :Port)
|
|
2000
|
+
Mongoid.deregister_model(Device)
|
|
1848
2001
|
Object.send(:remove_const, :Device)
|
|
1849
2002
|
end
|
|
1850
2003
|
|
|
@@ -1879,8 +2032,11 @@ describe Mongoid::Criteria::Includable do
|
|
|
1879
2032
|
end
|
|
1880
2033
|
|
|
1881
2034
|
after(:all) do
|
|
2035
|
+
Mongoid.deregister_model(Port)
|
|
1882
2036
|
Object.send(:remove_const, :Port)
|
|
2037
|
+
Mongoid.deregister_model(Computer)
|
|
1883
2038
|
Object.send(:remove_const, :Computer)
|
|
2039
|
+
Mongoid.deregister_model(Device)
|
|
1884
2040
|
Object.send(:remove_const, :Device)
|
|
1885
2041
|
end
|
|
1886
2042
|
|
|
@@ -1922,9 +2078,13 @@ describe Mongoid::Criteria::Includable do
|
|
|
1922
2078
|
end
|
|
1923
2079
|
|
|
1924
2080
|
after(:all) do
|
|
2081
|
+
Mongoid.deregister_model(Desk)
|
|
1925
2082
|
Object.send(:remove_const, :Desk)
|
|
2083
|
+
Mongoid.deregister_model(Computer)
|
|
1926
2084
|
Object.send(:remove_const, :Computer)
|
|
2085
|
+
Mongoid.deregister_model(Port)
|
|
1927
2086
|
Object.send(:remove_const, :Port)
|
|
2087
|
+
Mongoid.deregister_model(Device)
|
|
1928
2088
|
Object.send(:remove_const, :Device)
|
|
1929
2089
|
end
|
|
1930
2090
|
|
|
@@ -1974,10 +2134,15 @@ describe Mongoid::Criteria::Includable do
|
|
|
1974
2134
|
end
|
|
1975
2135
|
|
|
1976
2136
|
after(:all) do
|
|
2137
|
+
Mongoid.deregister_model(Desk)
|
|
1977
2138
|
Object.send(:remove_const, :Desk)
|
|
2139
|
+
Mongoid.deregister_model(Computer)
|
|
1978
2140
|
Object.send(:remove_const, :Computer)
|
|
2141
|
+
Mongoid.deregister_model(Port)
|
|
1979
2142
|
Object.send(:remove_const, :Port)
|
|
2143
|
+
Mongoid.deregister_model(Pin)
|
|
1980
2144
|
Object.send(:remove_const, :Pin)
|
|
2145
|
+
Mongoid.deregister_model(Device)
|
|
1981
2146
|
Object.send(:remove_const, :Device)
|
|
1982
2147
|
end
|
|
1983
2148
|
|
|
@@ -2027,10 +2192,15 @@ describe Mongoid::Criteria::Includable do
|
|
|
2027
2192
|
end
|
|
2028
2193
|
|
|
2029
2194
|
after(:all) do
|
|
2195
|
+
Mongoid.deregister_model(Desk)
|
|
2030
2196
|
Object.send(:remove_const, :Desk)
|
|
2197
|
+
Mongoid.deregister_model(Computer)
|
|
2031
2198
|
Object.send(:remove_const, :Computer)
|
|
2199
|
+
Mongoid.deregister_model(Card)
|
|
2032
2200
|
Object.send(:remove_const, :Card)
|
|
2201
|
+
Mongoid.deregister_model(Port)
|
|
2033
2202
|
Object.send(:remove_const, :Port)
|
|
2203
|
+
Mongoid.deregister_model(Device)
|
|
2034
2204
|
Object.send(:remove_const, :Device)
|
|
2035
2205
|
end
|
|
2036
2206
|
|
|
@@ -2072,8 +2242,11 @@ describe Mongoid::Criteria::Includable do
|
|
|
2072
2242
|
end
|
|
2073
2243
|
|
|
2074
2244
|
after(:all) do
|
|
2245
|
+
Mongoid.deregister_model(Cartridge)
|
|
2075
2246
|
Object.send(:remove_const, :Cartridge)
|
|
2247
|
+
Mongoid.deregister_model(Scanner)
|
|
2076
2248
|
Object.send(:remove_const, :Scanner)
|
|
2249
|
+
Mongoid.deregister_model(Printer)
|
|
2077
2250
|
Object.send(:remove_const, :Printer)
|
|
2078
2251
|
end
|
|
2079
2252
|
|
|
@@ -2111,8 +2284,11 @@ describe Mongoid::Criteria::Includable do
|
|
|
2111
2284
|
end
|
|
2112
2285
|
|
|
2113
2286
|
after(:all) do
|
|
2287
|
+
Mongoid.deregister_model(Accessory)
|
|
2114
2288
|
Object.send(:remove_const, :Accessory)
|
|
2289
|
+
Mongoid.deregister_model(RemoteDevice)
|
|
2115
2290
|
Object.send(:remove_const, :RemoteDevice)
|
|
2291
|
+
Mongoid.deregister_model(LocalDevice)
|
|
2116
2292
|
Object.send(:remove_const, :LocalDevice)
|
|
2117
2293
|
end
|
|
2118
2294
|
|
|
@@ -2155,7 +2331,9 @@ describe Mongoid::Criteria::Includable do
|
|
|
2155
2331
|
end
|
|
2156
2332
|
|
|
2157
2333
|
after(:all) do
|
|
2334
|
+
Mongoid.deregister_model(Workstation)
|
|
2158
2335
|
Object.send(:remove_const, :Workstation)
|
|
2336
|
+
Mongoid.deregister_model(RemoteServer)
|
|
2159
2337
|
Object.send(:remove_const, :RemoteServer)
|
|
2160
2338
|
end
|
|
2161
2339
|
|
|
@@ -2214,11 +2392,17 @@ describe Mongoid::Criteria::Includable do
|
|
|
2214
2392
|
end
|
|
2215
2393
|
|
|
2216
2394
|
after(:all) do
|
|
2395
|
+
Mongoid.deregister_model(Press)
|
|
2217
2396
|
Object.send(:remove_const, :Press)
|
|
2397
|
+
Mongoid.deregister_model(Lathe)
|
|
2218
2398
|
Object.send(:remove_const, :Lathe)
|
|
2399
|
+
Mongoid.deregister_model(Machine)
|
|
2219
2400
|
Object.send(:remove_const, :Machine)
|
|
2401
|
+
Mongoid.deregister_model(Belt)
|
|
2220
2402
|
Object.send(:remove_const, :Belt)
|
|
2403
|
+
Mongoid.deregister_model(Cog)
|
|
2221
2404
|
Object.send(:remove_const, :Cog)
|
|
2405
|
+
Mongoid.deregister_model(Supplier)
|
|
2222
2406
|
Object.send(:remove_const, :Supplier)
|
|
2223
2407
|
end
|
|
2224
2408
|
|
|
@@ -2272,9 +2456,13 @@ describe Mongoid::Criteria::Includable do
|
|
|
2272
2456
|
end
|
|
2273
2457
|
|
|
2274
2458
|
after(:all) do
|
|
2459
|
+
Mongoid.deregister_model(Board)
|
|
2275
2460
|
Object.send(:remove_const, :Board)
|
|
2461
|
+
Mongoid.deregister_model(Cable)
|
|
2276
2462
|
Object.send(:remove_const, :Cable)
|
|
2463
|
+
Mongoid.deregister_model(Chip)
|
|
2277
2464
|
Object.send(:remove_const, :Chip)
|
|
2465
|
+
Mongoid.deregister_model(Part)
|
|
2278
2466
|
Object.send(:remove_const, :Part)
|
|
2279
2467
|
end
|
|
2280
2468
|
|
|
@@ -2289,6 +2477,164 @@ describe Mongoid::Criteria::Includable do
|
|
|
2289
2477
|
end
|
|
2290
2478
|
end
|
|
2291
2479
|
end
|
|
2480
|
+
|
|
2481
|
+
context 'when a document is saved after eager loading' do
|
|
2482
|
+
context 'when the reference lives inside an embedded document' do
|
|
2483
|
+
before(:all) do
|
|
2484
|
+
class Device
|
|
2485
|
+
include Mongoid::Document
|
|
2486
|
+
end
|
|
2487
|
+
|
|
2488
|
+
class Port
|
|
2489
|
+
include Mongoid::Document
|
|
2490
|
+
|
|
2491
|
+
embedded_in :computer
|
|
2492
|
+
belongs_to :device
|
|
2493
|
+
end
|
|
2494
|
+
|
|
2495
|
+
class Computer
|
|
2496
|
+
include Mongoid::Document
|
|
2497
|
+
|
|
2498
|
+
embeds_many :ports
|
|
2499
|
+
end
|
|
2500
|
+
end
|
|
2501
|
+
|
|
2502
|
+
after(:all) do
|
|
2503
|
+
Object.send(:remove_const, :Computer)
|
|
2504
|
+
Object.send(:remove_const, :Port)
|
|
2505
|
+
Object.send(:remove_const, :Device)
|
|
2506
|
+
end
|
|
2507
|
+
|
|
2508
|
+
let!(:device) { Device.create! }
|
|
2509
|
+
let!(:computer) { Computer.create!(ports: [ Port.new(device: device) ]) }
|
|
2510
|
+
|
|
2511
|
+
it 'does not persist the eager-loaded association data' do
|
|
2512
|
+
loaded = Computer.eager_load(ports: :device).first
|
|
2513
|
+
|
|
2514
|
+
# Reassigning the collection makes the save rewrite the whole array,
|
|
2515
|
+
# serializing each already-hydrated port.
|
|
2516
|
+
loaded.ports = loaded.ports.to_a + [ Port.new(device: Device.create!) ]
|
|
2517
|
+
loaded.save!
|
|
2518
|
+
|
|
2519
|
+
# With the bug present, the persisted port comes back as:
|
|
2520
|
+
#
|
|
2521
|
+
# {
|
|
2522
|
+
# '_id' => ...,
|
|
2523
|
+
# 'device_id' => ...,
|
|
2524
|
+
# 'device' => [ { ...the whole device document... } ] # <-- the $lookup left this
|
|
2525
|
+
# }
|
|
2526
|
+
raw_ports = Computer.collection.find(_id: computer.id).first['ports']
|
|
2527
|
+
expect(raw_ports.first).to eq('_id' => computer.ports.first.id, 'device_id' => device.id)
|
|
2528
|
+
end
|
|
2529
|
+
end
|
|
2530
|
+
|
|
2531
|
+
context 'when the reference lives on a referenced document' do
|
|
2532
|
+
before(:all) do
|
|
2533
|
+
class Device
|
|
2534
|
+
include Mongoid::Document
|
|
2535
|
+
end
|
|
2536
|
+
|
|
2537
|
+
class Port
|
|
2538
|
+
include Mongoid::Document
|
|
2539
|
+
|
|
2540
|
+
belongs_to :computer
|
|
2541
|
+
belongs_to :device
|
|
2542
|
+
end
|
|
2543
|
+
|
|
2544
|
+
class Computer
|
|
2545
|
+
include Mongoid::Document
|
|
2546
|
+
|
|
2547
|
+
has_many :ports
|
|
2548
|
+
end
|
|
2549
|
+
end
|
|
2550
|
+
|
|
2551
|
+
after(:all) do
|
|
2552
|
+
Object.send(:remove_const, :Computer)
|
|
2553
|
+
Object.send(:remove_const, :Port)
|
|
2554
|
+
Object.send(:remove_const, :Device)
|
|
2555
|
+
end
|
|
2556
|
+
|
|
2557
|
+
let!(:device) { Device.create! }
|
|
2558
|
+
let!(:computer) { Computer.create!(ports: [ Port.new(device: device) ]) }
|
|
2559
|
+
|
|
2560
|
+
it 'does not persist the eager-loaded association data' do
|
|
2561
|
+
loaded = Computer.eager_load(ports: :device).first
|
|
2562
|
+
port = loaded.ports.first
|
|
2563
|
+
|
|
2564
|
+
# An upsert rewrites the whole document, so everything the port
|
|
2565
|
+
# carries gets serialized.
|
|
2566
|
+
port.upsert
|
|
2567
|
+
|
|
2568
|
+
# With the bug present, the persisted port comes back as:
|
|
2569
|
+
#
|
|
2570
|
+
# {
|
|
2571
|
+
# '_id' => ...,
|
|
2572
|
+
# 'computer_id' => ...,
|
|
2573
|
+
# 'device_id' => ...,
|
|
2574
|
+
# 'device' => [ { ...the whole device document... } ] # <-- the $lookup left this
|
|
2575
|
+
# }
|
|
2576
|
+
expect(Port.collection.find(_id: port.id).first)
|
|
2577
|
+
.to eq('_id' => port.id, 'computer_id' => computer.id, 'device_id' => device.id)
|
|
2578
|
+
end
|
|
2579
|
+
end
|
|
2580
|
+
|
|
2581
|
+
context 'when more than one subclass defines the association' do
|
|
2582
|
+
before(:all) do
|
|
2583
|
+
class Cog
|
|
2584
|
+
include Mongoid::Document
|
|
2585
|
+
|
|
2586
|
+
belongs_to :machine, optional: true
|
|
2587
|
+
end
|
|
2588
|
+
|
|
2589
|
+
class Belt
|
|
2590
|
+
include Mongoid::Document
|
|
2591
|
+
|
|
2592
|
+
belongs_to :machine, optional: true
|
|
2593
|
+
end
|
|
2594
|
+
|
|
2595
|
+
class Machine
|
|
2596
|
+
include Mongoid::Document
|
|
2597
|
+
end
|
|
2598
|
+
|
|
2599
|
+
class Lathe < Machine
|
|
2600
|
+
has_many :widgets, class_name: 'Cog', inverse_of: :machine
|
|
2601
|
+
end
|
|
2602
|
+
|
|
2603
|
+
class Press < Machine
|
|
2604
|
+
has_many :widgets, class_name: 'Belt', inverse_of: :machine
|
|
2605
|
+
end
|
|
2606
|
+
end
|
|
2607
|
+
|
|
2608
|
+
after(:all) do
|
|
2609
|
+
Object.send(:remove_const, :Press)
|
|
2610
|
+
Object.send(:remove_const, :Lathe)
|
|
2611
|
+
Object.send(:remove_const, :Machine)
|
|
2612
|
+
Object.send(:remove_const, :Belt)
|
|
2613
|
+
Object.send(:remove_const, :Cog)
|
|
2614
|
+
end
|
|
2615
|
+
|
|
2616
|
+
let!(:lathe) { Lathe.create! }
|
|
2617
|
+
let!(:cog) { Cog.create!(machine: lathe) }
|
|
2618
|
+
|
|
2619
|
+
it 'does not persist the eager-loaded association data' do
|
|
2620
|
+
loaded = Machine.eager_load(:widgets).first
|
|
2621
|
+
|
|
2622
|
+
# An upsert rewrites the whole document, so everything the lathe
|
|
2623
|
+
# carries gets serialized.
|
|
2624
|
+
loaded.upsert
|
|
2625
|
+
|
|
2626
|
+
# With the bug present, the persisted lathe comes back as:
|
|
2627
|
+
#
|
|
2628
|
+
# {
|
|
2629
|
+
# '_id' => ...,
|
|
2630
|
+
# '_type' => 'Lathe',
|
|
2631
|
+
# 'widgets' => [ { '_id' => ..., 'machine_id' => ... } ] # <-- the $lookup left this
|
|
2632
|
+
# }
|
|
2633
|
+
expect(Machine.collection.find(_id: lathe.id).first)
|
|
2634
|
+
.to eq('_id' => lathe.id, '_type' => 'Lathe')
|
|
2635
|
+
end
|
|
2636
|
+
end
|
|
2637
|
+
end
|
|
2292
2638
|
end
|
|
2293
2639
|
|
|
2294
2640
|
describe '#inclusions' do
|
|
@@ -29,6 +29,14 @@ describe Mongoid::Encryptable do
|
|
|
29
29
|
end
|
|
30
30
|
end
|
|
31
31
|
|
|
32
|
+
# Any subclass of the declared class can be assigned to an embeds_one
|
|
33
|
+
# association, so the check has to look at the subclasses too.
|
|
34
|
+
context 'when only a subclass of an embedded model is encrypted' do
|
|
35
|
+
it 'returns true' do
|
|
36
|
+
expect(Crypt::Locker.requires_encryption_schema?).to be true
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
32
40
|
context 'when the model declares no encryption anywhere' do
|
|
33
41
|
it 'returns false' do
|
|
34
42
|
expect(Person.requires_encryption_schema?).to be false
|
|
@@ -57,5 +65,51 @@ describe Mongoid::Encryptable do
|
|
|
57
65
|
expect(Crypt::Drawer.requires_encryption_schema?).to be false
|
|
58
66
|
end
|
|
59
67
|
end
|
|
68
|
+
|
|
69
|
+
context 'when every embedded association resolves' do
|
|
70
|
+
it 'memoizes a false answer' do
|
|
71
|
+
expect(Truck.requires_encryption_schema?).to be false
|
|
72
|
+
expect(Truck.instance_variable_defined?(:@requires_encryption_schema)).to be true
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
context 'when an embedded association does not resolve' do
|
|
77
|
+
it 'does not memoize a false answer' do
|
|
78
|
+
expect(Crypt::Drawer.requires_encryption_schema?).to be false
|
|
79
|
+
expect(Crypt::Drawer.instance_variable_defined?(:@requires_encryption_schema)).to be false
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
context 'when an embedded encrypted class is defined after the first check' do
|
|
84
|
+
after do
|
|
85
|
+
if Crypt.const_defined?(:MissingNote, false)
|
|
86
|
+
Mongoid.deregister_model(Crypt::MissingNote)
|
|
87
|
+
Crypt.send(:remove_const, :MissingNote)
|
|
88
|
+
end
|
|
89
|
+
# While the class above existed, resolving it through the association
|
|
90
|
+
# memoized the class on the association, and a true answer on the
|
|
91
|
+
# model. Drop both, so the other examples see the model as it was
|
|
92
|
+
# before the class was defined.
|
|
93
|
+
relation = Crypt::Drawer.relations['missing_note']
|
|
94
|
+
relation.remove_instance_variable(:@klass) if relation.instance_variable_defined?(:@klass)
|
|
95
|
+
if Crypt::Drawer.instance_variable_defined?(:@requires_encryption_schema)
|
|
96
|
+
Crypt::Drawer.remove_instance_variable(:@requires_encryption_schema)
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
it 'returns true once the class is loaded' do
|
|
101
|
+
expect(Crypt::Drawer.requires_encryption_schema?).to be false
|
|
102
|
+
|
|
103
|
+
missing_note = Class.new do
|
|
104
|
+
include Mongoid::Document
|
|
105
|
+
|
|
106
|
+
embedded_in :drawer, class_name: 'Crypt::Drawer'
|
|
107
|
+
field :text, type: String, encrypt: true
|
|
108
|
+
end
|
|
109
|
+
Crypt.const_set(:MissingNote, missing_note)
|
|
110
|
+
|
|
111
|
+
expect(Crypt::Drawer.requires_encryption_schema?).to be true
|
|
112
|
+
end
|
|
113
|
+
end
|
|
60
114
|
end
|
|
61
115
|
end
|
data/spec/mongoid/fields_spec.rb
CHANGED
|
@@ -1814,6 +1814,14 @@ describe Mongoid::Fields do
|
|
|
1814
1814
|
it { is_expected.to eq '' }
|
|
1815
1815
|
end
|
|
1816
1816
|
|
|
1817
|
+
context 'when the returned name is mutated' do
|
|
1818
|
+
it 'does not corrupt the aliased field map' do
|
|
1819
|
+
Person.database_field_name('test') << '_mutated'
|
|
1820
|
+
|
|
1821
|
+
expect(Person.database_field_name('test')).to eq('t')
|
|
1822
|
+
end
|
|
1823
|
+
end
|
|
1824
|
+
|
|
1817
1825
|
context 'given a String' do
|
|
1818
1826
|
subject { Person.database_field_name(key.to_s) }
|
|
1819
1827
|
|
|
@@ -118,6 +118,32 @@ describe Mongoid::SearchIndexable do
|
|
|
118
118
|
end
|
|
119
119
|
end
|
|
120
120
|
|
|
121
|
+
describe '.wait_for_search_indexes' do
|
|
122
|
+
let(:model) do
|
|
123
|
+
Class.new do
|
|
124
|
+
include Mongoid::Document
|
|
125
|
+
|
|
126
|
+
store_in collection: BSON::ObjectId.new.to_s
|
|
127
|
+
search_index :idx, mappings: { dynamic: false }
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
it 'reads the index status inside collection management' do
|
|
132
|
+
managing = nil
|
|
133
|
+
search_indexes = [ { 'name' => 'idx', 'queryable' => true, 'status' => 'READY' } ]
|
|
134
|
+
collection = instance_double(Mongo::Collection)
|
|
135
|
+
allow(collection).to receive(:search_indexes) do
|
|
136
|
+
managing = Mongoid::Threaded.managing_collection?
|
|
137
|
+
search_indexes
|
|
138
|
+
end
|
|
139
|
+
allow(model).to receive(:collection).and_return(collection)
|
|
140
|
+
|
|
141
|
+
model.wait_for_search_indexes([ 'idx' ])
|
|
142
|
+
|
|
143
|
+
expect(managing).to be true
|
|
144
|
+
end
|
|
145
|
+
end
|
|
146
|
+
|
|
121
147
|
describe '.vector_search_index' do
|
|
122
148
|
let(:vector_model) do
|
|
123
149
|
Class.new do
|