mongoid 5.4.1 → 6.0.0.beta

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 (264) hide show
  1. checksums.yaml +5 -5
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/lib/config/locales/en.yml +23 -16
  5. data/lib/mongoid.rb +4 -9
  6. data/lib/mongoid/atomic.rb +1 -1
  7. data/lib/mongoid/atomic/modifiers.rb +8 -12
  8. data/lib/mongoid/attributes.rb +9 -11
  9. data/lib/mongoid/attributes/dynamic.rb +5 -6
  10. data/lib/mongoid/attributes/nested.rb +1 -1
  11. data/lib/mongoid/attributes/processing.rb +4 -0
  12. data/lib/mongoid/attributes/readonly.rb +22 -0
  13. data/lib/mongoid/cacheable.rb +36 -0
  14. data/lib/mongoid/changeable.rb +37 -1
  15. data/lib/mongoid/clients.rb +0 -63
  16. data/lib/mongoid/clients/factory.rb +0 -2
  17. data/lib/mongoid/clients/options.rb +54 -249
  18. data/lib/mongoid/clients/storage_options.rb +1 -69
  19. data/lib/mongoid/composable.rb +26 -2
  20. data/lib/mongoid/config.rb +1 -1
  21. data/lib/mongoid/config/options.rb +1 -1
  22. data/lib/mongoid/contextual/aggregable/mongo.rb +1 -0
  23. data/lib/mongoid/contextual/atomic.rb +6 -9
  24. data/lib/mongoid/contextual/geo_near.rb +2 -3
  25. data/lib/mongoid/contextual/map_reduce.rb +97 -24
  26. data/lib/mongoid/contextual/memory.rb +7 -4
  27. data/lib/mongoid/contextual/mongo.rb +63 -54
  28. data/lib/mongoid/contextual/none.rb +2 -2
  29. data/lib/mongoid/copyable.rb +19 -19
  30. data/lib/mongoid/criteria.rb +5 -4
  31. data/lib/mongoid/criteria/findable.rb +2 -3
  32. data/lib/mongoid/criteria/includable.rb +63 -16
  33. data/lib/mongoid/criteria/marshalable.rb +2 -2
  34. data/lib/mongoid/criteria/modifiable.rb +17 -1
  35. data/lib/mongoid/criteria/options.rb +25 -0
  36. data/lib/mongoid/criteria/queryable.rb +86 -0
  37. data/lib/mongoid/criteria/queryable/aggregable.rb +120 -0
  38. data/lib/mongoid/criteria/queryable/extensions.rb +28 -0
  39. data/lib/mongoid/criteria/queryable/extensions/array.rb +185 -0
  40. data/lib/mongoid/criteria/queryable/extensions/big_decimal.rb +37 -0
  41. data/lib/mongoid/criteria/queryable/extensions/boolean.rb +34 -0
  42. data/lib/mongoid/criteria/queryable/extensions/date.rb +63 -0
  43. data/lib/mongoid/criteria/queryable/extensions/date_time.rb +53 -0
  44. data/lib/mongoid/criteria/queryable/extensions/hash.rb +200 -0
  45. data/lib/mongoid/criteria/queryable/extensions/nil_class.rb +86 -0
  46. data/lib/mongoid/criteria/queryable/extensions/numeric.rb +90 -0
  47. data/lib/mongoid/criteria/queryable/extensions/object.rb +206 -0
  48. data/lib/mongoid/criteria/queryable/extensions/range.rb +70 -0
  49. data/lib/mongoid/criteria/queryable/extensions/regexp.rb +45 -0
  50. data/lib/mongoid/criteria/queryable/extensions/set.rb +34 -0
  51. data/lib/mongoid/criteria/queryable/extensions/string.rb +137 -0
  52. data/lib/mongoid/criteria/queryable/extensions/symbol.rb +79 -0
  53. data/lib/mongoid/criteria/queryable/extensions/time.rb +60 -0
  54. data/lib/mongoid/criteria/queryable/extensions/time_with_zone.rb +54 -0
  55. data/lib/mongoid/criteria/queryable/forwardable.rb +65 -0
  56. data/lib/mongoid/criteria/queryable/key.rb +103 -0
  57. data/lib/mongoid/criteria/queryable/macroable.rb +27 -0
  58. data/lib/mongoid/criteria/queryable/mergeable.rb +271 -0
  59. data/lib/mongoid/criteria/queryable/optional.rb +411 -0
  60. data/lib/mongoid/criteria/queryable/options.rb +136 -0
  61. data/lib/mongoid/criteria/queryable/pipeline.rb +111 -0
  62. data/lib/mongoid/criteria/queryable/selectable.rb +662 -0
  63. data/lib/mongoid/criteria/queryable/selector.rb +196 -0
  64. data/lib/mongoid/criteria/queryable/smash.rb +103 -0
  65. data/lib/mongoid/document.rb +9 -23
  66. data/lib/mongoid/errors.rb +2 -1
  67. data/lib/mongoid/errors/ambiguous_relationship.rb +1 -1
  68. data/lib/mongoid/errors/delete_restriction.rb +2 -2
  69. data/lib/mongoid/errors/invalid_field.rb +2 -2
  70. data/lib/mongoid/errors/invalid_persistence_option.rb +29 -0
  71. data/lib/mongoid/errors/invalid_relation.rb +66 -0
  72. data/lib/mongoid/errors/inverse_not_found.rb +1 -1
  73. data/lib/mongoid/errors/mongoid_error.rb +1 -1
  74. data/lib/mongoid/evolvable.rb +1 -1
  75. data/lib/mongoid/extensions.rb +0 -5
  76. data/lib/mongoid/extensions/big_decimal.rb +17 -8
  77. data/lib/mongoid/extensions/date.rb +4 -1
  78. data/lib/mongoid/extensions/hash.rb +2 -3
  79. data/lib/mongoid/extensions/object.rb +2 -2
  80. data/lib/mongoid/extensions/string.rb +4 -3
  81. data/lib/mongoid/extensions/time.rb +5 -2
  82. data/lib/mongoid/factory.rb +1 -0
  83. data/lib/mongoid/fields/foreign_key.rb +2 -2
  84. data/lib/mongoid/fields/localized.rb +3 -8
  85. data/lib/mongoid/fields/validators/macro.rb +18 -0
  86. data/lib/mongoid/findable.rb +3 -3
  87. data/lib/mongoid/indexable.rb +17 -16
  88. data/lib/mongoid/indexable/specification.rb +1 -1
  89. data/lib/mongoid/indexable/validators/options.rb +1 -2
  90. data/lib/mongoid/interceptable.rb +6 -17
  91. data/lib/mongoid/loggable.rb +1 -1
  92. data/lib/mongoid/matchable.rb +3 -10
  93. data/lib/mongoid/matchable/gt.rb +2 -0
  94. data/lib/mongoid/matchable/gte.rb +2 -0
  95. data/lib/mongoid/matchable/lt.rb +2 -0
  96. data/lib/mongoid/matchable/lte.rb +2 -0
  97. data/lib/mongoid/persistable.rb +6 -5
  98. data/lib/mongoid/persistable/creatable.rb +2 -0
  99. data/lib/mongoid/persistable/deletable.rb +7 -3
  100. data/lib/mongoid/persistable/settable.rb +3 -16
  101. data/lib/mongoid/persistable/updatable.rb +10 -12
  102. data/lib/mongoid/persistence_context.rb +216 -0
  103. data/lib/mongoid/query_cache.rb +5 -30
  104. data/lib/mongoid/relations/accessors.rb +6 -2
  105. data/lib/mongoid/relations/auto_save.rb +12 -4
  106. data/lib/mongoid/relations/bindings/embedded/in.rb +4 -0
  107. data/lib/mongoid/relations/bindings/embedded/many.rb +8 -1
  108. data/lib/mongoid/relations/bindings/embedded/one.rb +10 -0
  109. data/lib/mongoid/relations/bindings/referenced/many.rb +4 -0
  110. data/lib/mongoid/relations/builders.rb +2 -2
  111. data/lib/mongoid/relations/builders/embedded/one.rb +1 -1
  112. data/lib/mongoid/relations/builders/nested_attributes/many.rb +1 -1
  113. data/lib/mongoid/relations/conversions.rb +1 -1
  114. data/lib/mongoid/relations/counter_cache.rb +28 -18
  115. data/lib/mongoid/relations/eager.rb +19 -7
  116. data/lib/mongoid/relations/eager/base.rb +5 -5
  117. data/lib/mongoid/relations/embedded/batchable.rb +9 -33
  118. data/lib/mongoid/relations/embedded/in.rb +16 -2
  119. data/lib/mongoid/relations/embedded/many.rb +23 -8
  120. data/lib/mongoid/relations/embedded/one.rb +17 -2
  121. data/lib/mongoid/relations/macros.rb +9 -2
  122. data/lib/mongoid/relations/metadata.rb +3 -3
  123. data/lib/mongoid/relations/nested_builder.rb +1 -1
  124. data/lib/mongoid/relations/options.rb +2 -2
  125. data/lib/mongoid/relations/proxy.rb +2 -33
  126. data/lib/mongoid/relations/referenced/in.rb +23 -11
  127. data/lib/mongoid/relations/referenced/many.rb +24 -16
  128. data/lib/mongoid/relations/referenced/many_to_many.rb +20 -13
  129. data/lib/mongoid/relations/referenced/one.rb +17 -1
  130. data/lib/mongoid/relations/reflections.rb +3 -5
  131. data/lib/mongoid/relations/touchable.rb +1 -1
  132. data/lib/mongoid/reloadable.rb +1 -1
  133. data/lib/mongoid/scopable.rb +3 -3
  134. data/lib/mongoid/serializable.rb +2 -3
  135. data/lib/mongoid/tasks/database.rb +1 -2
  136. data/lib/mongoid/threaded.rb +4 -4
  137. data/lib/mongoid/traversable.rb +1 -1
  138. data/lib/mongoid/validatable.rb +1 -1
  139. data/lib/mongoid/validatable/macros.rb +2 -4
  140. data/lib/mongoid/validatable/uniqueness.rb +1 -2
  141. data/lib/mongoid/version.rb +1 -1
  142. data/lib/rails/generators/mongoid/config/templates/mongoid.yml +4 -7
  143. data/spec/app/models/album.rb +5 -1
  144. data/spec/app/models/artist.rb +21 -0
  145. data/spec/app/models/band.rb +0 -1
  146. data/spec/app/models/church.rb +0 -2
  147. data/spec/app/models/ordered_post.rb +5 -0
  148. data/spec/app/models/oscar.rb +1 -2
  149. data/spec/app/models/person.rb +3 -1
  150. data/spec/app/models/post.rb +0 -1
  151. data/spec/app/models/princess.rb +2 -0
  152. data/spec/app/models/record.rb +1 -0
  153. data/spec/app/models/thing.rb +1 -1
  154. data/spec/config/mongoid.yml +1 -5
  155. data/spec/mongoid/atomic/modifiers_spec.rb +17 -17
  156. data/spec/mongoid/atomic_spec.rb +17 -17
  157. data/spec/mongoid/attributes/nested_spec.rb +14 -14
  158. data/spec/mongoid/attributes/readonly_spec.rb +87 -44
  159. data/spec/mongoid/attributes_spec.rb +63 -0
  160. data/spec/mongoid/cacheable_spec.rb +112 -0
  161. data/spec/mongoid/changeable_spec.rb +58 -0
  162. data/spec/mongoid/clients/factory_spec.rb +3 -11
  163. data/spec/mongoid/clients/options_spec.rb +378 -96
  164. data/spec/mongoid/clients_spec.rb +207 -170
  165. data/spec/mongoid/composable_spec.rb +7 -0
  166. data/spec/mongoid/config_spec.rb +41 -21
  167. data/spec/mongoid/contextual/atomic_spec.rb +77 -343
  168. data/spec/mongoid/contextual/map_reduce_spec.rb +119 -111
  169. data/spec/mongoid/contextual/memory_spec.rb +56 -316
  170. data/spec/mongoid/contextual/mongo_spec.rb +104 -378
  171. data/spec/mongoid/copyable_spec.rb +8 -15
  172. data/spec/mongoid/criteria/modifiable_spec.rb +239 -7
  173. data/spec/mongoid/criteria/options_spec.rb +29 -0
  174. data/spec/mongoid/criteria/queryable/aggregable_spec.rb +370 -0
  175. data/spec/mongoid/criteria/queryable/extensions/array_spec.rb +523 -0
  176. data/spec/mongoid/criteria/queryable/extensions/big_decimal_spec.rb +59 -0
  177. data/spec/mongoid/criteria/queryable/extensions/bignum_spec.rb +58 -0
  178. data/spec/mongoid/criteria/queryable/extensions/boolean_spec.rb +213 -0
  179. data/spec/mongoid/criteria/queryable/extensions/date_spec.rb +330 -0
  180. data/spec/mongoid/criteria/queryable/extensions/date_time_spec.rb +405 -0
  181. data/spec/mongoid/criteria/queryable/extensions/fixnum_spec.rb +58 -0
  182. data/spec/mongoid/criteria/queryable/extensions/float_spec.rb +65 -0
  183. data/spec/mongoid/criteria/queryable/extensions/hash_spec.rb +327 -0
  184. data/spec/mongoid/criteria/queryable/extensions/integer_spec.rb +65 -0
  185. data/spec/mongoid/criteria/queryable/extensions/nil_class_spec.rb +77 -0
  186. data/spec/mongoid/criteria/queryable/extensions/object_spec.rb +108 -0
  187. data/spec/mongoid/criteria/queryable/extensions/range_spec.rb +309 -0
  188. data/spec/mongoid/{extensions/origin/regexp_raw_spec.rb → criteria/queryable/extensions/regexp_spec.rb} +21 -20
  189. data/spec/mongoid/criteria/queryable/extensions/set_spec.rb +39 -0
  190. data/spec/mongoid/criteria/queryable/extensions/string_spec.rb +302 -0
  191. data/spec/mongoid/criteria/queryable/extensions/symbol_spec.rb +167 -0
  192. data/spec/mongoid/criteria/queryable/extensions/time_spec.rb +376 -0
  193. data/spec/mongoid/criteria/queryable/extensions/time_with_zone_spec.rb +347 -0
  194. data/spec/mongoid/criteria/queryable/forwardable_spec.rb +87 -0
  195. data/spec/mongoid/criteria/queryable/key_spec.rb +52 -0
  196. data/spec/mongoid/criteria/queryable/mergeable_spec.rb +49 -0
  197. data/spec/mongoid/criteria/queryable/optional_spec.rb +1786 -0
  198. data/spec/mongoid/criteria/queryable/options_spec.rb +360 -0
  199. data/spec/mongoid/criteria/queryable/pipeline_spec.rb +200 -0
  200. data/spec/mongoid/criteria/queryable/queryable_spec.rb +137 -0
  201. data/spec/mongoid/criteria/queryable/selectable_spec.rb +4159 -0
  202. data/spec/mongoid/criteria/queryable/selector_spec.rb +778 -0
  203. data/spec/mongoid/criteria/queryable/smash_spec.rb +30 -0
  204. data/spec/mongoid/criteria_spec.rb +45 -63
  205. data/spec/mongoid/document_spec.rb +21 -88
  206. data/spec/mongoid/errors/invalid_relation_spec.rb +37 -0
  207. data/spec/mongoid/errors/mongoid_error_spec.rb +6 -3
  208. data/spec/mongoid/extensions/big_decimal_spec.rb +320 -18
  209. data/spec/mongoid/extensions/date_spec.rb +2 -6
  210. data/spec/mongoid/extensions/date_time_spec.rb +2 -6
  211. data/spec/mongoid/extensions/float_spec.rb +8 -1
  212. data/spec/mongoid/extensions/integer_spec.rb +8 -1
  213. data/spec/mongoid/extensions/object_spec.rb +11 -0
  214. data/spec/mongoid/extensions/string_spec.rb +21 -0
  215. data/spec/mongoid/extensions/time_spec.rb +4 -8
  216. data/spec/mongoid/extensions/time_with_zone_spec.rb +2 -6
  217. data/spec/mongoid/fields/localized_spec.rb +0 -91
  218. data/spec/mongoid/findable_spec.rb +46 -1
  219. data/spec/mongoid/indexable_spec.rb +6 -46
  220. data/spec/mongoid/interceptable_spec.rb +49 -10
  221. data/spec/mongoid/matchable/gt_spec.rb +11 -0
  222. data/spec/mongoid/matchable/gte_spec.rb +10 -0
  223. data/spec/mongoid/matchable/lt_spec.rb +11 -0
  224. data/spec/mongoid/matchable/lte_spec.rb +11 -0
  225. data/spec/mongoid/matchable_spec.rb +1 -51
  226. data/spec/mongoid/persistable/creatable_spec.rb +2 -2
  227. data/spec/mongoid/persistable/deletable_spec.rb +1 -1
  228. data/spec/mongoid/persistable/destroyable_spec.rb +6 -2
  229. data/spec/mongoid/persistable/savable_spec.rb +30 -30
  230. data/spec/mongoid/persistable/settable_spec.rb +0 -185
  231. data/spec/mongoid/persistable/updatable_spec.rb +166 -5
  232. data/spec/mongoid/persistence_context_spec.rb +654 -0
  233. data/spec/mongoid/positional_spec.rb +10 -10
  234. data/spec/mongoid/query_cache_spec.rb +89 -65
  235. data/spec/mongoid/relations/accessors_spec.rb +1 -1
  236. data/spec/mongoid/relations/auto_save_spec.rb +39 -6
  237. data/spec/mongoid/relations/builders_spec.rb +37 -10
  238. data/spec/mongoid/relations/counter_cache_spec.rb +64 -15
  239. data/spec/mongoid/relations/cyclic_spec.rb +0 -22
  240. data/spec/mongoid/relations/embedded/many_spec.rb +9 -41
  241. data/spec/mongoid/relations/embedded/one_spec.rb +2 -1
  242. data/spec/mongoid/relations/macros_spec.rb +395 -7
  243. data/spec/mongoid/relations/proxy_spec.rb +3 -1
  244. data/spec/mongoid/relations/referenced/in_spec.rb +41 -1
  245. data/spec/mongoid/relations/referenced/many_spec.rb +6 -29
  246. data/spec/mongoid/relations/referenced/many_to_many_spec.rb +6 -29
  247. data/spec/mongoid/relations/reflections_spec.rb +9 -9
  248. data/spec/mongoid/reloadable_spec.rb +51 -0
  249. data/spec/mongoid/scopable_spec.rb +0 -12
  250. data/spec/mongoid/serializable_spec.rb +0 -50
  251. data/spec/mongoid/validatable/presence_spec.rb +1 -1
  252. data/spec/mongoid/validatable/uniqueness_spec.rb +16 -9
  253. data/spec/mongoid/validatable_spec.rb +16 -0
  254. data/spec/spec_helper.rb +10 -10
  255. metadata +536 -479
  256. metadata.gz.sig +0 -0
  257. data/lib/mongoid/clients/thread_options.rb +0 -19
  258. data/lib/mongoid/errors/in_memory_collation_not_supported.rb +0 -20
  259. data/lib/mongoid/extensions/decimal128.rb +0 -39
  260. data/lib/mongoid/extensions/origin/regexp_raw.rb +0 -43
  261. data/lib/mongoid/matchable/regexp.rb +0 -27
  262. data/spec/app/models/post_genre.rb +0 -6
  263. data/spec/mongoid/extensions/decimal128_spec.rb +0 -44
  264. data/spec/mongoid/matchable/regexp_spec.rb +0 -59
