Перейти до основного вмісту

← Попереднє завантаження · Повернутися до README · Перетворення даних →

Конфігурація

Публікація конфігурації​

php artisan vendor:publish --tag="model_settings"

Команда публікує config/model_settings.php і міграцію пакета.

Доступні параметри​

ПараметрЗначення за замовчуваннямПризначення
modelDragonCode\LaravelModelSettings\Models\SettingsEloquent-модель для збережених налаштувань
connectionСтандартне для застосункуПідключення до бази даних для моделі та міграції
tablesettingsТаблиця бази даних для моделі та міграції
casts[]Перетворення даних, вибрані за класом батьківської моделі та, за потреби, ключем налаштування

Пакет читає такі змінні середовища:

ЗміннаЗначення за замовчуванням
MODEL_SETTINGS_DATABASE_CONNECTIONDATABASE_CONNECTION, потім стандартне підключення Laravel
MODEL_SETTINGS_DATABASE_TABLEsettings

Задайте підключення й таблицю до запуску міграції:

MODEL_SETTINGS_DATABASE_CONNECTION=mysql
MODEL_SETTINGS_DATABASE_TABLE=model_settings

Пізніша зміна цих параметрів не переносить наявні записи.

Налаштування перетворень даних​

Сумісна форма для всієї моделі й надалі підтримується. Один клас перетворення обробляє всі дані, що належать класу моделі:

'casts' => [
App\Models\User::class => App\Casts\UserSettingsPayloadCast::class,
],

Використовуйте мапу за ключами, якщо різним налаштуванням потрібні різні типи або обробка:

'casts' => [
App\Models\User::class => [
'profile' => App\Data\ProfileData::class,
'billing.credentials' => App\Casts\EncryptedSettingPayload::class,
],
],

Ключі зіставляються точно. Крапки не позначають вкладений шлях, а відсутній у мапі ключ використовує стандартне JSON-перетворення. Запис кожної моделі задається або рядком класу для всієї моделі, або мапою за ключами; символу підстановки всередині мапи немає. Підтримувані контракти та приклад шифрування наведено в розділі Перетворення даних.

Схема зберігання​

Опублікована міграція створює такі стовпці:

СтовпецьПризначення
idПервинний ключ рядка налаштування
item_typeMorph-клас батьківської моделі або псевдонім
item_idІдентифікатор батьківської моделі як рядок довжиною до 36 символів
is_defaultВідрізняє значення класу за замовчуванням від перевизначень моделей
keyКлюч налаштування
payloadДані, оголошені в міграції як jsonb
created_at і updated_atЧасові мітки Laravel

Комбінація item_type, item_id, is_default і key унікальна. Індекс пошуку за item_type, is_default та item_id підтримує читання значень за замовчуванням і області власника.

Значення класу за замовчуванням і перевизначення моделей містяться в одній таблиці. Пакет не створює другу таблицю значень за замовчуванням і не додає стовпці з метаданими шифрування.

Стандартний стовпець item_id зберігає не більше 36 символів. У цю схему вміщуються цілочислові, рядкові, UUID- та ULID-ідентифікатори, якщо їхнє рядкове представлення не довше за 36 символів. Для довшого користувацького первинного ключа потрібна відповідна зміна міграції.

Значення класу за замовчуванням використовують item_id = '0' з is_default = true. Збережений власник із цілим ключем 0 або рядковим '0' використовує те саме фізичне значення item_id з is_default = false, тому обидва рядки можуть існувати для одного типу моделі та ключа налаштування. Якщо дані вже існують, зміна підключення, назви таблиці або псевдонімів morph map потребує самостійного перенесення чи оновлення рядків.

Оновлення з попередньої версії 1.x​

Цей випуск змінює контракт виконання на додаток до міграції дискримінатора сховища:

