-
Notifications
You must be signed in to change notification settings - Fork 29
DOCSP-45360: nested attributes #71
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 3 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||
---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,191 @@ | ||||||||
.. _mongoid-modeling-nested-attr: | ||||||||
|
||||||||
================= | ||||||||
Nested Attributes | ||||||||
================= | ||||||||
|
||||||||
.. facet:: | ||||||||
:name: genre | ||||||||
:values: reference | ||||||||
|
||||||||
.. meta:: | ||||||||
:keywords: ruby framework, odm, embeddings, code example, queries | ||||||||
|
||||||||
.. contents:: On this page | ||||||||
:local: | ||||||||
:backlinks: none | ||||||||
:depth: 2 | ||||||||
:class: singlecol | ||||||||
|
||||||||
Overview | ||||||||
-------- | ||||||||
|
||||||||
In this guide, you can learn how to define **nested attributes** on | ||||||||
models to enable data operations on documents and their associations. | ||||||||
After you define a nested attribute, you can specify updates to | ||||||||
top-level and associated documents in a single parameter hash. This might be | ||||||||
useful if your application requires editing multiple documents within a single | ||||||||
form. | ||||||||
|
||||||||
Behavior | ||||||||
-------- | ||||||||
|
||||||||
You can enable nested attributes for any association, embedded or | ||||||||
referenced. To add a nested attribute for an association, provide the | ||||||||
association name to the ``accepts_nested_attributes_for`` macro when | ||||||||
defining a model class. | ||||||||
|
||||||||
The following code defines embedded associations on the ``Band`` model | ||||||||
class and includes the ``accepts_nested_attributes_for`` macro: | ||||||||
|
||||||||
.. literalinclude:: /includes/data-modeling/nested_attr.rb | ||||||||
:start-after: start-simple-nested | ||||||||
:end-before: end-simple-nested | ||||||||
:language: ruby | ||||||||
:emphasize-lines: 5 | ||||||||
:dedent: | ||||||||
|
||||||||
.. note:: Autosave Enabled | ||||||||
|
||||||||
When you add nested attribute functionality to a referenced | ||||||||
association, {+odm+} automatically enables autosave for that | ||||||||
association. | ||||||||
|
||||||||
When you enable nested attributes behavior on an association, {+odm+} | ||||||||
adds a special method to the base model. You can use this method to | ||||||||
update the attributes by using this added functionality. | ||||||||
|
||||||||
The method name is the association name suffixed with ``_attributes``. For | ||||||||
example, the setter method to update the ``producers`` association is | ||||||||
``producer_attributes``. | ||||||||
|
||||||||
You can use this method directly, or you can use the name of the method | ||||||||
as an attribute in the updates for the top-level class. In this case, | ||||||||
{+odm+} calls the appropriate setter method internally. | ||||||||
|
||||||||
The following code retrieves an instance of ``Band``, then uses the | ||||||||
nested attribute update method ``producer_attributes`` to set a value | ||||||||
for the association document: | ||||||||
|
||||||||
.. literalinclude:: /includes/data-modeling/nested_attr.rb | ||||||||
:start-after: start-use-method | ||||||||
:end-before: end-use-method | ||||||||
:language: ruby | ||||||||
:emphasize-lines: 4 | ||||||||
:dedent: | ||||||||
|
||||||||
There are multiple ways to update a nested attribute: | ||||||||
|
||||||||
- Use the ``<association name>_attributes`` setter method. | ||||||||
- Use the ``attributes`` setter method and specify ``<association | ||||||||
name>_attributes`` in the value to update the associations. | ||||||||
- Use the ``update_attributes`` setter method and specify the attribute | ||||||||
names in the value to update the associations. | ||||||||
- Use the ``update()`` method and specify ``<association | ||||||||
name>_attributes`` in the value to update the associations. | ||||||||
- Use the ``create()`` method and specify ``<association | ||||||||
name>_attributes`` in the value to create the associations. | ||||||||
|
||||||||
The following example demonstrates how to create a ``Band`` instance | ||||||||
with associated ``album`` records in a single statement: | ||||||||
|
||||||||
.. literalinclude:: /includes/data-modeling/nested_attr.rb | ||||||||
:start-after: start-create-attr | ||||||||
:end-before: end-create-attr | ||||||||
:language: ruby | ||||||||
:emphasize-lines: 3-5 | ||||||||
:dedent: | ||||||||
|
||||||||
Creating Nested Documents | ||||||||
------------------------- | ||||||||
|
||||||||
You can create new nested documents by using the nested attributes | ||||||||
feature. When creating a document, omit the ``_id`` field. The following | ||||||||
code uses the ``update()`` method to create a nested ``album`` document | ||||||||
on an existing ``Band`` instance: | ||||||||
|
||||||||
.. literalinclude:: /includes/data-modeling/nested_attr.rb | ||||||||
:start-after: start-update-create | ||||||||
:end-before: end-update-create | ||||||||
:language: ruby | ||||||||
:dedent: | ||||||||
|
||||||||
This action appends the new document to the existing set, without changing | ||||||||
rustagir marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||||
any existing nested documents. | ||||||||
|
||||||||
Updating Nested Documents | ||||||||
------------------------- | ||||||||
|
||||||||
You can update existing nested documents by using the nested attributes | ||||||||
feature. To update a nested document, pass the ``_id`` value for the | ||||||||
document to direct {+odm+} to use attributes to update it. The following | ||||||||
|
feature. To update a nested document, pass the ``_id`` value for the | |
document to direct {+odm+} to use attributes to update it. The following | |
feature. To instruct {+odm+} to update a nested document by using attributes, pass the document's ``_id`` value to the ``update()`` method. The following |
rustagir marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
Check failure on line 141 in source/data-modeling/nested-attributes.txt
GitHub Actions / TDBX Vale rules
[vale] reported by reviewdog 🐶
[MongoDB.NegativeWords] Use 'remove, delete' instead of the negative word 'destroy'.
Raw Output:
{"message": "[MongoDB.NegativeWords] Use 'remove, delete' instead of the negative word 'destroy'.", "location": {"path": "source/data-modeling/nested-attributes.txt", "range": {"start": {"line": 141, "column": 32}}}, "severity": "ERROR"}
Check failure on line 150 in source/data-modeling/nested-attributes.txt
GitHub Actions / TDBX Vale rules
[vale] reported by reviewdog 🐶
[MongoDB.NegativeWords] Use 'remove, delete' instead of the negative word 'destroy'.
Raw Output:
{"message": "[MongoDB.NegativeWords] Use 'remove, delete' instead of the negative word 'destroy'.", "location": {"path": "source/data-modeling/nested-attributes.txt", "range": {"start": {"line": 150, "column": 52}}}, "severity": "ERROR"}
Check failure on line 153 in source/data-modeling/nested-attributes.txt
GitHub Actions / TDBX Vale rules
[vale] reported by reviewdog 🐶
[MongoDB.NegativeWords] Use 'remove, delete' instead of the negative word 'destroy'.
Raw Output:
{"message": "[MongoDB.NegativeWords] Use 'remove, delete' instead of the negative word 'destroy'.", "location": {"path": "source/data-modeling/nested-attributes.txt", "range": {"start": {"line": 153, "column": 32}}}, "severity": "ERROR"}
rustagir marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
# start-simple-nested | ||
class Band | ||
include Mongoid::Document | ||
embeds_many :albums | ||
belongs_to :producer | ||
accepts_nested_attributes_for :albums, :producer | ||
end | ||
# end-simple-nested | ||
|
||
#start-use-method | ||
# Retrieves a Band instance | ||
band = Band.where(name: 'Tennis').first | ||
# Updates the "producer" association | ||
band.producer_attributes = { name: 'Alaina Moore' } | ||
#end-use-method | ||
|
||
# start-create-attr | ||
band = Band.create( | ||
name: 'Tennis', | ||
albums_attributes: [ | ||
{ name: 'Swimmer', year: 2020 }, | ||
{ name: 'Young & Old', year: 2013 }] | ||
) | ||
# end-create-attr | ||
|
||
# start-update-create | ||
band = Band.where(name: 'Vampire Weekend').first | ||
band.update(albums_attributes: [ | ||
{ name: 'Contra', year: 2010 } | ||
]) | ||
# end-update-create | ||
|
||
# start-update-id | ||
band = Band.where(name: 'Vampire Weekend').first | ||
# Retrieves the first entry from the albums array | ||
album = band.albums.first | ||
# Updates the entry by passing the _id value | ||
band.update(albums_attributes: [ | ||
{ _id: album._id, year: 2011 } ]) | ||
# end-update-id | ||
|
||
# start-delete-id | ||
band = Band.where(name: 'Vampire Weekend').first | ||
# Retrieves the first entry from the albums array | ||
album = band.albums.first | ||
# Deletes the entry by passing the _id value | ||
band.update(albums_attributes: [ | ||
{ _id: album._id, _destroy: true } ]) | ||
# end-delete-id | ||
|
||
# start-multiple-ops | ||
band = Band.where(name: 'Yeah Yeah Yeahs').first | ||
# Performs multiple data changes | ||
band.update(albums_attributes: [ | ||
{ name: 'Show Your Bones', year: 2006 }, | ||
{ _id: 1, name: 'Fever To T3ll' }, | ||
{ _id: 2, _destroy: true } ]) | ||
# end-multiple-ops |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
S: I think you can delete "by using this added functionality"; it seems repetitive after "You can use this method"