-
Notifications
You must be signed in to change notification settings - Fork 1.5k
DOCSP-35964 eloquent models standardization #2726
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
Merged
ccho-mongodb
merged 25 commits into
mongodb:4.1
from
ccho-mongodb:DOCSP-35964-eloquent-models-standardization
Mar 25, 2024
Merged
Changes from all commits
Commits
Show all changes
25 commits
Select commit
Hold shift + click to select a range
61f150d
DOCSP-35964: Eloquent Models section (WIP)
d765e7b
split files
e4d05f9
outline
88b7ec7
rst fix
c57aaa0
Eloquent models Model Class page
f3e40e8
grammar and spelling fixes
fd48c62
rst fixes
4fa0cda
rst fix
9c999f0
tweaks
afda903
tweaks
6c2a80d
semicolon
27635f4
Apply CS fixes to the docs examples
GromNaN bcf9d76
PRR fixes
5b5215d
fix code emphasis lines
bc9796a
PRR fixes
b454cfa
fix header and highlighting
4a28ba5
apply phpcbf formatting
ccho-mongodb 2313965
style guide fix
462e500
phpcbf highlighted line fix
5fab20a
typo fix
7d7f6ef
shorten comment
fb6bc68
PRR fix
c327218
Merge branch '4.1' into DOCSP-35964-eloquent-models-standardization
49b08c2
PRR fixes
27527fa
Merge branch '4.1' into DOCSP-35964-eloquent-models-standardization
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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: | ||
GromNaN marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
.. 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: | ||
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
<?php | ||
|
||
namespace App\Models; | ||
|
||
use MongoDB\Laravel\Auth\User as Authenticatable; | ||
|
||
class User extends Authenticatable | ||
{ | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
<?php | ||
|
||
namespace App\Models; | ||
|
||
use MongoDB\Laravel\Eloquent\Model; | ||
|
||
class Planet extends Model | ||
GromNaN marked this conversation as resolved.
Show resolved
Hide resolved
|
||
{ | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
<?php | ||
|
||
namespace App\Models; | ||
|
||
use MongoDB\Laravel\Eloquent\Model; | ||
|
||
class Planet extends Model | ||
{ | ||
protected $collection = 'celestial_body'; | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
<?php | ||
|
||
namespace App\Models; | ||
|
||
use MongoDB\Laravel\Eloquent\Model; | ||
|
||
class Planet extends Model | ||
{ | ||
protected $casts = [ | ||
GromNaN marked this conversation as resolved.
Show resolved
Hide resolved
|
||
'discovery_dt' => 'datetime', | ||
]; | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
<?php | ||
|
||
namespace App\Models; | ||
|
||
use MongoDB\Laravel\Eloquent\Model; | ||
|
||
class Planet extends Model | ||
{ | ||
protected $fillable = [ | ||
'name', | ||
'gravitational_force', | ||
'diameter', | ||
'moons', | ||
]; | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.