Skip to content

Commit

Permalink
Merge 4.2 into 4.3 (#2800)
Browse files Browse the repository at this point in the history
  • Loading branch information
jmikola authored Mar 27, 2024
2 parents f2d2820 + 90ebf12 commit c9b9d2c
Show file tree
Hide file tree
Showing 31 changed files with 2,027 additions and 512 deletions.
536 changes: 24 additions & 512 deletions docs/eloquent-models.txt

Large diffs are not rendered by default.

317 changes: 317 additions & 0 deletions docs/eloquent-models/model-class.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,317 @@
.. _laravel-eloquent-model-class:

====================
Eloquent Model Class
====================

.. facet::
:name: genre
:values: reference

.. meta::
:keywords: php framework, odm, code example, authentication, laravel

.. contents:: On this page
:local:
:backlinks: none
:depth: 2
:class: singlecol

Overview
--------

This guide shows you how to use the {+odm-long+} to define and
customize Laravel Eloquent models. You can use these models to work with
MongoDB data by using the Laravel Eloquent object-relational mapper (ORM).

The following sections explain how to add Laravel Eloquent ORM behaviors
to {+odm-short+} models:

- :ref:`laravel-model-define` demonstrates how to create a model class.
- :ref:`laravel-authenticatable-model` shows how to set MongoDB as the
authentication user provider.
- :ref:`laravel-model-customize` explains several model class customizations.
- :ref:`laravel-model-pruning` shows how to periodically remove models that
you no longer need.

.. _laravel-model-define:

Define an Eloquent Model Class
------------------------------

Eloquent models are classes that represent your data. They include methods
that perform database operations such as inserts, updates, and deletes.

To declare a {+odm-short+} model, create a class in the ``app/Models``
directory of your Laravel application that extends
``MongoDB\Laravel\Eloquent\Model`` as shown in the following code example:

.. literalinclude:: /includes/eloquent-models/Planet.php
:language: php
:emphasize-lines: 3,5,7
:dedent:

By default, the model uses the MongoDB database name set in your Laravel
application's ``config/database.php`` setting and the snake case plural
form of your model class name for the collection.

This model is stored in the ``planets`` MongoDB collection.

.. tip::

Alternatively, use the ``artisan`` console to generate the model class and
change the ``Illuminate\Database\Eloquent\Model`` import to ``MongoDB\Laravel\Eloquent\Model``.
To learn more about the ``artisan`` console, see `Artisan Console <https://laravel.com/docs/{+laravel-docs-version+}/artisan>`__
in the Laravel docs.

To learn how to specify the database name that your Laravel application uses,
:ref:`laravel-quick-start-connect-to-mongodb`.


.. _laravel-authenticatable-model:

Extend the Authenticatable Model
--------------------------------

To configure MongoDB as the Laravel user provider, you can extend the
{+odm-short+} ``MongoDB\Laravel\Auth\User`` class. The following code example
shows how to extend this class:

.. literalinclude:: /includes/eloquent-models/AuthenticatableUser.php
:language: php
:emphasize-lines: 3,5,7
:dedent:

To learn more about customizing a Laravel authentication user provider,
see `Adding Custom User Providers <https://laravel.com/docs/{+laravel-docs-version+}/authentication#adding-custom-user-providers>`__
in the Laravel docs.

.. _laravel-model-customize:

Customize an Eloquent Model Class
---------------------------------

This section shows how to perform the following Eloquent model behavior
customizations:

- :ref:`laravel-model-customize-collection-name`
- :ref:`laravel-model-customize-primary-key`
- :ref:`laravel-model-soft-delete`
- :ref:`laravel-model-cast-data-types`
- :ref:`laravel-model-mass-assignment`

.. _laravel-model-customize-collection-name:

Change the Model Collection Name
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

By default, the model uses the snake case plural form of your model
class name. To change the name of the collection the model uses to retrieve
and save data in MongoDB, override the ``$collection`` property of the model
class.

.. note::

We recommend using the default collection naming behavior to keep
the associations between models and collections straightforward.

The following example specifies the custom MongoDB collection name,
``celestial_body``, for the ``Planet`` class:

.. literalinclude:: /includes/eloquent-models/PlanetCollection.php
:language: php
:emphasize-lines: 9
:dedent:

Without overriding the ``$collection`` property, this model maps to the
``planets`` collection. With the overridden property, the example class stores
the model in the ``celestial_body`` collection.

.. _laravel-model-customize-primary-key:

Change the Primary Key Field
~~~~~~~~~~~~~~~~~~~~~~~~~~~~

To customize the model's primary key field that uniquely identifies a MongoDB
document, override the ``$primaryKey`` property of the model class.

By default, the model uses the PHP MongoDB driver to generate unique ObjectIDs
for each document your Laravel application inserts.

The following example specifies the ``name`` field as the primary key for
the ``Planet`` class:

.. literalinclude:: /includes/eloquent-models/PlanetPrimaryKey.php
:language: php
:emphasize-lines: 9
:dedent:

To learn more about primary key behavior and customization options, see
`Eloquent Primary Keys <https://laravel.com/docs/{+laravel-docs-version+}/eloquent#primary-keys>`__
in the Laravel docs.

To learn more about the ``_id`` field, ObjectIDs, and the MongoDB document
structure, see :manual:`Documents </core/document>` in the MongoDB server docs.

.. _laravel-model-soft-delete:

Enable Soft Deletes
~~~~~~~~~~~~~~~~~~~

Eloquent includes a soft delete feature that changes the behavior of the
``delete()`` method on a model. When soft delete is enabled on a model, the
``delete()`` method marks a document as deleted instead of removing it from the
database. It sets a timestamp on the ``deleted_at`` field to exclude it from
retrieve operations automatically.

To enable soft deletes on a class, add the ``MongoDB\Laravel\Eloquent\SoftDeletes``
trait as shown in the following code example:

.. literalinclude:: /includes/eloquent-models/PlanetSoftDelete.php
:language: php
:emphasize-lines: 6,10
:dedent:

To learn about methods you can perform on models with soft deletes enabled, see
`Eloquent Soft Deleting <https://laravel.com/docs/{+laravel-docs-version+}/eloquent#soft-deleting>`__
in the Laravel docs.

.. _laravel-model-cast-data-types:

Cast Data Types
---------------

Eloquent lets you convert model attribute data types before storing or
retrieving data by using a casting helper. This helper is a convenient
alternative to defining equivalent accessor and mutator methods on your model.

In the following example, the casting helper converts the ``discovery_dt``
model attribute, stored in MongoDB as a `MongoDB\\BSON\\UTCDateTime <https://www.php.net/manual/en/class.mongodb-bson-utcdatetime.php>`__
type, to the Laravel ``datetime`` type.

.. literalinclude:: /includes/eloquent-models/PlanetDate.php
:language: php
:emphasize-lines: 9-11
:dedent:

This conversion lets you use the PHP `DateTime <https://www.php.net/manual/en/class.datetime.php>`__
or the `Carbon class <https://carbon.nesbot.com/docs/>`__ to work with dates
in this field. The following example shows a Laravel query that uses the
casting helper on the model to query for planets with a ``discovery_dt`` of
less than three years ago:

.. code-block:: php

Planet::where( 'discovery_dt', '>', new DateTime('-3 years'))->get();

To learn more about MongoDB's data types, see :manual:`BSON Types </reference/bson-types/>`
in the MongoDB server docs.

To learn more about the Laravel casting helper and supported types, see `Attribute Casting <https://laravel.com/docs/{+laravel-docs-version+}/eloquent-mutators#attribute-casting>`__
in the Laravel docs.

.. _laravel-model-mass-assignment:

Customize Mass Assignment
~~~~~~~~~~~~~~~~~~~~~~~~~

Eloquent lets you create several models and their attribute data by passing
an array of data to the ``create()`` model method. This process of inserting
multiple models is called mass assignment.

Mass assignment can be an efficient way to create multiple models. However, it
can expose an exploitable security vulnerability. The data in the fields
might contain updates that lead to unauthorized permissions or access.

Eloquent provides the following traits to protect your data from mass
assignment vulnerabilities:

- ``$fillable`` contains the fields that are writeable in a mass assignment
- ``$guarded`` contains the fields that are ignored in a mass assignment

.. important::

We recommend using ``$fillable`` instead of ``$guarded`` to protect against
vulnerabilities. To learn more about this recommendation, see the
`Security Release: Laravel 6.18.35, 7.24.0 <https://blog.laravel.com/security-release-laravel-61835-7240>`__
article on the Laravel site.

In the following example, the model allows mass assignment of the fields
by using the ``$fillable`` attribute:

.. literalinclude:: /includes/eloquent-models/PlanetMassAssignment.php
:language: php
:emphasize-lines: 9-14
:dedent:

The following code example shows mass assignment of the ``Planet`` model:

.. code-block:: php

$planets = [
[ 'name' => 'Earth', gravity => 9.8, day_length => '24 hours' ],
[ 'name' => 'Mars', gravity => 3.7, day_length => '25 hours' ],
];

Planet::create($planets);

The models saved to the database contain only the ``name`` and ``gravity``
fields since ``day_length`` is omitted from the ``$fillable`` attribute.

To learn how to change the behavior when attempting to fill a field omitted
from the ``$fillable`` array, see `Mass Assignment Exceptions <https://laravel.com/docs/{+laravel-docs-version+}/eloquent#mass-assignment-exceptions>`__
in the Laravel docs.

.. _laravel-model-pruning:

Specify Pruning Behavior
------------------------

Eloquent lets you specify criteria to periodically delete model data that you
no longer need. When you schedule or run the ``model:prune`` command,
Laravel calls the ``prunable()`` method on all models that import the
``Prunable`` and ``MassPrunable`` traits to match the models for deletion.

To use this feature with models that use MongoDB as a database, add the
appropriate import to your model:

- ``MongoDB\Laravel\Eloquent\Prunable`` optionally performs a cleanup
step before deleting a model that matches the criteria
- ``MongoDB\Laravel\Eloquent\MassPrunable`` deletes models that match the
criteria without fetching the model data

.. note::

When enabling soft deletes on a mass prunable model, you must import the
following {+odm-short+} packages:

- ``MongoDB\Laravel\Eloquent\SoftDeletes``
- ``MongoDB\Laravel\Eloquent\MassPrunable``


To learn more about the pruning feature, see `Pruning Models <https://laravel.com/docs/{+laravel-docs-version+}/eloquent#pruning-models>`__
in the Laravel docs.

Prunable Example
~~~~~~~~~~~~~~~~

The following prunable class includes a ``prunable()`` method that matches
models that the prune action deletes and a ``pruning()`` method that runs
before deleting a matching model:

.. literalinclude:: /includes/eloquent-models/PlanetPrune.php
:language: php
:emphasize-lines: 6,10,12,18
:dedent:

Mass Prunable Example
~~~~~~~~~~~~~~~~~~~~~

The following mass prunable class includes a ``prunable()`` method that matches
models that the prune action deletes:

.. literalinclude:: /includes/eloquent-models/PlanetMassPrune.php
:language: php
:emphasize-lines: 5,10,12
:dedent:

Loading

0 comments on commit c9b9d2c

Please sign in to comment.