Поведінка попередньої 1.xПоточна поведінкаНеобхідна зміна застосунку
set($key, null), порожні рядки, рядки з пробілів і порожні масиви видаляли рядокset() точно зберігає кожне JSON-значенняЗамініть виклики видалення на forget($key)
Порожні елементи в setMany() видалялися в тому самому пакетіКожен елемент setMany() зберігається одним транзакційним upsertПеренесіть ключі для видалення в окремий виклик forgetMany()
Порожні ключі та ключі лише з пробілів приймалисяНормалізовані порожні ключі викидають InvalidSettingKeyПерейменуйте або видаліть недійсні ключі до оновлення
Для перевірки наявності був потрібен all()->has($key)has($key) відрізняє збережений JSON null від відсутнього ключаВикористовуйте спеціалізований метод has()

Збережене перевизначення моделі зі значенням null тепер приховує заповнене значення класу за замовчуванням, доки forget() не видалить перевизначення. Користувацькі перетворення даних тепер отримують порожні значення з обох setter-методів, а події створення або оновлення користувацької моделі сховища отримують їх із set(). get() досі приймає лише один аргумент; резервне значення від викликача та постійний псевдонім put() не додані.

Після оновлення пакета опублікуйте нову міграцію та запустіть її в режимі обслуговування застосунку:

php artisan vendor:publish --tag="model_settings"
php artisan migrate

Міграція додає is_default, відносить усі попередні рядки з item_id = '0' до значень класу за замовчуванням, створює індекси з дискримінатором, а потім видаляє попередній унікальний індекс. Вона не виводить ключі або дані налаштувань.

У попередній схемі 1.x значення класу за замовчуванням і рядки реального власника з ідентифікатором 0 зберігалися однаково. Тому міграція не може відрізнити додане вручну перевизначення власника від значення за замовчуванням і відносить обидва рядки до значень за замовчуванням. Після міграції перевірте відомі попередні дані власників з ідентифікатором 0 та встановіть is_default = false для рядків, які є перевизначеннями моделей.

Не запускайте попередню версію пакета з оновленою схемою. Вона не записує дискримінатор і збереже значення за замовчуванням як перевизначення. Розгортайте міграцію та сумісну версію пакета в одній межі режиму обслуговування.

Відкат безпечний лише до появи реального перевизначення власника з ідентифікатором 0. Міграція зупиняється до зміни схеми, якщо знаходить item_id = '0' з is_default = false, оскільки попередня схема не може подати такий рядок без зміни його змісту. Видаліть або експортуйте ці перевизначення перед відкатом. Безпечний відкат відновлює попередній унікальний індекс і видаляє is_default.

Заміна моделі зберігання​

Вбудована модель налаштувань оголошена як final. Замість успадкування налаштуйте заміну:

namespace App\Models;

use DragonCode\LaravelModelSettings\Casts\PayloadCast;
use Illuminate\Database\Eloquent\Model;

final class ApplicationSetting extends Model
{
protected $fillable = [
'item_type',
'item_id',
'is_default',
'key',
'payload',
];

public function __construct(array $attributes = [])
{
$this->setConnection(config('model_settings.connection'));
$this->setTable(config('model_settings.table'));

parent::__construct($attributes);
}

protected function casts(): array
{
return [
'item_id' => 'string',
'is_default' => 'boolean',
'payload' => PayloadCast::class,
];
}
}

Потім оновіть конфігурацію:

'model' => App\Models\ApplicationSetting::class,

Заміна має залишатися сумісною з опублікованою схемою. Збережіть заповнювані атрибути та PayloadCast, якщо нова модель не реалізує еквівалентну серіалізацію.

Щонайменше нова модель має зберігати таку поведінку:

ВимогаПричина
Заповнювати item_type, item_id, is_default, key і payloadСховище записує ці атрибути
Використовувати налаштовані підключення й таблицюМіграція та репозиторій мають звертатися до тих самих рядків
Перетворювати item_id на stringЦілі числа, рядки, UUID і ULID зберігаються в одному стовпці
Перетворювати is_default на booleanЛіниве й попереднє завантаження мають читати той самий дискримінатор області
Перетворювати payload через PayloadCast або еквівалентЧитання й запис мають зберігати поведінку JSON

Див. також​