@@ -552,42 +552,71 @@ collection named "bands" in the default database in the default client.
552552Runtime Persistence Options
553553---------------------------
554554
555- You can change at runtime where to store, query, update, or remove documents by prefixing
556- any operation with ``#with`` and passing a block.
555+ It is possible to change the client, database and collection, as well as
556+ any of the MongoDB client options, used for persistence for a group of
557+ operations by using the ``with`` method on a model class or instance:
557558
558559.. code-block:: ruby
559560
560- Band.with(database: "music-non-stop") do |klass|
561- klass.create
562- end
563- Band.with(collection: "artists") do |klass|
564- klass.delete_all
565- end
566- band.with(client: :tertiary) do |band_object|
567- band_object.save!
568- end
569-
570- Persisting using with is a one-time switch in the persistence context - it creates a new
571- client under the covers which will get closed and garbage collected after use. Mongoid will not remember
572- anything specific on the document level regarding how it was saved when using this method.
573- A potential gotcha with this is persisting a document via with and then immediately updating it after.
561+ Band.with(database: "music-non-stop") do |klass|
562+ klass.create(...)
563+
564+ band = Band.first
565+
566+ Band.create(...)
567+ end
568+
569+ Band.with(collection: "artists") do |klass|
570+ klass.delete_all
571+
572+ Band.delete_all
573+ end
574+
575+ band.with(client: :tertiary) do |band_object|
576+ band_object.save!
577+
578+ band.save!
579+ end
580+
581+ The ``with`` method creates a temporary persistence context and a MongoDB
582+ client to be used for operations in the context. For the duration of the block,
583+ the persistence context on the model class or instance that ``with`` was
584+ called on is changed to the temporary persistence context. For convenience,
585+ the model class or instance that ``with`` was called on is yielded to the
586+ block.
587+
588+ The temporary persistence context applies to both queries and writes.
589+
590+ Care should be taken when performing persistence operations across different
591+ persistence contexts. For example, if a document is saved in a temporary
592+ persistence context, it may not exist in the default persistence context,
593+ failing subsequent updates:
574594
575595.. code-block:: ruby
576596
577- band = Band.new(name: "Scuba")
578- band.with(collection: "artists") do |band_object|
579- band_object.save!
580- end
581- band.update_attribute(likes: 1000) # This will not save - queries the collection "bands"
582- band.with(collection: "artists") do |band_object|
583- band_object.update_attribute(likes: 1000) # This will update the document.
584- end
585-
586- The Mongoid API was changed in version 6.0 to always require that a block be passed to #with. This is because
587- a new client is created under the covers with the options passed to #with. A new client may spin up new
588- monitor threads for keeping track of the MongoDB cluster, depending on what options are specified. This may in
589- turn cause the number of connections to continually grow with each use of #with. Now that a block is required,
590- Mongoid can properly stop the monitor threads and close the client after the block is called.
597+ band = Band.new(name: "Scuba")
598+ band.with(collection: "artists") do |band_object|
599+ band_object.save!
600+ end
601+
602+ # This will not save - updates the collection "bands" which does not have
603+ # the Scuba band
604+ band.update_attribute(likes: 1000)
605+
606+ # This will update the document.
607+ band.with(collection: "artists") do |band_object|
608+ band_object.update_attribute(likes: 1000)
609+ end
610+
611+ As of Mongoid 6.0, the ``with`` method must always be called with a block,
612+ and the temporary persistence context exists only for the duration of the block.
613+ This is because a new client is created under the covers with the options
614+ passed to ``with``. To ensure that this client is closed and its associated
615+ resources are freed, the scope when this client could be used must be
616+ well-defined.
617+
618+ Global Override
619+ ```````````````
591620
592621If you want to switch the persistence context for all operations at runtime, but don't want
593622to be using with all over your code, Mongoid provides the ability to do this as the client
@@ -632,7 +661,7 @@ Client and Collection Access
632661----------------------------
633662
634663If you want to drop down to the driver level to perform operations, you can grab
635- the Mongo client or collection from the model or document instance.
664+ the Mongo client or collection from the model or document instance:
636665
637666.. code-block:: ruby
638667
@@ -641,14 +670,14 @@ the Mongo client or collection from the model or document instance.
641670 Band.collection
642671 band.collection
643672
644- From here you also have the same runtime persistence options using the client's ``#with``.
673+ From here you also have the same runtime persistence options using the client's ``#with``:
645674
646675.. code-block:: ruby
647676
648677 client = Band.mongo_client.with(write: { w: 0 }, database: "musik")
649678 client[:artists].find(...)
650679
651- You can also override the :read or :write options on the collection using the collections ``#with``.
680+ You can also override the :read or :write options on the collection using the collections ``#with``:
652681
653682.. code-block:: ruby
654683
0 commit comments