mongoid 9.0.7 → 9.0.9

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.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/lib/mongoid/association/embedded/batchable.rb +11 -10
  3. data/lib/mongoid/association/embedded/embeds_many/proxy.rb +64 -29
  4. data/lib/mongoid/association/nested/many.rb +2 -0
  5. data/lib/mongoid/association/nested/one.rb +1 -1
  6. data/lib/mongoid/association/referenced/has_and_belongs_to_many/proxy.rb +0 -6
  7. data/lib/mongoid/association/referenced/has_many/enumerable.rb +40 -0
  8. data/lib/mongoid/association/referenced/has_many/proxy.rb +17 -5
  9. data/lib/mongoid/attributes.rb +19 -1
  10. data/lib/mongoid/changeable.rb +10 -1
  11. data/lib/mongoid/clients/sessions.rb +3 -4
  12. data/lib/mongoid/config.rb +1 -1
  13. data/lib/mongoid/contextual/aggregable/mongo.rb +6 -1
  14. data/lib/mongoid/contextual/mongo.rb +8 -89
  15. data/lib/mongoid/pluckable.rb +132 -0
  16. data/lib/mongoid/railties/bson_object_id_serializer.rb +7 -0
  17. data/lib/mongoid/reloadable.rb +6 -0
  18. data/lib/mongoid/traversable.rb +0 -2
  19. data/lib/mongoid/version.rb +1 -1
  20. data/spec/integration/associations/embeds_many_spec.rb +110 -0
  21. data/spec/integration/associations/has_and_belongs_to_many_spec.rb +81 -0
  22. data/spec/integration/associations/has_many_spec.rb +56 -0
  23. data/spec/integration/associations/has_one_spec.rb +55 -3
  24. data/spec/mongoid/association/referenced/has_many/enumerable_spec.rb +394 -0
  25. data/spec/mongoid/association/referenced/has_many_models.rb +24 -0
  26. data/spec/mongoid/association/referenced/has_one_models.rb +10 -2
  27. data/spec/mongoid/attributes_spec.rb +13 -0
  28. data/spec/mongoid/clients/transactions_spec.rb +162 -1
  29. data/spec/mongoid/clients/transactions_spec_models.rb +93 -0
  30. data/spec/mongoid/contextual/aggregable/mongo_spec.rb +33 -0
  31. data/spec/mongoid/reloadable_spec.rb +24 -0
  32. data/spec/shared/CANDIDATE.md +28 -0
  33. data/spec/shared/lib/mrss/spec_organizer.rb +32 -3
  34. data/spec/shared/shlib/server.sh +1 -1
  35. data/spec/support/models/company.rb +2 -0
  36. data/spec/support/models/passport.rb +1 -0
  37. data/spec/support/models/product.rb +2 -0
  38. data/spec/support/models/seo.rb +2 -0
  39. metadata +7 -4
@@ -1819,6 +1819,400 @@ describe Mongoid::Association::Referenced::HasMany::Enumerable do
1819
1819
  end
1820
1820
  end
1821
1821
 