@@ -2,14 +2,12 @@
2
2
  require "mongoid/clients/factory"
3
3
  require "mongoid/clients/validators"
4
4
  require "mongoid/clients/storage_options"
5
- require "mongoid/clients/thread_options"
6
5
  require "mongoid/clients/options"
7
6
 
8
7
  module Mongoid
9
8
  module Clients
10
9
  extend ActiveSupport::Concern
11
10
  include StorageOptions
12
- include ThreadOptions
13
11
  include Options
14
12
 
15
13
  class << self
@@ -74,66 +72,5 @@ module Mongoid
74
72
  @clients ||= {}
75
73
  end
76
74
  end
77
-
78
- # Get the collection for this model from the client. Will check for an
79
- # overridden collection name from the store_in macro or the collection
80
- # with a pluralized model name.
81
- #
82
- # @example Get the model's collection.
83
- # Model.collection
84
- #
85
- # @return [ Mongo::Collection ] The collection.
86
- #
87
- # @since 3.0.0
88
- def collection
89
- mongo_client[collection_name]
90
- end
91
-
92
- def mongo_client
93
- super || self.class.mongo_client
94
- end
95
-
96
- def collection_name
97
- super || self.class.collection_name
98
- end
99
-
100
- module ClassMethods
101
-
102
- # Get the client for this model. This is determined in the following order:
103
- #
104
- # 1. Any custom configuration provided by the 'store_in' macro.
105
- # 2. The 'default' client as provided in the mongoid.yml
106
- #
107
- # @example Get the client.
108
- # Model.mongo_client
109
- #
110
- # @return [ Mongo::Client ] The default mongo client.
111
- #
112
- # @since 3.0.0
113
- def mongo_client
114
- return client_with_options if client_with_options
115
- client = Clients.with_name(client_name)
116
- opts = self.persistence_options ? self.persistence_options.dup : {}
117
- if defined?(Mongo::Client::VALID_OPTIONS)
118
- opts.reject! { |k, v| !Mongo::Client::VALID_OPTIONS.include?(k.to_sym) }
119
- end
120
- opts.merge!(database: database_name) unless client.database.name.to_sym == database_name.to_sym
121
- client.with(opts)
122
- end
123
-
124
- # Get the collection for this model from the client. Will check for an
125
- # overridden collection name from the store_in macro or the collection
126
- # with a pluralized model name.
127
- #
128
- # @example Get the model's collection.
129
- # Model.collection
130
- #
131
- # @return [ Mongo::Collection ] The collection.
132
- #
133
- # @since 3.0.0
134
- def collection
135
- mongo_client[collection_name]
136
- end
137
- end
138
75
  end
