Skip to content

Commit 78cb913

Browse files
authored
DOCSP-46394: CRUD remaining sections (#83)
* DOCSP-46394: CRUD remaining sections * vale fixes * JS PR fixes 1
1 parent 491c4ce commit 78cb913

File tree

2 files changed

+219
-1
lines changed

2 files changed

+219
-1
lines changed

source/includes/interact-data/crud.rb

Lines changed: 71 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -263,4 +263,74 @@ class Person
263263
raise 'An exception'
264264
# Name and age changes are not persisted
265265
end
266-
# end join_contexts atomic
266+
# end join_contexts atomic
267+
268+
# start-dirty-tracking-view
269+
# Retrieves a person instance
270+
person = Person.first
271+
# Sets a new `name` value
272+
person.name = "Sarah Frank"
273+
274+
# Checks to see if the document is changed
275+
person.changed? # true
276+
# Gets an array of changed fields.
277+
person.changed # [ :name ]
278+
# Gets a hash of the old and changed values for each field
279+
person.changes # { "name" => [ "Sarah Frink", "Sarah Frank" ] }
280+
281+
# Checks if a specific field is changed
282+
person.name_changed? # true
283+
# Gets the changes for a specific field
284+
person.name_change # [ "Sarah Frink", "Sarah Frank" ]
285+
286+
# Gets the previous value for a field
287+
person.name_was # "Sarah Frink"
288+
# end-dirty-tracking-view
289+
290+
# start-dirty-tracking-reset
291+
person = Person.first
292+
person.name = "Sarah Frank"
293+
294+
# Reset the changed `name` field
295+
person.reset_name!
296+
person.name # "Sarah Frink"
297+
# end-dirty-tracking-reset
298+
299+
# start-dirty-tracking-prev
300+
person = Person.first
301+
person.name = "Sarah Frank"
302+
person.save # Clears out current changes
303+
304+
# Lists the previous changes
305+
person.previous_changes
306+
# { "name" => [ "Sarah Frink", "Sarah Frank" ] }
307+
# end-dirty-tracking-prev
308+
309+
# start-container-save
310+
person = Person.new
311+
interests = person.interests
312+
# => #<Set: {}>
313+
interests << 'Hiking'
314+
# => #<Set: {"Hiking"}>
315+
316+
# Assigns the Set to the field
317+
person.interests = interests
318+
# => #<Set: {"Hiking"}>
319+
person.interests
320+
# => #<Set: {"Hiking"}>
321+
# end-container-save
322+
323+
# start-override-readonly
324+
class Person
325+
include Mongoid::Document
326+
field :name, type: String
327+
328+
def readonly?
329+
true
330+
end
331+
end
332+
333+
person = Person.first
334+
person.readonly? # => true
335+
person.destroy # => raises ReadonlyDocument error
336+
# end-override-readonly

source/interact-data/crud.txt

Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -677,6 +677,154 @@ When you globally set ``join_contexts`` to ``true``, you can use the
677677
``join_context: false`` option on an ``atomically`` block to run
678678
operations at the end of the block for that block only.
679679

680+
Dirty Tracking
681+
--------------
682+
683+
You can track changed ("dirty") fields by using a {+odm+} API similar to
684+
the one available in Active Model. If you modify a defined field in a
685+
model, {+odm+} marks the model as dirty and allows you to perform
686+
special actions. The following sections describe how you can interact
687+
with dirty models.
688+
689+
View Changes
690+
~~~~~~~~~~~~
691+
692+
{+odm+} records changes from the time a model is instantiated, either as
693+
a new document or by retrieving one from the database, until the time it is
694+
saved. Any persistence operation clears the changes.
695+
696+
{+odm+} creates model-specific methods that allow you to explore the
697+
changes to a model instance. The following code demonstrates ways that
698+
you can view changes on your model instance:
699+
700+
.. literalinclude:: /includes/interact-data/crud.rb
701+
:language: ruby
702+
:start-after: start-dirty-tracking-view
703+
:end-before: end-dirty-tracking-view
704+
705+
.. note:: Tracking Changes to Associations
706+
707+
Setting the associations on a document does not modify the
708+
``changes`` or ``changed_attributes`` hashes. This is true for all
709+
types of associations. However, changing the
710+
``_id`` field on referenced associations causes the changes to
711+
show up in the ``changes`` and the ``changed_attributes`` hashes.
712+
713+
Reset Changes
714+
~~~~~~~~~~~~~
715+
716+
You can reset a changed field to its previous value by calling the
717+
``reset`` method, as shown in the following code:
718+
719+
.. literalinclude:: /includes/interact-data/crud.rb
720+
:language: ruby
721+
:start-after: start-dirty-tracking-reset
722+
:end-before: end-dirty-tracking-reset
723+
724+
Persistence
725+
~~~~~~~~~~~
726+
727+
{+odm+} uses dirty tracking as the basis of all persistence operations.
728+
It evaluates the changes on a document and atomically updates only what
729+
has changed, compared to other frameworks that write the entire document on
730+
each save. If you don't make any changes, {+odm+} does not access the
731+
database when you call ``Model#save``.
732+
733+
View Previous Changes
734+
~~~~~~~~~~~~~~~~~~~~~
735+
736+
After you persist a model to MongoDB, {+odm+} clears the current
737+
changes. However, you can still see what changes were made previously by
738+
calling the ``previous_changes`` method, as shown in the following
739+
code:
740+
741+
.. literalinclude:: /includes/interact-data/crud.rb
742+
:language: ruby
743+
:start-after: start-dirty-tracking-prev
744+
:end-before: end-dirty-tracking-prev
745+
746+
Update Container Fields
747+
-----------------------
748+
749+
{+odm+} currently has an issue that prevents changes to attributes of
750+
container types, such as ``Set`` or ``Array``, from saving to MongoDB.
751+
You must assign all fields, including container types, for their values
752+
to save to MongoDB.
753+
754+
For example, adding an item to a ``Set`` instance as shown in the
755+
following code *does not* persist changes to MongoDB:
756+
757+
.. code-block:: ruby
758+
759+
person = Person.new
760+
person.interests
761+
# => #<Set: {}>
762+
763+
person.interests << 'Hiking'
764+
# => #<Set: {"Hiking"}>
765+
person.interests
766+
# => #<Set: {}> # Change does not take effect
767+
768+
To persist this change, you must modify the field value *outside* of the
769+
model and assign it back to the model as shown in the following code:
770+
771+
.. literalinclude:: /includes/interact-data/crud.rb
772+
:language: ruby
773+
:start-after: start-container-save
774+
:end-before: end-container-save
775+
776+
Read-only Documents
777+
-------------------
778+
779+
You can mark documents as read-only in the following ways, depending on
780+
the value of the ``Mongoid.legacy_readonly`` feature flag:
781+
782+
- If this flag is turned *off*, you can mark a document as
783+
read-only by calling the ``readonly!`` method on that document. The
784+
resulting read-only document raises a ``ReadonlyDocument`` error if
785+
you attempt to perform any persistence operation, including, but not
786+
limited to, saving, updating, deleting, and destroying. Note that
787+
reloading *does not* reset the read-only state.
788+
789+
.. code-block:: ruby
790+
791+
person = Person.first
792+
person.readonly? # => false
793+
person.readonly! # Sets the document as read-only
794+
person.readonly? # => true
795+
person.name = "Larissa Shay" # Changes the document
796+
person.save # => raises ReadonlyDocument error
797+
person.reload.readonly? # => true
798+
799+
- If this flag is turned ``on``, you can mark a document as read-only
800+
after you project that document by using methods such as ``only`` or
801+
``without``. As a result, you can't delete or destroy the read-only
802+
document because {+odm+} raises a ``ReadonlyDocument`` error, but you can
803+
save and update it. The read-only status *is reset* if you reload the
804+
document.
805+
806+
.. code-block:: ruby
807+
808+
person = Person.only(:name).first
809+
person.readonly? # => true
810+
person.destroy # => raises ReadonlyDocument error
811+
person.reload.readonly? # => false
812+
813+
.. tip:: Projection
814+
815+
To learn more about projections, see the
816+
:ref:`mongoid-data-projection` section of the Modify Query
817+
Results guide.
818+
819+
You can also make a document read-only by overriding the ``readonly?``
820+
method, as shown in the following code:
821+
822+
.. literalinclude:: /includes/interact-data/crud.rb
823+
:language: ruby
824+
:start-after: start-override-readonly
825+
:end-before: end-override-readonly
826+
:emphasize-lines: 5-7
827+
680828
Additional Information
681829
----------------------
682830

0 commit comments

Comments
 (0)