1822
+ describe '#pluck' do
1823
+ let(:person) do
1824
+ Person.create!
1825
+ end
1826
+
1827
+ let!(:post) do
1828
+ Post.create!(person_id: person.id, title: 'Test Title')
1829
+ end
1830
+
1831
+ let(:base) { Person }
1832
+ let(:association) { Person.relations[:posts] }
1833
+
1834
+ let(:criteria) do
1835
+ Post.where(person_id: person.id)
1836
+ end
1837
+
1838
+ context 'when the enumerable is not loaded' do
1839
+ let!(:enumerable) do
1840
+ described_class.new(criteria, base, association)
1841
+ end
1842
+
1843
+ context 'when the criteria is present' do
1844
+ it 'delegates to the criteria pluck method' do
1845
+ result = enumerable.pluck(:title)
1846
+ expect(result).to eq(['Test Title'])
1847
+ end
1848
+
1849
+ context 'when added docs are present' do
1850
+ it 'combines the results from the criteria and the added docs' do
1851
+ added_post = Post.new(title: 'Added Title', person_id: person.id)
1852
+ enumerable << added_post
1853
+
1854
+ expect(criteria).to receive(:pluck).with(:title).and_return(['Test Title'])
1855
+ result = enumerable.pluck(:title)
1856
+ expect(result).to eq(['Test Title', 'Added Title'])
1857
+ end
1858
+ end
1859
+ end
1860
+
1861
+ context 'when the criteria is not present' do
1862
+ let(:enumerable) { described_class.new([], base, association) }
1863
+
1864
+ it 'returns nothing' do
1865
+ result = enumerable.pluck(:title)
1866
+ expect(result).to eq([])
1867
+ end
1868
+
1869
+ context 'when added docs are present' do
1870
+ it 'returns the values from the added docs' do
1871
+ added_post = Post.new(title: 'Added Title', person_id: person.id)
1872
+ enumerable << added_post
1873
+
1874
+ result = enumerable.pluck(:title)
1875
+ expect(result).to eq(['Added Title'])
1876
+ end
1877
+ end
1878
+ end
1879
+ end
1880
+
1881
+ context 'when the enumerable is loaded' do
1882
+ let(:enumerable) { described_class.new([post], base, association) }
1883
+
1884
+ it 'returns the values from the loaded documents' do
1885
+ result = enumerable.pluck(:title)
1886
+ expect(result).to eq(['Test Title'])
1887
+ end
1888
+
1889
+ context 'when added docs are present' do
1890
+ it 'returns the values from both loaded and added docs' do
1891
+ added_post = Post.new(title: 'Added Title', person_id: person.id)
1892
+ enumerable << added_post
1893
+
1894
+ result = enumerable.pluck(:title)
1895
+ expect(result).to eq(['Test Title', 'Added Title'])
1896
+ end
1897
+ end
1898
+ end
1899
+ end
1900
+
1901
+ describe '#pluck with aliases' do
1902
+ let!(:parent) do
1903
+ Company.create!
1904
+ end
1905
+
1906
+ context 'when the field is aliased' do
1907
+ let!(:expensive) do
1908
+ parent.products.create!(price: 100000)
1909
+ end
1910
+
1911
+ let!(:cheap) do
1912
+ parent.products.create!(price: 1)
1913
+ end
1914
+
1915
+ context 'when using alias_attribute' do
1916
+
1917
+ let(:plucked) do
1918
+ parent.products.pluck(:price)
1919
+ end
1920
+
1921
+ it 'uses the aliases' do
1922
+ expect(plucked).to eq([ 100000, 1 ])
1923
+ end
1924
+ end
1925
+ end
1926
+
1927
+ context 'when plucking a localized field' do
1928
+ with_default_i18n_configs
1929
+
1930
+ before do
1931
+ I18n.locale = :en
1932
+ p = parent.products.create!(name: 'english-text')
1933
+ I18n.locale = :de
1934
+ p.name = 'deutsch-text'
1935
+ p.save!
1936
+ end
1937
+
1938
+ context 'when plucking the entire field' do
1939
+ let(:plucked) do
1940
+ parent.products.all.pluck(:name)
1941
+ end
1942
+
1943
+ let(:plucked_translations) do
1944
+ parent.products.all.pluck(:name_translations)
1945
+ end
1946
+
1947
+ let(:plucked_translations_both) do
1948
+ parent.products.all.pluck(:name_translations, :name)
1949
+ end
1950
+
1951
+ it 'returns the demongoized translations' do
1952
+ expect(plucked.first).to eq('deutsch-text')
1953
+ end
1954
+
1955
+ it 'returns the full translations hash to _translations' do
1956
+ expect(plucked_translations.first).to eq({'de'=>'deutsch-text', 'en'=>'english-text'})
1957
+ end
1958
+
1959
+ it 'returns both' do
1960
+ expect(plucked_translations_both.first).to eq([{'de'=>'deutsch-text', 'en'=>'english-text'}, 'deutsch-text'])
1961
+ end
1962
+ end
1963
+
1964
+ context 'when plucking a specific locale' do
1965
+
1966
+ let(:plucked) do
1967
+ parent.products.all.pluck(:'name.de')
1968
+ end
1969
+
1970
+ it 'returns the specific translations' do
1971
+ expect(plucked.first).to eq('deutsch-text')
1972
+ end
1973
+ end
1974
+
1975
+ context 'when plucking a specific locale from _translations field' do
1976
+
1977
+ let(:plucked) do
1978
+ parent.products.all.pluck(:'name_translations.de')
1979
+ end
1980
+
1981
+ it 'returns the specific translations' do
1982
+ expect(plucked.first).to eq('deutsch-text')
1983
+ end
1984
+ end
1985
+
1986
+ context 'when fallbacks are enabled with a locale list' do
1987
+ require_fallbacks
1988
+
1989
+ before do
1990
+ I18n.fallbacks[:he] = [ :en ]
1991
+ end
1992
+
1993
+ let(:plucked) do
1994
+ parent.products.all.pluck(:name).first
1995
+ end
1996
+
1997
+ it 'correctly uses the fallback' do
1998
+ I18n.locale = :en
1999
+ parent.products.create!(name: 'english-text')
2000
+ I18n.locale = :he
2001
+ expect(plucked).to eq 'english-text'
2002
+ end
2003
+ end
2004
+
2005
+ context 'when the localized field is aliased' do
2006
+ before do
2007
+ I18n.locale = :en
2008
+ parent.products.delete_all
2009
+ p = parent.products.create!(name: 'ACME Rocket Skates', tagline: 'english-text')
2010
+ I18n.locale = :de
2011
+ p.tagline = 'deutsch-text'
2012
+ p.save!
2013
+ end
2014
+
2015
+ context 'when plucking the entire field' do
2016
+ let(:plucked) do
2017
+ parent.products.all.pluck(:tagline)
2018
+ end
2019
+
2020
+ let(:plucked_unaliased) do
2021
+ parent.products.all.pluck(:tl)
2022
+ end
2023
+
2024
+ let(:plucked_translations) do
2025
+ parent.products.all.pluck(:tagline_translations)
2026
+ end
2027
+
2028
+ let(:plucked_translations_both) do
2029
+ parent.products.all.pluck(:tagline_translations, :tagline)
2030
+ end
2031
+
2032
+ it 'returns the demongoized translations' do
2033
+ expect(plucked.first).to eq('deutsch-text')
2034
+ end
2035
+
2036
+ it 'returns the demongoized translations when unaliased' do
2037
+ expect(plucked_unaliased.first).to eq('deutsch-text')
2038
+ end
2039
+
2040
+ it 'returns the full translations hash to _translations' do
2041
+ expect(plucked_translations.first).to eq({ 'de' => 'deutsch-text', 'en' => 'english-text' })
2042
+ end
2043
+
2044
+ it 'returns both' do
2045
+ expect(plucked_translations_both.first).to eq([{ 'de' => 'deutsch-text', 'en' => 'english-text' }, 'deutsch-text'])
2046
+ end
2047
+ end
2048
+
2049
+ context 'when plucking a specific locale' do
2050
+
2051
+ let(:plucked) do
2052
+ parent.products.all.pluck(:'tagline.de')
2053
+ end
2054
+
2055
+ it 'returns the specific translations' do
2056
+ expect(plucked.first).to eq('deutsch-text')
2057
+ end
2058
+ end
2059
+
2060
+ context 'when plucking a specific locale from _translations field' do
2061
+
2062
+ let(:plucked) do
2063
+ parent.products.all.pluck(:'tagline_translations.de')
2064
+ end
2065
+
2066
+ it 'returns the specific translations' do
2067
+ expect(plucked.first).to eq('deutsch-text')
2068
+ end
2069
+ end
2070
+
2071
+ context 'when fallbacks are enabled with a locale list' do
2072
+ require_fallbacks
2073
+
2074
+ before do
2075
+ I18n.fallbacks[:he] = [:en]
2076
+ end
2077
+
2078
+ let(:plucked) do
2079
+ parent.products.all.pluck(:tagline).first
2080
+ end
2081
+
2082
+ it 'correctly uses the fallback' do
2083
+ I18n.locale = :en
2084
+ parent.products.create!(tagline: 'english-text')
2085
+ I18n.locale = :he
2086
+ expect(plucked).to eq 'english-text'
2087
+ end
2088
+ end
2089
+ end
2090
+
2091
+ context 'when the localized field is embedded' do
2092
+ with_default_i18n_configs
2093
+
2094
+ before do
2095
+ s = Seo.new
2096
+ I18n.locale = :en
2097
+ s.name = 'english-text'
2098
+ I18n.locale = :de
2099
+ s.name = 'deutsch-text'
2100
+
2101
+ parent.products.delete_all
2102
+ parent.products.create!(name: 'ACME Tunnel Paint', seo: s)
2103
+ end
2104
+
2105
+ let(:plucked) do
2106
+ parent.products.pluck('seo.name').first
2107
+ end
2108
+
2109
+ let(:plucked_translations) do
2110
+ parent.products.pluck('seo.name_translations').first
2111
+ end
2112
+
2113
+ let(:plucked_translations_field) do
2114
+ parent.products.pluck('seo.name_translations.en').first
2115
+ end
2116
+
2117
+ it 'returns the translation for the current locale' do
2118
+ expect(plucked).to eq('deutsch-text')
2119
+ end
2120
+
2121
+ it 'returns the full _translation hash' do
2122
+ expect(plucked_translations).to eq({ 'en' => 'english-text', 'de' => 'deutsch-text' })
2123
+ end
2124
+
2125
+ it 'returns the translation for the requested locale' do
2126
+ expect(plucked_translations_field).to eq('english-text')
2127
+ end
2128
+ end
2129
+ end
2130
+
2131
+ context 'when the localized field is embedded and aliased' do
2132
+ with_default_i18n_configs
2133
+
2134
+ before do
2135
+ s = Seo.new
2136
+ I18n.locale = :en
2137
+ s.description = 'english-text'
2138
+ I18n.locale = :de
2139
+ s.description = 'deutsch-text'
2140
+
2141
+ parent.products.delete_all
2142
+ parent.products.create!(name: 'ACME Tunnel Paint', seo: s)
2143
+ end
2144
+
2145
+ let(:plucked) do
2146
+ parent.products.pluck('seo.description').first
2147
+ end
2148
+
2149
+ let(:plucked_unaliased) do
2150
+ parent.products.pluck('seo.desc').first
2151
+ end
2152
+
2153
+ let(:plucked_translations) do
2154
+ parent.products.pluck('seo.description_translations').first
2155
+ end
2156
+
2157
+ let(:plucked_translations_field) do
2158
+ parent.products.pluck('seo.description_translations.en').first
2159
+ end
2160
+
2161
+ it 'returns the translation for the current locale' do
2162
+ I18n.with_locale(:en) do
2163
+ expect(plucked).to eq('english-text')
2164
+ end
2165
+ end
2166
+
2167
+ it 'returns the translation for the current locale when unaliased' do
2168
+ I18n.with_locale(:en) do
2169
+ expect(plucked_unaliased).to eq('english-text')
2170
+ end
2171
+ end
2172
+
2173
+ it 'returns the full _translation hash' do
2174
+ expect(plucked_translations).to eq({ 'en' => 'english-text', 'de' => 'deutsch-text' })
2175
+ end
2176
+
2177
+ it 'returns the translation for the requested locale' do
2178
+ expect(plucked_translations_field).to eq('english-text')
2179
+ end
2180
+ end
2181
+
2182
+ context 'when plucking an embedded field' do
2183
+ let(:label) { Label.new(sales: '1E2') }
2184
+ let!(:band) { Band.create!(label: label) }
2185
+
2186
+ let(:plucked) { Band.where(_id: band.id).pluck('label.sales') }
2187
+
2188
+ it 'demongoizes the field' do
2189
+ expect(plucked).to eq([ BigDecimal('1E2') ])
2190
+ end
2191
+ end
2192
+
2193
+ context 'when plucking an embeds_many field' do
2194
+ let(:label) { Label.new(sales: '1E2') }
2195
+ let!(:band) { Band.create!(labels: [label]) }
2196
+
2197
+ let(:plucked) { Band.where(_id: band.id).pluck('labels.sales') }
2198
+
2199
+ it 'demongoizes the field' do
2200
+ expect(plucked.first).to eq([ BigDecimal('1E2') ])
2201
+ end
2202
+ end
2203
+
2204
+ context 'when plucking a nonexistent embedded field' do
2205
+ let(:label) { Label.new(sales: '1E2') }
2206
+ let!(:band) { Band.create!(label: label) }
2207
+
2208
+ let(:plucked) { Band.where(_id: band.id).pluck('label.qwerty') }
2209
+
2210
+ it 'returns nil' do
2211
+ expect(plucked.first).to eq(nil)
2212
+ end
2213
+ end
2214
+ end
2215
+
1822
2216
  describe "#reset" do
