Skip to content

Commit

Permalink
expand docs for nested attributes (#5765)
Browse files Browse the repository at this point in the history
  • Loading branch information
jamis authored Dec 6, 2023
1 parent ef96d48 commit abf0640
Showing 1 changed file with 89 additions and 2 deletions.
91 changes: 89 additions & 2 deletions docs/reference/nested-attributes.txt
Original file line number Diff line number Diff line change
Expand Up @@ -49,5 +49,92 @@ Mongoid will call the appropriate setter under the covers.
band.producer_attributes = { name: "Flood" }
band.attributes = { producer_attributes: { name: "Flood" }}

Note that this will work with any attribute based setter method in Mongoid. This includes:
``update_attributes``, ``update_attributes!`` and ``attributes=``.
Note that this will work with any attribute based setter method in Mongoid,
including ``update``, ``update_attributes`` and ``attributes=``, as well as
``create`` (and all of their corresponding bang methods). For example, creating
a new person with associated address records can be done in a single
statement, like this:

.. code-block:: ruby

person = Person.create(
name: 'John Schmidt',
addresses_attributes: [
{ type: 'home', street: '1234 Street Ave.', city: 'Somewhere' },
{ type: 'work', street: 'Parkway Blvd.', city: 'Elsewehre' },
])


Creating Records
----------------

You can create new nested records via nested attributes by omitting
an ``_id`` field:

.. code-block:: ruby

person = Person.first
person.update(addresses_attributes: [
{ type: 'prior', street: '221B Baker St', city: 'London' } ])

This will append the new record to the existing set; existing records will
not be changed.


Updating Records
----------------

If you specify an ``_id`` field for any of the nested records, the attributes
will be used to update the record with that id:

.. code-block:: ruby

person = Person.first
address = person.addresses.first
person.update(addresses_attributes: [
{ _id: address._id, city: 'Lisbon' } ])

Note that if there is no record with that id, a ``Mongoid::Errors::DocumentNotFound``
exception will be raised.


Destroying Records
------------------

You can also destroy records this way, by specifying a special
``_destroy`` attribute. In order to use this, you must have passed
``allow_destroy: true`` with the ``accepts_nested_attributes_for``
declaration:

.. code-block:: ruby

class Person
# ...

accepts_nested_attributes_for :addresses, allow_destroy: true
end

person = Person.first
address = person.addresses.first
person.update(addresses_attributes: [
{ _id: address._id, _destroy: true } ])

Note that, as with updates, if there is no record with that id,
a ``Mongoid::Errors::DocumentNotFound`` exception will be raised.


Combining Operations
--------------------

Nested attributes allow you to combine all of these operations in
a single statement! Here's an example that creates an address,
updates another address, and destroys yet another address, all in
a single command:

.. code-block:: ruby

person = Person.first
person.update(addresses_attributes: [
{ type: 'alt', street: '1234 Somewhere St.', city: 'Cititon' },
{ _id: an_address_id, city: 'Changed City' },
{ _id: another_id, _destroy: true } ])

0 comments on commit abf0640

Please sign in to comment.