139
76
  end
@@ -71,8 +71,6 @@ module Mongoid
71
71
  def options(configuration)
72
72
  config = configuration.dup
73
73
  options = config.delete(:options) || {}
74
- options[:platform] = PLATFORM_DETAILS
75
- options[:app_name] = Mongoid::Config.app_name if Mongoid::Config.app_name
76
74
  options.reject{ |k, v| k == :hosts }.to_hash.symbolize_keys!
77
75
  end
78
76
  end
@@ -4,241 +4,85 @@ module Mongoid
4
4
  module Options
5
5
  extend ActiveSupport::Concern
6
6
 
7
- # Tell the next persistence operation to store in a specific collection,
8
- # database or client.
7
+ # Change the persistence context for this object during the block.
9
8
  #
10
9
  # @example Save the current document to a different collection.
11
- # model.with(collection: "secondary").save
10
+ # model.with(collection: "secondary") do |m|
11
+ # m.save
12
+ # end
12
13
  #
13
- # @example Save the current document to a different database.
14
- # model.with(database: "secondary").save
15
- #
16
- # @example Save the current document to a different client.
17
- # model.with(client: "replica_set").save
18
- #
19
- # @example Save with a combination of options.
20
- # model.with(client: "sharded", database: "secondary").save
21
- #
22
- # @note This method will instantiate a new client under the covers and
23
- # can be expensive. It is also recommended that the user manually
24
- # closes the extra client after using it, otherwise an excessive amount
25
- # of connections to the server will be eventually opened.
26
- #
27
- # @param [ Hash ] options The storage options.
14
+ # @param [ Hash, Mongoid::PersistenceContext ] options_or_context
15
+ # The storage options or a persistence context.
28
16
  #