1823
2217
 
1824
2218
  let(:person) do
@@ -96,3 +96,27 @@ class HmmAnimal
96
96
 
97
97
  belongs_to :trainer, class_name: 'HmmTrainer', scope: -> { where(name: 'Dave') }
98
98
  end
99
+
100
+ class HmmPost
101
+ include Mongoid::Document
102
+
103
+ field :title, type: String
104
+
105
+ has_many :comments, class_name: 'HmmComment', as: :container
106
+
107
+ accepts_nested_attributes_for :comments, allow_destroy: true
108
+ end
109
+
110
+ class HmmComment
111
+ include Mongoid::Document
112
+
113
+ field :title, type: String
114
+ field :num, type: Integer, default: 0
115
+
116
+ belongs_to :container, polymorphic: true
117
+ has_many :comments, class_name: 'HmmComment', as: :container
118
+
119
+ accepts_nested_attributes_for :comments, allow_destroy: true
120
+
121
+ validates :num, numericality: { greater_than_or_equal_to: 0 }
122
+ end
@@ -102,13 +102,21 @@ class HomPost
102
102
 
103
103
  field :title, type: String
104
104
 
105
- has_one :comment, inverse_of: :post, class_name: 'HomComment'
105
+ has_one :comment, as: :container, class_name: 'HomComment'
106
+
107
+ accepts_nested_attributes_for :comment, allow_destroy: true
106
108
  end
