Skip to content

Commit 2c1e2ae

Browse files
authored
DOCSP-45368: Persistence Configuration (#77)
1 parent cffbe26 commit 2c1e2ae

File tree

4 files changed

+430
-268
lines changed

4 files changed

+430
-268
lines changed

source/data-modeling.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ Model Your Data
1717
Documents </data-modeling/documents>
1818
Field Types </data-modeling/field-types>
1919
Field Behaviors </data-modeling/field-behaviors>
20+
Persistence Configuration </data-modeling/persistence-configuration>
2021
Inheritance </data-modeling/inheritance>
2122
Document Validation </data-modeling/validation>
2223
Data Associations </data-modeling/associations>
@@ -32,6 +33,9 @@ In this section, you can learn how to model data in {+odm+}.
3233

3334
- :ref:`mongoid-field-behaviors`: Learn how to customize the behaviors of fields
3435
in {+odm+} to meet your application requirements.
36+
37+
- :ref:`mongoid-persistence`: Learn how to use {+odm+} to view and customize
38+
your document storage.
3539

3640
- :ref:`mongoid-modeling-inheritance`: Learn how to implement
3741
inheritance in your model classes.
Lines changed: 293 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,293 @@
1+
.. _mongoid-persistence:
2+
3+
=========================
4+
Persistence Configuration
5+
=========================
6+
7+
.. facet::
8+
:name: genre
9+
:values: reference
10+
11+
.. meta::
12+
:keywords: code example, customize, config
13+
14+
.. contents:: On this page
15+
:local:
16+
:backlinks: none
17+
:depth: 3
18+
:class: singlecol
19+
20+
Overview
21+
--------
22+
23+
In this guide, you can learn about how {+odm+} persists data in your database
24+
and collections. **Persistence configuration** refers to the settings that
25+
control how {+odm+} stores data in MongoDB. This includes the client,
26+
database, and collection where documents for a model class are stored, as
27+
well as other configuration options such as read and write preferences. This guide
28+
provides methods and examples that you can use to access and update
29+
the persistence configuration of a model class.
30+
31+
.. note::
32+
33+
"Client" refers to a host configuration defined under ``clients`` in your
34+
``mongoid.yml`` file. Most applications use a single client named ``default``.
35+
36+
Default Collection Name
37+
-----------------------
38+
39+
By default, {+odm+} stores documents in a collection whose name is the pluralized
40+
form of its representative class name. In the following example, for the
41+
``Restaurant`` class, the corresponding collection is named ``restaurants``. For
42+
the ``Person`` class, the corresponding collection is named ``people``.
43+
44+
.. literalinclude:: /includes/data-modeling/persistence-configuration.rb
45+
:language: ruby
46+
:start-after: start default modeling
47+
:end-before: end default modeling
48+
49+
However, the default rules of pluralization don't always work. For
50+
example, suppose your model is named ``Rey``. The plural form of this word in
51+
Spanish is "reyes," but the default collection name is "reys."
52+
53+
You can create a new pluralization rule for your model class by calling the
54+
`ActiveSupport::Inflector::Inflections.plural() <https://api.rubyonrails.org/classes/ActiveSupport/Inflector/Inflections.html#method-i-plural>`__
55+
instance method and passing the singular and plural forms of your class name.
56+
The following example specifies "reyes" as the plural of "rey":
57+
58+
.. literalinclude:: /includes/data-modeling/persistence-configuration.rb
59+
:language: ruby
60+
:start-after: start set pluralization
61+
:end-before: end set pluralization
62+
63+
As a result, {+odm+} stores ``Rey`` model class documents in the ``reyes``
64+
collection.
65+
66+
.. note:: BSON Document Structure
67+
68+
When {+odm+} stores a document in a database, it serializes the Ruby object
69+
to a BSON document that has the following structure:
70+
71+
.. literalinclude:: /includes/data-modeling/persistence-configuration.rb
72+
:language: ruby
73+
:start-after: start BSON model
74+
:end-before: end BSON model
75+
76+
Persistence Context Attributes
77+
------------------------------
78+
79+
Every model class contains the following methods, which you can use to retrieve
80+
information about where {+odm+} persists the model:
81+
82+
- ``client_name``: Retrieves the client name
83+
- ``database_name``: Retrieves the database name
84+
- ``collection_name``: Retrieves the collection name
85+
86+
The following example shows how to retrieve and print the names of the client,
87+
database, and collection where documents for the ``Band`` class are persisted:
88+
89+
.. io-code-block::
90+
91+
.. input:: /includes/data-modeling/persistence-configuration.rb
92+
:language: ruby
93+
:start-after: start persistence context attributes
94+
:end-before: end persistence context attributes
95+
96+
.. output::
97+
:language: ruby
98+
:visible: false
99+
100+
default
101+
102+
my_bands
103+
104+
bands
105+
106+
Customize Your Persistence Configuration
107+
----------------------------------------
108+
109+
{+odm+} provides both model-level and runtime options for customizing your
110+
persistence configuration. The following sections describe these options.
111+
112+
Model-Level Persistence Options
113+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
114+
115+
Suppose you want to store your model's documents in a collection with a
116+
different name than the pluralized form of the model class name.
117+
You can use the ``store_in`` macro to change the collection, database, or client
118+
where {+odm+} stores a model's documents. The following example shows how
119+
to use the ``store_in`` macro to store documents from the ``Person`` class in
120+
a collection called ``citizens`` in the ``other`` database within a client
121+
named ``analytics``:
122+
123+
.. literalinclude:: /includes/data-modeling/persistence-configuration.rb
124+
:language: ruby
125+
:start-after: start store_in example
126+
:end-before: end store_in example
127+
128+
The ``store_in`` macro can also accept a lambda function. This is useful if you
129+
want to define a persistence context with values that cannot use a constant string.
130+
131+
You might want to use this pattern in a multi-tenant application,
132+
where multiple users share common access to an application. By using
133+
a lambda, you can define a persistence context based on information that is local
134+
to the current thread so that users cannot access each others' data.
135+
136+
The following example stores documents in a database determined by a
137+
thread-local variable:
138+
139+
.. literalinclude:: /includes/data-modeling/persistence-configuration.rb
140+
:language: ruby
141+
:start-after: start store_in lambda example
142+
:end-before: end store_in lambda example
143+
144+
.. _mongoid-set-runtime-persistence-options:
145+
146+
Runtime Persistence Options
147+
~~~~~~~~~~~~~~~~~~~~~~~~~~~
148+
149+
You can use the ``with`` method on a model class or instance to change
150+
a model's persistence configuration for a group of operations during runtime.
151+
152+
Call the ``with`` method on a model class or instance and pass options
153+
that define a persistence context. You can call the ``with`` method in two ways:
154+
155+
- ``with(context, options)``: ``context`` is an instance of
156+
``Mongoid::PersistenceContext`` and ``options`` is a Hash that represents a
157+
customizable set of options.
158+
159+
- ``with(options)``: ``options`` is a Hash that represents a
160+
customizable set of options.
161+
162+
Then, use a block to define the operations that you want to execute in the
163+
specified context. The context that you define only exists while the code
164+
in the block runs.
165+
166+
By default, {+odm+} stores documents for the ``Band`` class in a collection called
167+
``bands``. The following code example uses the ``with`` method to temporarily
168+
use a different client, database, and collection to perform operations on the
169+
``Band`` class's documents:
170+
171+
.. literalinclude:: /includes/data-modeling/persistence-configuration.rb
172+
:language: ruby
173+
:start-after: start with example
174+
:end-before: end with example
175+
176+
.. note:: Define Clients
177+
178+
In the preceding example, you must define the ``tertiary`` cluster under
179+
``clients`` in your ``mongoid.yml`` file.
180+
181+
.. important:: Block Scope
182+
183+
You must call the ``with`` method with a block.
184+
This is because {+odm+} uses the options you pass to the method to create
185+
a new client in the background. A block defines the scope of this client
186+
so it can be closed and its resources freed.
187+
188+
You can also pass the ``with`` method configuration options for read or write
189+
operations. The configurations apply only to the specified type of operation.
190+
191+
The following example uses the ``with`` method to specify the use of the
192+
secondary node for all read operations within the block.
193+
194+
.. literalinclude:: /includes/data-modeling/persistence-configuration.rb
195+
:language: ruby
196+
:start-after: start read configuration
197+
:end-before: end read configuration
198+
199+
.. note:: Ensuring Consistency in Contexts
200+
201+
When you perform an operation in one context, {+odm+} doesn't automatically
202+
perform the same operation in different contexts.
203+
For example, if you insert a ``Band`` model document into
204+
the ``artists`` collection, the same document will not be inserted into the
205+
``bands`` collection.
206+
207+
Global Persistence Contexts
208+
+++++++++++++++++++++++++++
209+
210+
In previous examples in this section, you changed persistence context only in
211+
the scope of a block. You can use {+odm+} to globally define a custom persistence
212+
context that all operations in your program use.
213+
This lets you change the persistence context for all operations at runtime
214+
without repeatedly calling the ``with`` method.
215+
216+
You can use the following methods to globally define the persistence context
217+
in your program:
218+
219+
- ``{+odm+}.override_client``: {+odm+} performs all operations on the specified client.
220+
221+
- ``{+odm+}.override_database``: {+odm+} performs all operations on the specified
222+
database.
223+
224+
In the following code example, the application stores information for different
225+
locales in different databases. The code shows how to use the
226+
``{+odm+}.override_database`` method to globally set the persistence
227+
context based on the locale:
228+
229+
.. literalinclude:: /includes/data-modeling/persistence-configuration.rb
230+
:language: ruby
231+
:start-after: start global configuration example
232+
:end-before: end global configuration example
233+
234+
In the preceding example, {+odm+} performs all other operations on this thread
235+
on an alternative database determined by the locale. Because the ``after_action``
236+
macro sets the override option to ``nil``, subsequent requests with no
237+
changes in persistence configuration use the default configuration.
238+
239+
Client and Collection Access
240+
----------------------------
241+
242+
You can access the client or collection of a model or document instance by using
243+
the ``mongo_client`` and ``collection`` class methods:
244+
245+
.. literalinclude:: /includes/data-modeling/persistence-configuration.rb
246+
:language: ruby
247+
:start-after: start access client collection
248+
:end-before: end access client collection
249+
250+
When using these methods, you can also set runtime persistence options by calling
251+
the ``with`` method, similar to examples in the :ref:`mongoid-set-runtime-persistence-options`
252+
section.
253+
254+
``mongo_client.with``
255+
~~~~~~~~~~~~~~~~~~~~~
256+
257+
The following code example accesses the client used by the ``Band`` model class.
258+
It then uses the ``with`` method on the client to write to the ``music``
259+
database, setting the ``w`` write option to ``0`` to not require write acknowledgement.
260+
261+
.. literalinclude:: /includes/data-modeling/persistence-configuration.rb
262+
:language: ruby
263+
:start-after: start client with example
264+
:end-before: end client with example
265+
266+
``collection.with``
267+
~~~~~~~~~~~~~~~~~~~
268+
269+
You can override the ``:read`` and ``:write`` options on a collection by using the
270+
``with`` method. The following example shows how to use
271+
the ``with`` method to set the ``w`` write option to ``0``:
272+
273+
.. literalinclude:: /includes/data-modeling/persistence-configuration.rb
274+
:language: ruby
275+
:start-after: start collection with example
276+
:end-before: end collection with example
277+
278+
API Documentation
279+
-----------------
280+
281+
For more information about the methods mentioned in this guide, see the following
282+
API documentation:
283+
284+
- `#client_name <{+api-root+}/PersistenceContext.html#client_name-instance_method>`__
285+
- `#database_name <{+api-root+}/Clients/Options/ClassMethods.html#database_name-instance_method>`__
286+
- `#collection_name <{+api-root+}/Clients/Options/ClassMethods.html#collection_name-instance_method>`__
287+
- `#store_in <{+api-root+}/Clients/StorageOptions/ClassMethods.html#store_in-instance_method>`__
288+
- `Model.with <{+api-root+}/Clients/Options.html#with-instance_method>`__
289+
- `Mongoid::PersistenceContext <{+api-root+}/PersistenceContext.html>`__
290+
- `Mongoid.override_client <{+api-root+}/Config.html#override_client-instance_method>`__
291+
- `Mongoid.override_database <{+api-root+}/Config.html#override_database-instance_method>`__
292+
- `Model.mongo_client <{+api-root+}/Clients/Options/ClassMethods.html#mongo_client-instance_method>`__
293+
- `Model.collection <{+api-root+}/Clients/Options/ClassMethods.html#collection-instance_method>`__

0 commit comments

Comments
 (0)