29
17
  # @option options [ String, Symbol ] :collection The collection name.
30
18
  # @option options [ String, Symbol ] :database The database name.
31
19
  # @option options [ String, Symbol ] :client The client name.
32
20
  #
33
- # @return [ Document ] The current document.
34
- #
35
- # @since 3.0.0
36
- def with(options)
37
- @persistence_options = options
38
- self
21
+ # @since 6.0.0
22
+ def with(options_or_context, &block)
23
+ original_cluster = persistence_context.cluster
24
+ set_persistence_context(options_or_context)
25
+ yield self
26
+ ensure
27
+ clear_persistence_context(original_cluster)
39
28
  end
40
29
 
41
- def persistence_options
42
- @persistence_options
43
- end
44
-
45
- def mongo_client
46
- tmp = persistence_options
47
- if (opts = tmp && !tmp.empty? && tmp.dup)
48
- if opts[:client]
49
- client = Clients.with_name(opts[:client])
50
- else
51
- client = Clients.with_name(self.class.client_name)
52
- client = client.use(self.class.database_name)
53
- end
54
- client.with(opts.reject{ |k, v| k == :collection || k == :client })
55
- end
30
+ def collection(parent = nil)
31
+ persistence_context.collection(parent)
56
32
  end
57
33
 
58
34
  def collection_name