107
109
 
108
110
  class HomComment
109
111
  include Mongoid::Document
110
112
 
111
113
  field :content, type: String
114
+ field :num, type: Integer, default: 0
115
+
116
+ validates :num, numericality: { greater_than_or_equal_to: 0 }
117
+
118
+ belongs_to :container, polymorphic: true, optional: true
119
+ has_one :comment, as: :container, class_name: 'HomComment'
112
120
 
113
- belongs_to :post, inverse_of: :comment, optional: true, class_name: 'HomPost'
121
+ accepts_nested_attributes_for :comment, allow_destroy: true
114
122
  end
@@ -1729,6 +1729,19 @@ describe Mongoid::Attributes do
1729
1729
  end
1730
1730
  end
1731
1731
  end
1732
+
1733
+ context 'when map_big_decimal_to_decimal128 is enabled' do
1734
+ config_override :map_big_decimal_to_decimal128, true
1735
+
1736
+ context 'when writing an identical number' do
1737
+ let(:band) { Band.create!(name: 'Nirvana', sales: 123456.78).reload }
1738
+
1739
+ it 'does not mark the document as changed' do
1740
+ band.sales = 123456.78
1741
+ expect(band.changed?).to be false
1742
+ end
1743
+ end
1744
+ end
1732
1745
  end
