@@ -33,6 +33,8 @@ to {+odm-short+} models:
33
33
- :ref:`laravel-model-customize` explains several model class customizations.
34
34
- :ref:`laravel-model-pruning` shows how to periodically remove models that
35
35
you no longer need.
36
+ - :ref:`laravel-schema-versioning` shows how to implement model schema
37
+ versioning.
36
38
37
39
.. _laravel-model-define:
38
40
@@ -67,7 +69,6 @@ This model is stored in the ``planets`` MongoDB collection.
67
69
To learn how to specify the database name that your Laravel application uses,
68
70
:ref:`laravel-quick-start-connect-to-mongodb`.
69
71
70
-
71
72
.. _laravel-authenticatable-model:
72
73
73
74
Extend the Authenticatable Model
@@ -333,3 +334,101 @@ models that the prune action deletes:
333
334
:emphasize-lines: 5,10,12
334
335
:dedent:
335
336
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