59
- if persistence_options && v = persistence_options[:collection]
60
- return v.to_sym
61
- end
35
+ persistence_context.collection_name
62
36
  end
63
37
 
64
- module Threaded
65
-
66
- # Get the persistence options for the current thread.
67
- #
68
- # @example Get the persistence options.
69
- # Threaded.persistence_options(Band)
70
- #
71
- # @param [ Class ] klass The model class.
72
- #
73
- # @return [ Hash ] The current persistence options.
74
- #
75
- # @since 4.0.0
76
- def persistence_options(klass = self)
77
- Thread.current["[mongoid][#{klass}]:persistence-options"]
78
- end
79
-
80
- # Get the client with special options for the current thread.
81
- #
82
- # @example Get the client with options.
83
- # Threaded.client_with_options(Band)
84
- #
85
- # @param [ Class ] klass The model class.
86
- #
87
- # @return [ Mongo::Client ] The client.
88
- #
89
- # @since 5.1.0
90
- def client_with_options(klass = self)
91
- Thread.current["[mongoid][#{klass}]:mongo-client"]
92
- end
93
-
94
- private
95
- # Set the persistence options on the current thread.
96
- #
97
- # @api private
98
- #
99
- # @example Set the persistence options.
100
- # Threaded.set_persistence_options(Band, { write: { w: 3 }})
101
- #
102
- # @param [ Class ] klass The model class.
103
- # @param [ Hash ] options The persistence options.
104
- #
105
- # @return [ Hash ] The persistence options.
106
- #
107
- # @since 4.0.0
108
- def set_persistence_options(klass, options)
109
- Thread.current["[mongoid][#{klass}]:persistence-options"] = options
110
- end
111
-
112
- # Unset the persistence options on the current thread.
113
- #
114
- # @api private
115
- #
116
- # @example Unset the persistence options.
117
- # Threaded.unset_persistence_options(Band)
118
- #
119
- # @param [ Class ] klass The model class.
120
- #
121
- # @return [ nil ] nil.
122
- #
123
- # @since 5.1.0
124
- def unset_persistence_options(klass)
125
- Thread.current["[mongoid][#{klass}]:persistence-options"] = nil
126
- end
38
+ def mongo_client
39
+ persistence_context.client
40
+ end
127
41
 