1733
1746
 
1734
1747
  describe "#typed_value_for" do
@@ -716,7 +716,7 @@ describe Mongoid::Clients::Sessions do
716
716
  require_transaction_support
717
717
 
718
718
  context 'when no error raised' do
719
- before do
719
+ let!(:person) do
720
720
  Mongoid.transaction do
721
721
  Person.create!
722
722
  end
@@ -727,6 +727,10 @@ describe Mongoid::Clients::Sessions do
727
727
  expect(other_events.count { |e| e.command_name == 'commitTransaction'}).to be(1)
728
728
  end
729
729
 
730
+ it 'returns the value from the block' do
731
+ expect(person).to be_a(Person)
732
+ end
733
+
730
734
  it 'executes the commands inside the transaction' do
731
735
  expect(Person.count).to be(1)
732
736
  end
@@ -787,8 +791,12 @@ describe Mongoid::Clients::Sessions do
787
791
  Mongoid::Clients.with_name(:default).database.collections.each(&:drop)
788
792
  TransactionsSpecPerson.collection.create
789
793
  TransactionsSpecPersonWithOnCreate.collection.create
794
+ TransactionsSpecPersonWithAfterCreateCommit.collection.create
790
795
  TransactionsSpecPersonWithOnUpdate.collection.create
796
+ TransactionsSpecPersonWithAfterUpdateCommit.collection.create
797
+ TransactionsSpecPersonWithAfterSaveCommit.collection.create
791
798
  TransactionsSpecPersonWithOnDestroy.collection.create
