@@ -33,6 +33,8 @@ to {+odm-short+} models:
3333- :ref:`laravel-model-customize` explains several model class customizations.
3434- :ref:`laravel-model-pruning` shows how to periodically remove models that
3535 you no longer need.
36+ - :ref:`laravel-schema-versioning` shows how to implement model schema
37+ versioning.
3638
3739.. _laravel-model-define:
3840
@@ -67,7 +69,6 @@ This model is stored in the ``planets`` MongoDB collection.
6769To learn how to specify the database name that your Laravel application uses,
6870:ref:`laravel-quick-start-connect-to-mongodb`.
6971
70-
7172.. _laravel-authenticatable-model:
7273
7374Extend the Authenticatable Model
@@ -333,3 +334,101 @@ models that the prune action deletes:
333334 :emphasize-lines: 5,10,12
334335 :dedent:
335336
337+ .. _laravel-schema-versioning:
338+
339+ Create a Versioned Model Schema
340+ -------------------------------
341+
342+ You can implement a schema versioning pattern into your application by
343+ using the ``HasSchemaVersion`` trait on an Eloquent model. You might
344+ choose to implement a schema version to organize or standardize a
345+ collection that contains data with different schemas.
346+
347+ .. tip::
348+
349+ To learn more about schema versioning, see the :manual:`Model Data for
350+ Schema Versioning </tutorial/model-data-for-schema-versioning/>`
351+ tutorial in the {+server-docs-name+}.
352+
353+ To use this feature with models that use MongoDB as a database, add the
354+ ``MongoDB\Laravel\Eloquent\HasSchemaVersion`` import to your model.
355+ Then, set the ``SCHEMA_VERSION`` constant to ``1`` to set the first
356+ schema version on your collection. If your collection evolves to contain
357+ multiple schemas, you can update the value of the ``SCHEMA_VERSION``
358+ constant in subsequent model classes.
359+
360+ When creating your model, you can define the ``migrateSchema()`` method
361+ to specify a migration to the current schema version upon retrieving a
362+ model. In this method, you can specify the changes to make to an older
363+ model to update it to match the current schema version.
364+
365+ When you save a model that does not have a schema version
366+ specified, the ``HasSchemaVersion`` trait assumes that it follows the
367+ latest schema version. When you retrieve a model that does not contain
368+ the ``schema_version`` field, the trait assumes that its schema version
369+ is ``0`` and performs the migration.
370+
371+ Schema Versioning Example
372+ ~~~~~~~~~~~~~~~~~~~~~~~~~
373+
374+ In this sample situation, you are working with a collection that was
375+ first modeled by the following class:
376+
377+ .. literalinclude:: /includes/eloquent-models/PlanetSchemaVersion1.php
378+ :language: php
379+ :dedent:
380+
381+ Now, you want to implement a new schema version on the collection.
382+ You can define the new model class with the following behavior:
383+
384+ - Implements the ``HasSchemaVersion`` trait and sets the current
385+ ``SCHEMA_VERSION`` to ``2``
386+
387+ - Defines the ``migrateSchema()`` method to migrate models in which the
388+ schema version is less than ``2`` to have a ``galaxy`` field that has a value
389+ of ``'Milky Way'``
390+
391+ .. literalinclude:: /includes/eloquent-models/PlanetSchemaVersion2.php
392+ :language: php
393+ :emphasize-lines: 10,12,20
394+ :dedent:
395+
396+ In the ``"WASP-39 b"`` document in the following code, the
397+ ``schema_version`` field value is less than ``2``. When you retrieve the
398+ document, {+odm-short+} adds the ``galaxy`` field and updates the schema
399+ version to the current version, ``2``.
400+
401+ The ``"Saturn"`` document does not contain the ``schema_version`` field,
402+ so {+odm-short+} assigns it the current schema version upon saving.
403+
404+ Finally, the code retrieves the models from the collection to
405+ demonstrate the changes:
406+
407+ .. io-code-block::
408+ :copyable: true
409+
410+ .. input:: /includes/eloquent-models/SchemaVersionTest.php
411+ :language: php
412+ :dedent:
413+ :start-after: begin-schema-version
414+ :end-before: end-schema-version
415+
416+ .. output::
417+ :language: none
418+ :visible: false
419+
420+ [
421+ {
422+ "_id": ...,
423+ "name": "WASP-39 b",
424+ "type": "gas",
425+ "galaxy": "Milky Way",
426+ "schema_version": 2,
427+ },
428+ {
429+ "_id": ...,
430+ "name": "Saturn",
431+ "type": "gas",
432+ "schema_version": 2,
433+ }
434+ ]
0 commit comments