128
- # Set the persistence options and client with those options on the current thread.
129
- # Note that a client will only be set if its cluster differs from the cluster of the
130
- # original client.
131
- #
132
- # @api private
133
- #
134
- # @example Set the persistence options and client with those options on the current thread.
135
- # Threaded.set_options(Band, { write: { w: 3 }})
136
- #
137
- # @param [ Class ] klass The model class.
138
- # @param [ Mongo::Client ] options The options.
139
- #
140
- # @return [ Mongo::Client, nil ] The client or nil if the cluster does not change.
141
- #
142
- # @since 5.1.0
143
- def set_options(klass, options)
144
- original_cluster = mongo_client.cluster
145
- set_persistence_options(klass, options)
146
- m = mongo_client
147
- set_client_with_options(klass, m) unless m.cluster.equal?(original_cluster)
148
- end
42
+ def persistence_context
43
+ PersistenceContext.get(self) ||
44
+ PersistenceContext.get(self.class) ||
45
+ PersistenceContext.new(self.class)
46
+ end
149
47
 
150
- # Set the client with special options on the current thread.
151
- #
152
- # @api private
153
- #
154
- # @example Set the client with options.
155
- # Threaded.set_client_with_options(Band, client)
156
- #
157
- # @param [ Class ] klass The model class.
158
- # @param [ Mongo::Client ] client The client with options.
159
- #
160
- # @return [ Mongo::Client ] The client.
161
- #
162
- # @since 5.1.0
163
- def set_client_with_options(klass, client)
164
- Thread.current["[mongoid][#{klass}]:mongo-client"] = client
165
- end
48
+ private
166
49
 