799
+ TransactionsSpecPersonWithAfterDestroyCommit.collection.create
792
800
  TransactionSpecRaisesBeforeSave.collection.create
793
801
  TransactionSpecRaisesAfterSave.collection.create
794
802
  end
@@ -818,6 +826,18 @@ describe Mongoid::Clients::Sessions do
818
826
 
819
827
  it_behaves_like 'commit callbacks are called'
820
828
  end
829
+
830
+ context 'when callback is after_create_commit' do
831
+ let!(:subject) do
832
+ person = nil
833
+ TransactionsSpecPersonWithAfterCreateCommit.transaction do
834
+ person = TransactionsSpecPersonWithAfterCreateCommit.create!(name: 'James Bond')
835
+ end
836
+ person
837
+ end
838
+
839
+ it_behaves_like 'commit callbacks are called'
840
+ end
821
841
  end
822
842
 
823
843
  context 'save' do
@@ -886,6 +906,94 @@ describe Mongoid::Clients::Sessions do
886
906
  it_behaves_like 'commit callbacks are called'
887
907
  end
888
908
  end
909
+
910
+ context 'with after_update_commit callback' do
911
+ let(:subject) do
912
+ TransactionsSpecPersonWithAfterUpdateCommit.create!(name: 'James Bond').tap do |subject|
913
+ subject.after_commit_counter.reset
914
+ subject.after_rollback_counter.reset
915
+ end
916
+ end
917
+
918
+ context 'when modified once' do
919
+ before do
920
+ subject.transaction do
921
+ subject.name = 'Austin Powers'
922
+ subject.save!
923
+ end
924
+ end
925
+
926
+ it_behaves_like 'commit callbacks are called'
927
+ end
928
+
929
+ context 'when modified multiple times' do
930
+ before do
931
+ subject.transaction do
932
+ subject.name = 'Austin Powers'
933
+ subject.save!
934
+ subject.name = 'Jason Bourne'
935
+ subject.save!
936
+ end
937
+ end
938
+
939
+ it_behaves_like 'commit callbacks are called'
940
+ end
941
+ end
942
+
943
+ context 'with after_save_commit callback' do
944
+ let(:subject) do
945
+ TransactionsSpecPersonWithAfterSaveCommit.create!(name: 'James Bond').tap do |subject|
946
+ subject.after_commit_counter.reset
947
+ subject.after_rollback_counter.reset
948
+ end
949
+ end
950
+
951
+ context 'when modified once' do
952
+ before do
953
+ subject.transaction do
954
+ subject.name = 'Austin Powers'
955
+ subject.save!
956
+ end
957
+ end
958
+
959
+ it_behaves_like 'commit callbacks are called'
960
+ end
961
+
962
+ context 'when created' do
963
+ before do
964
+ TransactionsSpecPersonWithAfterSaveCommit.transaction do
965
+ subject
966
+ end
967
+ end
968
+
969
+ it_behaves_like 'commit callbacks are called'
970
+ end
971
+
972
+ context 'when modified multiple times' do
973
+ before do
974
+ subject.transaction do
975
+ subject.name = 'Austin Powers'
976
+ subject.save!
977
+ subject.name = 'Jason Bourne'
978
+ subject.save!
979
+ end
980
+ end
981
+
982
+ it_behaves_like 'commit callbacks are called'
983
+ end
984
+
985
+ context 'when created and modified' do
986
+ before do
987
+ TransactionsSpecPersonWithAfterSaveCommit.transaction do
988
+ subject
989
+ subject.name = 'Jason Bourne'
990
+ subject.save!
991
+ end
992
+ end
993
+
994
+ it_behaves_like 'commit callbacks are called'
995
+ end
996
+ end
889
997
  end
