mongo_mapper 0.15.1 → 0.15.5

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 (57) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +22 -7
  3. data/lib/mongo_mapper/document.rb +1 -0
  4. data/lib/mongo_mapper/extensions/array.rb +1 -1
  5. data/lib/mongo_mapper/extensions/binary.rb +1 -1
  6. data/lib/mongo_mapper/extensions/date.rb +1 -1
  7. data/lib/mongo_mapper/extensions/float.rb +1 -1
  8. data/lib/mongo_mapper/extensions/hash.rb +1 -1
  9. data/lib/mongo_mapper/extensions/nil_class.rb +2 -2
  10. data/lib/mongo_mapper/extensions/object.rb +1 -1
  11. data/lib/mongo_mapper/extensions/object_id.rb +1 -1
  12. data/lib/mongo_mapper/extensions/set.rb +1 -1
  13. data/lib/mongo_mapper/extensions/string.rb +1 -1
  14. data/lib/mongo_mapper/plugins/associations/many_association.rb +2 -3
  15. data/lib/mongo_mapper/plugins/associations/{belongs_to_polymorphic_proxy.rb → proxy/belongs_to_polymorphic_proxy.rb} +0 -0
  16. data/lib/mongo_mapper/plugins/associations/{belongs_to_proxy.rb → proxy/belongs_to_proxy.rb} +6 -0
  17. data/lib/mongo_mapper/plugins/associations/proxy/collection.rb +55 -0
  18. data/lib/mongo_mapper/plugins/associations/{embedded_collection.rb → proxy/embedded_collection.rb} +0 -0
  19. data/lib/mongo_mapper/plugins/associations/{in_array_proxy.rb → proxy/in_array_proxy.rb} +0 -0
  20. data/lib/mongo_mapper/plugins/associations/{in_foreign_array_proxy.rb → proxy/in_foreign_array_proxy.rb} +0 -0
  21. data/lib/mongo_mapper/plugins/associations/{many_documents_as_proxy.rb → proxy/many_documents_as_proxy.rb} +0 -0
  22. data/lib/mongo_mapper/plugins/associations/{many_documents_proxy.rb → proxy/many_documents_proxy.rb} +0 -4
  23. data/lib/mongo_mapper/plugins/associations/{many_embedded_polymorphic_proxy.rb → proxy/many_embedded_polymorphic_proxy.rb} +0 -0
  24. data/lib/mongo_mapper/plugins/associations/{many_embedded_proxy.rb → proxy/many_embedded_proxy.rb} +0 -0
  25. data/lib/mongo_mapper/plugins/associations/{many_polymorphic_proxy.rb → proxy/many_polymorphic_proxy.rb} +0 -0
  26. data/lib/mongo_mapper/plugins/associations/{one_as_proxy.rb → proxy/one_as_proxy.rb} +0 -0
  27. data/lib/mongo_mapper/plugins/associations/{one_embedded_polymorphic_proxy.rb → proxy/one_embedded_polymorphic_proxy.rb} +0 -0
  28. data/lib/mongo_mapper/plugins/associations/{one_embedded_proxy.rb → proxy/one_embedded_proxy.rb} +3 -1
  29. data/lib/mongo_mapper/plugins/associations/{one_proxy.rb → proxy/one_proxy.rb} +0 -0
  30. data/lib/mongo_mapper/plugins/associations/{proxy.rb → proxy/proxy.rb} +69 -49
  31. data/lib/mongo_mapper/plugins/associations/single_association.rb +2 -11
  32. data/lib/mongo_mapper/plugins/dirty.rb +2 -2
  33. data/lib/mongo_mapper/plugins/embedded_document.rb +1 -1
  34. data/lib/mongo_mapper/plugins/keys/key.rb +9 -6
  35. data/lib/mongo_mapper/plugins/keys.rb +17 -7
  36. data/lib/mongo_mapper/plugins/querying.rb +2 -2
  37. data/lib/mongo_mapper/plugins/scopes.rb +19 -3
  38. data/lib/mongo_mapper/plugins/shardable.rb +30 -0
  39. data/lib/mongo_mapper/plugins/validations.rb +1 -1
  40. data/lib/mongo_mapper/version.rb +1 -1
  41. data/lib/mongo_mapper.rb +18 -18
  42. data/spec/examples.txt +1718 -1697
  43. data/spec/functional/associations/belongs_to_proxy_spec.rb +33 -0
  44. data/spec/functional/associations/one_embedded_proxy_spec.rb +28 -0
  45. data/spec/functional/associations/one_proxy_spec.rb +11 -1
  46. data/spec/functional/dirty_spec.rb +21 -0
  47. data/spec/functional/dirty_with_callbacks_spec.rb +59 -0
  48. data/spec/functional/keys_spec.rb +13 -0
  49. data/spec/functional/scopes_spec.rb +88 -0
  50. data/spec/functional/shardable_spec.rb +67 -0
  51. data/spec/spec_helper.rb +7 -0
  52. data/spec/unit/associations/proxy_spec.rb +30 -5
  53. data/spec/unit/extensions_spec.rb +9 -3
  54. data/spec/unit/inspect_spec.rb +1 -1
  55. data/spec/unit/key_spec.rb +7 -1
  56. metadata +36 -19
  57. data/lib/mongo_mapper/plugins/associations/collection.rb +0 -29
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 77d669d6c4286995fb2afbed7cf23475c6dc496cb3faf97a57f3b8f115e263b3
4
- data.tar.gz: d11040bb05eeb6cb57465c4585c0667b16d750b16d7fd5fedca5e03734b769ac
3
+ metadata.gz: ae0bcdb6320444b591dc779d739c553ba371c86e8465c4547c5e35423fe37ade
4
+ data.tar.gz: 270341e4efc65ba09578c2ba889c3c2e560610cf6eddfa7889fee19ded37c760
5
5
  SHA512:
6
- metadata.gz: 56a665e63c65da52238cc18348333a2a9c6b6d1c5acf564308f60f8fcec8a1be759c5b7546a0259092a7f6acc9170659d55c462ac59fffe6520f3339a650df15
7
- data.tar.gz: 8dceac60d1ef1159585453450d2960e4d9d50e472ec7728f3b703da8e40e80af625b01bb6c4022327e16631960faa698da93c7d37c563cd1c839eb3ebfc28ddb
6
+ metadata.gz: 3af02a093ffb4f9b13f48557bd83689c5cdcf35e434c00b152be18ad33e520e9ffbf1b7817b90ac4d363fe6f4452bab2ee66c5c450aca65981cc29ac2e74fe89
7
+ data.tar.gz: '09f802a3351959d626e23b4a6fa331ef10749a3b2f259440b527b26a25a23d0f0684c1e2bf0001938357e76fe5664da481ff298b572e665ded6afe0feb5fb286'
data/README.md CHANGED
@@ -4,9 +4,9 @@ A Ruby Object Mapper for Mongo.
4
4
 
5
5
  [<img src="https://badge.fury.io/rb/mongo_mapper.svg" alt="RubyGems">](https://rubygems.org/gems/mongo_mapper)
6
6
 
7
- [<img src="https://travis-ci.org/mongomapper/mongomapper.svg?branch=master" alt="Build Status" />](https://travis-ci.org/mongomapper/mongomapper)
7
+ [<img src="https://github.com/mongomapper/mongomapper/workflows/Ruby/badge.svg?branch=master" alt="Build Status" />](https://github.com/mongomapper/mongomapper/actions?query=workflow%3ARuby+branch%3Amaster)
8
8
 
9
- [<img src="https://coveralls.io/repos/mongomapper/mongomapper/badge.svg" alt="Coverage Status" />](https://coveralls.io/r/mongomapper/mongomapper)
9
+ <!-- [<img src="https://coveralls.io/repos/mongomapper/mongomapper/badge.svg" alt="Coverage Status" />](https://coveralls.io/r/mongomapper/mongomapper) -->
10
10
 
11
11
  ## Install
12
12
 
@@ -18,16 +18,27 @@ http://mongomapper.com/documentation/
18
18
 
19
19
  http://rdoc.info/github/mongomapper/mongomapper
20
20
 
21
+ ## Open Commit Policy
22
+
23
+ Like Rubinius, we're trying out an "open commit policy".
24
+
25
+ If you've committed one (code) patch that has been accepted and would like to
26
+ work some more on the project, send an email to Scott Taylor
27
+ <scott@railsnewbie.com> along with your commit sha1.
28
+
21
29
  ## Compatibility
22
30
 
23
31
  MongoMapper is tested against:
24
32
 
25
- * MRI 2.4 - 2.7
33
+ * MRI 2.4 - 3.0.1
26
34
  * JRuby (Versions with 1.9 compatibility)
27
35
 
28
36
  Additionally, MongoMapper is tested against:
29
37
 
30
- * Rails 5.0+ - 6.0
38
+ * Rails 5.0 - 5.2
39
+ * Rails 6.0 - 6.1
40
+
41
+ Note, if you are using Ruby 3.0+, you'll need Rails 6.
31
42
 
32
43
  ## Contributing & Development
33
44
 
@@ -37,17 +48,21 @@ Additionally, MongoMapper is tested against:
37
48
 
38
49
  * Fork the project.
39
50
  * Make your feature addition or bug fix. All specs should pass.
40
- * Add specs for your changes. This is important so I don't break it in a future version unintentionally.
41
- * Commit, do not mess with Rakefile, version, or history. If you want to have your own version, that is fine but bump version in a commit by itself in another branch so a maintainer ignore it when your pull request is merged.
51
+ * Add specs for your changes. This is important so that it doesn't break in a future version.
52
+ * Commit, do not mess with Rakefile, version, or history. If you want to have your own version, that is fine but bump version in a commit by itself in another branch so a maintainer can ignore it when your pull request is merged.
42
53
  * Send a pull request. Bonus points for topic branches.
43
54
 
55
+ ## How to release
56
+
57
+ See `HOW_TO_RELEASE.md`
58
+
44
59
  ## Problems or Questions?
45
60
 
46
61
  Hit up the Google group: http://groups.google.com/group/mongomapper
47
62
 
48
63
  ## Copyright
49
64
 
50
- Copyright (c) 2009-2020 MongoMapper. See LICENSE for details.
65
+ Copyright (c) 2009-2021 MongoMapper. See LICENSE for details.
51
66
 
52
67
  ## Contributors
53
68
 
@@ -39,6 +39,7 @@ module MongoMapper
39
39
  include Plugins::PartialUpdates
40
40
  include Plugins::IdentityMap
41
41
  include Plugins::CounterCache
42
+ include Plugins::Shardable
42
43
 
43
44
  included do
44
45
  extend Plugins
@@ -24,4 +24,4 @@ end
24
24
 
25
25
  class Array
26
26
  include MongoMapper::Extensions::Array
27
- end
27
+ end
@@ -19,4 +19,4 @@ end
19
19
 
20
20
  class Binary
21
21
  extend MongoMapper::Extensions::Binary
22
- end
22
+ end
@@ -22,4 +22,4 @@ end
22
22
 
23
23
  class Date
24
24
  extend MongoMapper::Extensions::Date
25
- end
25
+ end
@@ -11,4 +11,4 @@ end
11
11
 
12
12
  class Float
13
13
  extend MongoMapper::Extensions::Float
14
- end
14
+ end
@@ -23,4 +23,4 @@ end
23
23
 
24
24
  class Hash
25
25
  include MongoMapper::Extensions::Hash
26
- end
26
+ end
@@ -14,5 +14,5 @@ module MongoMapper
14
14
  end
15
15
 
16
16
  class NilClass
17
- include MongoMapper::Extensions::NilClass
18
- end
17
+ extend MongoMapper::Extensions::NilClass
18
+ end
@@ -27,4 +27,4 @@ end
27
27
 
28
28
  class Object
29
29
  include MongoMapper::Extensions::Object
30
- end
30
+ end
@@ -33,4 +33,4 @@ class BSON::ObjectId
33
33
  def original_to_json(*args)
34
34
  original_as_json.to_json(*args)
35
35
  end
36
- end
36
+ end
@@ -17,4 +17,4 @@ end
17
17
 
18
18
  class Set
19
19
  extend MongoMapper::Extensions::Set
20
- end
20
+ end
@@ -23,4 +23,4 @@ end
23
23
 
24
24
  class String
25
25
  include MongoMapper::Extensions::String
26
- end
26
+ end
@@ -30,12 +30,11 @@ module MongoMapper
30
30
  def setup(model)
31
31
  model.associations_module.module_eval(<<-end_eval, __FILE__, __LINE__ + 1)
32
32
  def #{name}
33
- get_proxy(associations[#{name.inspect}])
33
+ get_proxy(associations[#{name.inspect}]).read
34
34
  end
35
35
 
36
36
  def #{name}=(value)
37
- get_proxy(associations[#{name.inspect}]).replace(value)
38
- value
37
+ get_proxy(associations[#{name.inspect}]).write(value)
39
38
  end
40
39
  end_eval
41
40
 
@@ -47,6 +47,12 @@ module MongoMapper
47
47
  loaded
48
48
  @target
49
49
  end
50
+
51
+ private
52
+
53
+ def stale_target?
54
+ loaded? && proxy_owner[association.foreign_key] != @target&.id
55
+ end
50
56
  end
51
57
  end
52
58
  end
@@ -0,0 +1,55 @@
1
+ # encoding: UTF-8
2
+ module MongoMapper
3
+ module Plugins
4
+ module Associations
5
+ class Collection < Proxy
6
+ include Enumerable
7
+
8
+ def to_a
9
+ load_target
10
+
11
+ target.is_a?(Array) ?
12
+ target :
13
+ Array(target)
14
+ end
15
+
16
+ alias_method :to_ary, :to_a
17
+
18
+ def each(&block)
19
+ to_a.each(&block)
20
+ end
21
+
22
+ def [](val)
23
+ objs = to_a
24
+ objs ? objs[val] : nil
25
+ end
26
+
27
+ def empty?
28
+ to_a.empty?
29
+ end
30
+
31
+ def size
32
+ to_a.size
33
+ end
34
+
35
+ def length
36
+ to_a.length
37
+ end
38
+
39
+ def reset
40
+ super
41
+ target = []
42
+ end
43
+
44
+ def read
45
+ self
46
+ end
47
+
48
+ def write(value)
49
+ replace(value)
50
+ read
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
@@ -76,10 +76,6 @@ module MongoMapper
76
76
  @target.each { |doc| doc.save(options) } if @target
77
77
  end
78
78
 
79
- def each(&block)
80
- load_target.each(&block)
81
- end
82
-
83
79
  protected
84
80
 
85
81
  def query(options={})
@@ -11,7 +11,9 @@ module MongoMapper
11
11
  end
12
12
 
13
13
  def replace(doc)
14
- if doc.respond_to?(:attributes)
14
+ if doc.instance_of?(klass)
15
+ @target = doc
16
+ elsif doc.respond_to?(:attributes)
15
17
  @target = klass.load(doc.attributes, true)
16
18
  else
17
19
  @target = klass.load(doc, true)
@@ -1,19 +1,25 @@
1
1
  # encoding: UTF-8
2
2
  require 'forwardable'
3
+
3
4
  module MongoMapper
4
5
  module Plugins
5
6
  module Associations
6
7
  class Proxy
7
8
  extend Forwardable
8
9
 
9
- alias :proxy_respond_to? :respond_to?
10
- alias :proxy_extend :extend
11
-
12
- instance_methods.each { |m| undef_method m unless m =~ /(^__|^nil\?$|^send$|proxy_|^respond_to_missing\?$|^object_id$)/ }
10
+ class << self
11
+ def define_proxy_method(method)
12
+ define_method(method) do |*args, &block|
13
+ proxy_method(method, *args, &block)
14
+ end
15
+ end
16
+ end
13
17
 
14
18
  attr_reader :proxy_owner, :association, :target
15
19
 
16
- alias :proxy_association :association
20
+ alias_method :proxy_respond_to?, :respond_to?
21
+ alias_method :proxy_extend, :extend
22
+ alias_method :proxy_association, :association
17
23
 
18
24
  def_delegators :proxy_association, :klass, :options
19
25
  def_delegator :klass, :collection
@@ -24,26 +30,31 @@ module MongoMapper
24
30
  reset
25
31
  end
26
32
 
27
- # Active support in rails 3 beta 4 can override to_json after this is loaded,
28
- # at least when run in mongomapper tests. The implementation was changed in master
29
- # some time after this, so not sure whether this is still a problem.
30
- #
31
- # In rails 2, this isn't a problem however it also solves an issue where
32
- # to_json isn't forwarded because it supports to_json itself
33
- def to_json(*options)
34
- load_target
35
- target.to_json(*options)
36
- end
37
-
38
- # see comments to to_json
39
- def as_json(*options)
40
- load_target
41
- target.as_json(*options)
33
+ [
34
+ :is_a?,
35
+ :to_mongo,
36
+ :==,
37
+ :!=,
38
+ :nil?,
39
+ :blank?,
40
+ :present?,
41
+ :hash,
42
+ # Active support in rails 3 beta 4 can override to_json after this is loaded,
43
+ # at least when run in mongomapper tests. The implementation was changed in master
44
+ # some time after this, so not sure whether this is still a problem.
45
+ #
46
+ # In rails 2, this isn't a problem however it also solves an issue where
47
+ # to_json isn't forwarded because it supports to_json itself
48
+ :to_json,
49
+ # see comments to to_json
50
+ :as_json,
51
+ ].each do |m|
52
+ define_proxy_method(m)
42
53
  end
43
54
 
44
55
  def inspect
45
56
  load_target
46
- target.inspect
57
+ "#<#{self.class.inspect}:#{object_id} #{@target.inspect}>"
47
58
  end
48
59
 
49
60
  def loaded?
@@ -54,21 +65,6 @@ module MongoMapper
54
65
  @loaded = true
55
66
  end
56
67
 
57
- def nil?
58
- load_target
59
- target.nil?
60
- end
61
-
62
- def blank?
63
- load_target
64
- target.blank?
65
- end
66
-
67
- def present?
68
- load_target
69
- target.present?
70
- end
71
-
72
68
  def reload
73
69
  reset
74
70
  load_target
@@ -87,16 +83,7 @@ module MongoMapper
87
83
  end
88
84
 
89
85
  def respond_to?(*args)
90
- proxy_respond_to?(*args) || (load_target && target.respond_to?(*args))
91
- end
92
-
93
- def send(method, *args, &block)
94
- if proxy_respond_to?(method, true)
95
- super
96
- else
97
- load_target
98
- target.send(method, *args, &block)
99
- end
86
+ super || (load_target && target.respond_to?(*args))
100
87
  end
101
88
 
102
89
  def read
@@ -104,10 +91,20 @@ module MongoMapper
104
91
  @target
105
92
  end
106
93
 
94
+ def write(value)
95
+ replace(value)
96
+ read
97
+ end
98
+
99
+ def proxy_method(method, *args, &block)
100
+ load_target
101
+ target.public_send(method, *args, &block)
102
+ end
103
+
107
104
  protected
108
105
 
109
106
  def load_target
110
- unless loaded?
107
+ if !loaded? || stale_target?
111
108
  if @target.is_a?(Array) && @target.any?
112
109
  @target = find_target + @target.find_all { |record| !record.persisted? }
113
110
  else
@@ -134,9 +131,32 @@ module MongoMapper
134
131
 
135
132
  private
136
133
 
134
+ def stale_target?
135
+ false
136
+ end
137
+
138
+ def define_proxy_method(method)
139
+ metaclass = class << self; self; end
140
+ metaclass.class_eval do
141
+ define_proxy_method(method)
142
+ end
143
+ end
144
+
145
+ def define_and_call_proxy_method(method, *args, &block)
146
+ define_proxy_method(method)
147
+ public_send(method, *args, &block)
148
+ end
149
+
137
150
  def method_missing(method, *args, &block)
138
- if load_target
139
- target.send(method, *args, &block)
151
+ # load the target just in case it isn't loaded
152
+ load_target
153
+
154
+ # only define the method if the target has the method
155
+ # NOTE: include private methods!
156
+ if target.respond_to?(method, true)
157
+ define_and_call_proxy_method(method, *args, &block)
158
+ else
159
+ super
140
160
  end
141
161
  end
142
162
  end
@@ -8,20 +8,11 @@ module MongoMapper
8
8
 
9
9
  model.associations_module.module_eval(<<-end_eval, __FILE__, __LINE__ + 1)
10
10
  def #{name}
11
- proxy = get_proxy(associations[#{name.inspect}])
12
- proxy.nil? ? nil : proxy.read
11
+ get_proxy(associations[#{name.inspect}]).read
13
12
  end
14
13
 
15
14
  def #{name}=(value)
16
- association = associations[#{name.inspect}]
17
- proxy = get_proxy(association)
18
-
19
- if proxy.nil? || proxy.target != value
20
- proxy = build_proxy(association)
21
- end
22
-
23
- proxy.replace(value)
24
- proxy.read
15
+ get_proxy(associations[#{name.inspect}]).write(value)
25
16
  end
26
17
 
27
18
  def #{name}?
@@ -13,7 +13,7 @@ module MongoMapper
13
13
  end
14
14
  end
15
15
 
16
- def create_or_update(*)
16
+ def save_to_collection(*)
17
17
  super.tap do
18
18
  changes_applied
19
19
  end
@@ -38,7 +38,7 @@ module MongoMapper
38
38
 
39
39
  # typecast to the new value
40
40
  old_value = read_key(key_name)
41
- new_value = key.type.to_mongo(value)
41
+ new_value = key.set(value)
42
42
 
43
43
  # only mark changed if really changed value (after typecasting)
44
44
  unless old_value == new_value
@@ -46,7 +46,7 @@ module MongoMapper
46
46
  end
47
47
 
48
48
  def _root_document
49
- @_root_document ||= _parent_document.try(:_root_document)
49
+ _parent_document.try(:_root_document)
50
50
  end
51
51
  end
52
52
  end
@@ -61,7 +61,7 @@ module MongoMapper
61
61
  # Special Case: Generate default _id on access
62
62
  value = default_value if @is_id and !value
63
63
 
64
- value = type.from_mongo(value)
64
+ value = type ? type.from_mongo(value) : value
65
65
 
66
66
  if @typecast
67
67
  klass = typecast_class # Don't make this lookup on every call
@@ -76,22 +76,25 @@ module MongoMapper
76
76
 
77
77
  def set(value)
78
78
  # Avoid tap here so we don't have to create a block binding.
79
- values = type.to_mongo(value)
79
+ value = type ? type.to_mongo(value) : value.to_mongo
80
+
80
81
  if @typecast
81
- values.map { |v| typecast_class.to_mongo(v) }
82
+ klass = typecast_class # Don't make this lookup on every call
83
+ value.map { |v| klass.to_mongo(v) }
82
84
  else
83
- values
85
+ value
84
86
  end
85
87
  end
86
88
 
87
89
  def default_value
88
90
  return unless default?
91
+
89
92
  if default.instance_of? Proc
90
- type.to_mongo default.call
93
+ default.call
91
94
  else
92
95
  # Using Marshal is easiest way to get a copy of mutable objects
93
96
  # without getting an error on immutable objects
94
- type.to_mongo Marshal.load(Marshal.dump(default))
97
+ Marshal.load(Marshal.dump(default))
95
98
  end
96
99
  end
97
100
 
@@ -144,9 +144,8 @@ module MongoMapper
144
144
  end
145
145
 
146
146
  def create_accessors_for(key)
147
- accessors = ""
148
147
  if key.read_accessor?
149
- accessors << <<-end_eval
148
+ accessors_module.module_eval(<<-end_eval, __FILE__, __LINE__+1)
150
149
  def #{key.name}
151
150
  read_key(:#{key.name})
152
151
  end
@@ -158,7 +157,7 @@ module MongoMapper
158
157
  end
159
158
 
160
159
  if key.write_accessor?
161
- accessors << <<-end_eval
160
+ accessors_module.module_eval(<<-end_eval, __FILE__, __LINE__+1)
162
161
  def #{key.name}=(value)
163
162
  write_key(:#{key.name}, value)
164
163
  end
@@ -166,7 +165,7 @@ module MongoMapper
166
165
  end
167
166
 
168
167
  if key.predicate_accessor?
169
- accessors << <<-end_eval
168
+ accessors_module.module_eval(<<-end_eval, __FILE__, __LINE__+1)
170
169
  def #{key.name}?
171
170
  read_key(:#{key.name}).present?
172
171
  end
@@ -179,7 +178,6 @@ module MongoMapper
179
178
  end
180
179
  end
181
180
 
182
- accessors_module.module_eval accessors
183
181
  include accessors_module
184
182
  end
185
183
 
@@ -253,12 +251,24 @@ module MongoMapper
253
251
 
254
252
  def remove_validate_callbacks(a_name)
255
253
  chain = _validate_callbacks.dup.reject do |callback|
256
- f = callback.raw_filter
254
+ f = callback_filter(callback)
257
255
  f.respond_to?(:attributes) && f.attributes == a_name
258
256
  end
259
257
  reset_callbacks(:validate)
260
258
  chain.each do |callback|
261
- set_callback 'validate', callback.raw_filter
259
+ set_callback 'validate', callback_filter(callback)
260
+ end
261
+ end
262
+
263
+ # The interface to obtain @filter from ActiveSupport::Callbacks::Callback has changed since rails 7.0.
264
+ # https://github.com/rails/rails/commit/d5ac941ddc3de7ad1aaff80ed67aa04fb626a263#diff-bf79b7ea0085308139af6de0afad9a9f22f13d4563cc56d784994414d88c5dd1
265
+ if ActiveSupport::VERSION::MAJOR >= 7
266
+ def callback_filter(callback)
267
+ callback.filter
268
+ end
269
+ else
270
+ def callback_filter(callback)
271
+ callback.raw_filter
262
272
  end
263
273
  end
264
274
  end
@@ -148,7 +148,7 @@ module MongoMapper
148
148
  when :insert
149
149
  collection.insert_one(update, query_options)
150
150
  when :save
151
- collection.update_one({:_id => _id}, update, query_options.merge(upsert: true))
151
+ collection.update_one({:_id => _id}.merge(shard_key_filter), update, query_options.merge(upsert: true))
152
152
  when :update
153
153
  update.stringify_keys!
154
154
 
@@ -180,4 +180,4 @@ module MongoMapper
180
180
  end
181
181
  end
182
182
  end
183
- end
183
+ end