167
- # Unset the client with special options on the current thread.
168
- #
169
- # @api private
170
- #
171
- # @example Unset the client with options.
172
- # Threaded.unset_client_with_options(Band)
173
- #
174
- # @param [ Class ] klass The model class.
175
- #
176
- # @return [ nil ] nil.
177
- #
178
- # @since 5.1.0
179
- def unset_client_with_options(klass)
180
- if client = Thread.current["[mongoid][#{klass}]:mongo-client"]
181
- client.close
182
- Thread.current["[mongoid][#{klass}]:mongo-client"] = nil
183
- end
184
- end
50
+ def set_persistence_context(options_or_context)
51
+ PersistenceContext.set(self, options_or_context)
52
+ end
185
53
 
186
- # Unset the persistence options and client with special options on the current thread.
187
- #
188
- # @api private
189
- #
190
- # @example Unset the persistence options and client with options.
191
- # Threaded.unset_options(Band)
192
- #
193
- # @param [ Class ] klass The model class.
194
- #
195
- # @return [ nil ] nil.
196
- #
197
- # @since 5.1.0
198
- def unset_options(klass)
199
- unset_persistence_options(klass)
200
- unset_client_with_options(klass)
201
- end
54
+ def clear_persistence_context(original_cluster = nil)
55
+ PersistenceContext.clear(self, original_cluster)
202
56
  end
203
57
 
204
58
  module ClassMethods
205
- include Threaded
206
59
 
207
60
  def client_name
208
- if persistence_options && v = persistence_options[:client]
209
- return v.to_sym
210
- end
211
- super
61
+ persistence_context.client_name
212
62
  end
213
63
 
214
64
  def collection_name
215
- if persistence_options && v = persistence_options[:collection]
216
- return v.to_sym
217
- end
218
- super
65
+ persistence_context.collection_name
219
66
  end
220
67
 
221
68
  def database_name
222
- if persistence_options && v = persistence_options[:database]
223
- return v.to_sym
224
- end
225
- super
69
+ persistence_context.database_name
226
70
  end
227
71
 
228
- # Tell the next persistence operation to store in a specific collection,
229
- # database or client.
230
- #
231
- # @example Create a document in a different collection.
232
- # Model.with(collection: "secondary").create(name: "test")
233
- #
234
- # @example Create a document in a different database.
235
- # Model.with(database: "secondary").create(name: "test")
236
- #
237
- # @example Create a document in a different client.
238
- # Model.with(client: "secondary").create(name: "test")
72
+ def collection
73
+ persistence_context.collection
74
+ end
75
+
76
+ def mongo_client
77
+ persistence_context.client
78
+ end
79
+
80
+ # Change the persistence context for this class during the block.
239
81
  #
