Оливер Найбро внес вызов запрос к Laravel (8.59.0), который позволяет разработчикам требовать установки карт морфинга, а не использовать по умолчанию полные имена классов.
Используя метод enforceMorphMap
вместо традиционного метода morphMap
, Laravel гарантирует, что все морфы сопоставляются с псевдонимом, и выдает ClassMorphViolationException
исключение, если оно не сопоставлено.
// If any other models are morphed but not mapped, Laravel
// will throw a `ClassMorphViolationException` exception.
Relation::enforceMorphMap([
'user' => User::class,
]);
Вы можете применить карту морфинга с помощью одного вызова, показанного выше, или вы можете использовать автономный метод requireMorphMap
в классе Relation
:
// Turn morph map enforcement on (new in 8.59.0).
Relation::requireMorphMap();
// And then map your morphs in the standard way.
Relation::morphMap([
'user' => User::class,
]);
Фон карты морфинга
При создании полиморфных отношений в Laravel по умолчанию всегда сохранялось имя класса связанной модели в базе данных. Из файла Документация по Laravel:
По умолчанию Laravel будет использовать полное имя класса для хранения «типа» связанной модели.Например, в приведенном выше примере отношения «один ко многим», где модель комментария может принадлежать модели записи или видео,
commentable_type
по умолчанию будет либоApp\Models\Post code> или
App\Models\Video
соответственно.
Использование этого метода по умолчанию означает, что ваша база данных будет заполнена именами классов ваших моделей, что тесно связывает данные в вашей базе данных с именами ваших классов.
Laravel всегда давал нам возможность отделить имя класса от базы данных с помощью регистрация MorphMap, которая предоставляет псевдоним для класса, разрывая эту ассоциацию:
// Store `user` in the database, instead of `App\User`
Relation::morphMap([
'user' => User::class,
]);
Несмотря на то, что это поведение было доступно в течение некоторого времени, никогда не было возможности строго требовать его.
Преимущества карт морфинга
Преимущество наличия карты морфинга в первую очередь заключается в том, что логика вашего приложения отделяется от ваших сохраненных данных. Хранение имен классов в вашей базе данных может привести к пагубным, трудным для отладки ошибкам.
Если вы измените имя одного из преобразованных классов, все ссылки в вашей базе данных больше не будут соответствовать вашему приложению. Эта скрытая часть заключается в том, что вполне вероятно, что при разработке или тестировании ничего не выйдет из строя! Если ваш набор тестов каким-либо образом не заполнит вашу базу данных именем класса previous, все ваши тесты будут зелеными.Только при развертывании в рабочей среде возникнет несоответствие класса и данных.
Приведенный выше сценарий можно решить, написав миграцию для обновления сохраненных данных, но нет гарантии, что вы (или следующий человек, или следующий) вспомните, что это необходимо.
Вместо того, чтобы полагаться на корпоративную память вашей компании, карты морфинга разрушают ассоциацию и избавляют вас от этой потенциальной ошибки.
Преимущества применения карты морфинга
Точно так же, как карты морфинга освобождают вас от необходимости помнить об обновлении сохраненных данных при рефакторинге класса, требование карты морфинга освобождает вас от необходимости помнить о необходимости регистрации класса. в первую очередь.
Relation::morphMap([
'image' => Image::class,
'post' => Post::class,
]);
-
image
- from the morph map -
post
- from the morph map -
App\Video
- from the Laravel default implementation
// All future morphs *must* be mapped!
Relation::enforceMorphMap([
'image' => Image::class,
'post' => Post::class,
]);