890
998
 
891
999
  context 'update_attributes' do
@@ -919,6 +1027,34 @@ describe Mongoid::Clients::Sessions do
919
1027
 
920
1028
  it_behaves_like 'commit callbacks are called'
921
1029
  end
1030
+
1031
+ context 'when callback is after_update_commit' do
1032
+ let(:subject) do
1033
+ TransactionsSpecPersonWithAfterUpdateCommit.create!(name: 'Jason Bourne')
1034
+ end
1035
+
1036
+ before do
1037
+ TransactionsSpecPersonWithAfterUpdateCommit.transaction do
1038
+ subject.update_attributes!(name: 'Foma Kiniaev')
1039
+ end
1040
+ end
1041
+
1042
+ it_behaves_like 'commit callbacks are called'
1043
+ end
1044
+
1045
+ context 'when callback is after_save_commit' do
1046
+ let(:subject) do
1047
+ TransactionsSpecPersonWithAfterSaveCommit.create!(name: 'Jason Bourne')
1048
+ end
1049
+
1050
+ before do
1051
+ TransactionsSpecPersonWithAfterSaveCommit.transaction do
1052
+ subject.update_attributes!(name: 'Foma Kiniaev')
1053
+ end
1054
+ end
1055
+
1056
+ it_behaves_like 'commit callbacks are called'
1057
+ end
922
1058
  end
923
1059
 
924
1060
  context 'destroy' do
@@ -971,6 +1107,31 @@ describe Mongoid::Clients::Sessions do
971
1107
 
972
1108
  it_behaves_like 'commit callbacks are called'
973
1109
  end
1110
+
1111
+ context 'with after_destroy_commit' do
1112
+ let(:after_commit_counter) do
1113
+ TransactionsSpecCounter.new
1114
+ end
1115
+
1116
+ let(:after_rollback_counter) do
1117
+ TransactionsSpecCounter.new
1118
+ end
1119
+
1120
+ let(:subject) do
1121
+ TransactionsSpecPersonWithAfterDestroyCommit.create!(name: 'James Bond').tap do |p|
1122
+ p.after_commit_counter = after_commit_counter
1123
+ p.after_rollback_counter = after_rollback_counter
1124
+ end
1125
+ end
1126
+
1127
+ before do
1128
+ subject.transaction do
1129
+ subject.destroy
1130
+ end
1131
+ end
1132
+
1133
+ it_behaves_like 'commit callbacks are called'
1134
+ end
974
1135
  end
975
1136
  end
976
1137