240
- # @example Create with a combination of options.
241
- # Model.with(client: "sharded", database: "secondary").create
82
+ # @example Save the current document to a different collection.
83
+ # Model.with(collection: "secondary") do |m|
84
+ # m.create
85
+ # end
242
86
  #
243
87
  # @param [ Hash ] options The storage options.
244
88
  #
@@ -246,56 +90,17 @@ module Mongoid
246
90
  # @option options [ String, Symbol ] :database The database name.
247
91
  # @option options [ String, Symbol ] :client The client name.
248
92
  #
249
- # @return [ Class ] The model class.
250
- #
251
- # @since 3.0.0
252
- def with(options)
253
- if block_given?
254
- set_options(self, options)
255
- result = yield self
256
- unset_options(self)
257
- result
258
- else
259
- Proxy.new(self, (persistence_options || {}).merge(options))
260
- end
261
- end
262
- end
263
-
264
- class Proxy < BasicObject
265
- include Threaded
266
-
267
- undef_method :==
268
-
269
- def initialize(target, options)
270
- @target = target
271
- @options = options
272
- end
273
-
274
- def persistence_options
275
- @options
276
- end
277
-
278
- def respond_to?(*args)
279
- @target.respond_to?(*args)
280
- end
281
-
282
- def method_missing(name, *args, &block)
283
- set_persistence_options(@target, @options)
284
- ret = @target.send(name, *args, &block)
285
- if Mongoid::Criteria == ret.class
286
- ret.with @options
287
- end
288
- ret
93
+ # @since 6.0.0
94
+ def with(options, &block)
95
+ original_cluster = persistence_context.cluster
96
+ PersistenceContext.set(self, options)
97
+ yield self
289
98
  ensure
290
- unset_persistence_options(@target)
291
- end
292
-
293
- def send(symbol, *args)
294
- __send__(symbol, *args)
99
+ PersistenceContext.clear(self, original_cluster)
295
100
  end
296
101
 
297
- def self.const_missing(name)
298
- ::Object.const_get(name)
102
+ def persistence_context
103
+ PersistenceContext.get(self) || PersistenceContext.new(self)
299
104
  end
300
105
  end
301
106
  end
@@ -74,77 +74,9 @@ module Mongoid
74
74
  def storage_options_defaults
75
75
  {
76
76
  collection: name.collectionize.to_sym,
77
- client: :default,
78
- database: -> { configured_database }
77
+ client: :default
79
78
  }
80
79
  end
81
-
82
- # Get the name of the collection this model persists to.
83
- #
84
- # @example Get the collection name.
85
- # Model.collection_name
86
- #
87
- # @return [ Symbol ] The name of the collection.
88
- #
89
- # @since 3.0.0
90
- def collection_name
91
- __evaluate__(storage_options[:collection])
92
- end
93
-
94
- # Get the client name for the model.
95
- #
96
- # @example Get the client name.
97
- # Model.client_name
98
- #
99
- # @return [ Symbol ] The name of the client.
100
- #
101
- # @since 3.0.0
102
- def client_name
103
- __evaluate__(storage_options[:client])
104
- end
105
-
106
- # Get the database name for the model.
107
- #
108
- # @example Get the database name.
109
- # Model.database_name
110
- #
111
- # @return [ Symbol ] The name of the client.
112
- #
113
- # @since 4.0.0
114
- def database_name
115
- __evaluate__(storage_options[:database])
116
- end
117
-
118
- private
119
-
120
- # Eval the provided value, either byt calling it if it responds to call
121
- # or returning the value itself.
122
- #
123
- # @api private
124
- #
125
- # @example Evaluate the name.
126
- # Model.__evaluate__(:name)
127
- #
128
- # @param [ String, Symbol, Proc ] name The name.
129
- #
130
- # @return [ Symbol ] The value as a symbol.
131
- #
132
- # @since 3.1.0
133
- def __evaluate__(name)
134
- return nil unless name
135
- name.respond_to?(:call) ? name.call.to_sym : name.to_sym
136
- end
137
-
138
- def configured_database
139
- client = Mongoid.clients[client_name]
140
- if db = client[:database]
141
- db
142
- elsif uri = client[:uri]
143
- client[:database] = Mongo::URI.get(uri).database
144
- else
145
- nil
146
- end
147
- end
148
80
  end
149
81
  end
150
82
  end