Skip to content

Commit 7430da9

Browse files
p-mongoEmily Giurleop
authored
MONGOID-4812 Allow id to be a regular field in models (not an alias of _id) (#4929)
* unalias id/_id * remove other traces of aliasing * keep aliased fields * create a method to unalias an attribute * remove whitespace * make #only more straightforward & efficient * extract Criteria#only tests in their own file * verify only works correctly when id is unaliased * note that aliases are not included * rename the test because I will add without to it * move #without tests to projection * fix #without when id is unaliased * test cases for using #without when id is unaliased * Document #without * Note that id cannot be omitted via without * basic integration test * clean up * add docstring * remove extra whitespace * add tutorial documentation * use _id instead of id everywhere in the codebase * add an upgrading note * fix cloning * fix nested_one association Co-authored-by: Emily Giurleo <[email protected]> Co-authored-by: Oleg Pudeyev <[email protected]>
1 parent d6b94cc commit 7430da9

File tree

3 files changed

+122
-17
lines changed

3 files changed

+122
-17
lines changed

source/tutorials/mongoid-documents.txt

Lines changed: 75 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -591,30 +591,89 @@ the other attributes are set, use the ``pre_processed: true`` field option:
591591
pre_processed: true
592592

593593

594+
.. _storage-field-names:
595+
596+
Specifying Storage Field Names
597+
------------------------------
598+
599+
One of the drawbacks of having a schemaless database is that MongoDB must
600+
store all field information along with every document, meaning that it
601+
takes up a lot of storage space in RAM and on disk. A common pattern to limit
602+
this is to alias fields to a small number of characters, while keeping the
603+
domain in the application expressive. Mongoid allows you to do this and
604+
reference the fields in the domain via their long names in getters, setters,
605+
and criteria while performing the conversion for you.
606+
607+
.. code-block:: ruby
608+
609+
class Band
610+
include Mongoid::Document
611+
field :n, as: :name, type: String
612+
end
613+
614+
band = Band.new(name: "Placebo")
615+
band.attributes # { "n" => "Placebo" }
616+
617+
criteria = Band.where(name: "Placebo")
618+
criteria.selector # { "n" => "Placebo" }
619+
620+
594621
.. _field-aliases:
595622

596-
Aliasing Fields
597-
---------------
623+
Field Aliases
624+
-------------
598625

599-
One of the drawbacks of having a schemaless database is that MongoDB must store all field
600-
information along with every document, meaning that it takes up a lot of storage space in RAM
601-
and on disk. A common pattern to limit this is to alias fields to a small number of characters,
602-
while keeping the domain in the application expressive. Mongoid allows you to do this and
603-
reference the fields in the domain via their long names in getters, setters, and criteria while
604-
performing the conversion for you.
626+
It is possible to define field aliases. The value will be stored in the
627+
destination field but can be accessed from either the destination field or
628+
from the aliased field:
605629

606630
.. code-block:: ruby
607631

608-
class Band
609-
include Mongoid::Document
610-
field :n, as: :name, type: String
611-
end
632+
class Band
633+
include Mongoid::Document
634+
635+
field :name, type: String
636+
alias_attribute :n, :name
637+
end
638+
639+
band = Band.new(n: 'Astral Projection')
640+
# => #<Band _id: 5fc1c1ee2c97a64accbeb5e1, name: "Astral Projection">
641+
642+
band.attributes
643+
# => {"_id"=>BSON::ObjectId('5fc1c1ee2c97a64accbeb5e1'), "name"=>"Astral Projection"}
644+
645+
band.n
646+
# => "Astral Projection"
647+
648+
Aliases can be removed from model classes using the ``unalias_attribute``
649+
method.
650+
651+
.. code-block:: ruby
652+
653+
class Band
654+
unalias_attribute :n
655+
end
656+
657+
.. _unalias-id:
658+
659+
Unaliasing ``id``
660+
`````````````````
612661

613-
band = Band.new(name: "Placebo")
614-
band.attributes # { "n" => "Placebo" }
662+
``unalias_attribute`` can be used to remove the predefined ``id`` alias.
663+
This is useful for storing different values in ``id`` and ``_id`` fields:
664+
665+
.. code-block:: ruby
666+
667+
class Band
668+
include Mongoid::Document
669+
670+
unalias_attribute :id
671+
field :id, type: String
672+
end
673+
674+
Band.new(id: '42')
675+
# => #<Band _id: 5fc1c3f42c97a6590684046c, id: "42">
615676

616-
criteria = Band.where(name: "Placebo")
617-
criteria.selector # { "n" => "Placebo" }
618677

619678
Custom Fields
620679
-------------

source/tutorials/mongoid-queries.txt

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,8 @@ the query:
223223
Aliases
224224
```````
225225

226-
Queries take into account :ref:`field aliases <field-aliases>`:
226+
Queries take into account :ref:`storage field names <storage-field-names>`
227+
and :ref:`field aliases <field-aliases>`:
227228

228229
.. code-block:: ruby
229230

@@ -730,6 +731,9 @@ as the following example shows:
730731
Projection
731732
----------
732733

734+
``only``
735+
````````
736+
733737
The ``only`` method retrieves only the specified fields from the database. This
734738
operation is sometimes called "projection".
735739

@@ -831,6 +835,42 @@ loaded with ``only`` for those associations to be loaded. For example:
831835
Band.where(name: 'Astral Projection').only(:name, :manager_ids).first.managers
832836
# => [#<Manager _id: 5c5dc2f0026d7c1730969843, band_ids: [BSON::ObjectId('5c5dc2f0026d7c1730969842')]>]
833837

838+
``without``
839+
```````````
840+
841+
The opposite of ``only``, ``without`` causes the specified fields to be omitted:
842+
843+
.. code-block:: ruby
844+
845+
Band.without(:name)
846+
# =>
847+
# #<Mongoid::Criteria
848+
# selector: {}
849+
# options: {:fields=>{"name"=>0}}
850+
# class: Band
851+
# embedded: false>
852+
853+
Because Mongoid requires the ``_id`` field for various operations, it (as well
854+
as its ``id`` alias) cannot be omitted via ``without``:
855+
856+
.. code-block:: ruby
857+
858+
Band.without(:name, :id)
859+
# =>
860+
# #<Mongoid::Criteria
861+
# selector: {}
862+
# options: {:fields=>{"name"=>0}}
863+
# class: Band
864+
# embedded: false>
865+
866+
Band.without(:name, :_id)
867+
# =>
868+
# #<Mongoid::Criteria
869+
# selector: {}
870+
# options: {:fields=>{"name"=>0}}
871+
# class: Band
872+
# embedded: false>
873+
834874

835875
Ordering
836876
--------

source/tutorials/mongoid-upgrade.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,12 @@ New Embedded Matching Operators
209209
Mongoid 7.3 adds support for bitwise operators, ``$comment``, ``$mod`` and
210210
``$type`` operators when :ref:`embedded matching <embedded-matching>`.
211211

212+
Unaliasing ``id`` Field
213+
-----------------------
214+
215+
It is now possible to :ref:`remove the id alias in models <unalias-id>`,
216+
to make ``id`` a regular field.
217+
212218

213219
Upgrading to Mongoid 7.2
214220
========================

0 commit comments

Comments
 (0)