Pular para o conteúdo principal

← Carregamento antecipado · Voltar ao README · Conversões de payload →

Configuração

Publicar a configuração​

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

Isso publica config/model_settings.php e a migration do pacote.

Opções disponíveis​

OpçãoPadrãoFinalidade
modelDragonCode\LaravelModelSettings\Models\SettingsModelo Eloquent usado para as configurações armazenadas
connectionPadrão da aplicaçãoConexão usada pelo modelo e pela migration
tablesettingsTabela usada pelo modelo e pela migration
casts[]Conversões de payload selecionadas pela classe do modelo pai e, opcionalmente, pela chave da configuração

O pacote lê estas variáveis de ambiente:

VariávelPadrão
MODEL_SETTINGS_DATABASE_CONNECTIONDATABASE_CONNECTION, depois a conexão padrão do Laravel
MODEL_SETTINGS_DATABASE_TABLEsettings

Defina a conexão e a tabela antes de executar a migration:

MODEL_SETTINGS_DATABASE_CONNECTION=mysql
MODEL_SETTINGS_DATABASE_TABLE=model_settings

Alterar qualquer um desses valores depois não move os registros existentes.

Configuração das conversões de payload​

O formato legado para todo o modelo continua compatível. Uma conversão processa todos os payloads pertencentes à classe do modelo:

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

Use um mapa por chave quando chaves diferentes precisarem de tipos ou tratamentos diferentes:

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

A correspondência da chave é exata. Pontos não representam caminhos aninhados, e uma chave ausente do mapa usa a conversão JSON padrão. Cada entrada de modelo é uma string de classe para todo o modelo ou um mapa por chave; não existe uma entrada curinga dentro desse mapa. Consulte Conversões de payload para ver os contratos compatíveis e um exemplo de criptografia.

Esquema de armazenamento​

A migration publicada cria estas colunas:

ColunaFinalidade
idChave primária da linha de configuração
item_typeClasse morph ou alias do modelo pai
item_idIdentificador do modelo pai, armazenado como string de até 36 caracteres
is_defaultDistingue os padrões da classe das sobrescritas dos modelos
keyChave da configuração
payloadPayload declarado pela migration como jsonb
created_at e updated_atTimestamps do Laravel

A combinação de item_type, item_id, is_default e key é única. Um índice de consulta em item_type, is_default e item_id atende às leituras dos padrões e do escopo do proprietário.

Os valores padrão da classe e as sobrescritas dos modelos compartilham essa tabela. O pacote não cria uma segunda tabela de valores padrão nem adiciona colunas de metadados de criptografia.

A coluna padrão item_id armazena no máximo 36 caracteres. Identificadores inteiros, string, UUID e ULID cabem nesse esquema quando sua representação como string tem no máximo 36 caracteres. Uma chave primária personalizada mais longa exige uma alteração correspondente na migration.

Os padrões da classe usam item_id = '0' com is_default = true. Um proprietário persistido cuja chave seja o inteiro 0 ou a string '0' usa o mesmo item_id físico com is_default = false. Assim, as duas linhas podem coexistir para o mesmo tipo de modelo e a mesma chave de configuração. Alterar a conexão, o nome da tabela ou os aliases do morph map depois que os dados existirem exige mover ou atualizar as linhas existentes manualmente.

Atualização a partir de uma versão 1.x anterior​

Esta versão altera o contrato de execução além da migration do discriminador de armazenamento:

Comportamento anterior da 1.xComportamento atualAlteração necessária na aplicação
set($key, null), strings vazias, strings de espaços e arrays vazios removiam a linhaset() armazena cada valor JSON exatamenteSubstitua chamadas de exclusão por forget($key)
Entradas vazias em setMany() eram removidas no mesmo loteCada entrada de setMany() é armazenada em um único upsert transacionalMova as chaves removidas para uma chamada separada de forgetMany()
Chaves vazias ou contendo apenas espaços eram aceitasChaves normalizadas vazias lançam InvalidSettingKeyRenomeie ou remova chaves inválidas antes da atualização
Verificações de existência exigiam all()->has($key)has($key) distingue um JSON null armazenado de uma chave ausentePrefira o método específico has()

Uma sobrescrita de modelo com null armazenado agora oculta um valor padrão preenchido da classe até que forget() remova a sobrescrita. Conversões personalizadas de payload agora recebem valores vazios de ambos os setters, e eventos de criação ou atualização de um modelo de armazenamento personalizado os recebem de set(). get() continua aceitando somente um argumento; nenhum valor alternativo do chamador nem alias permanente put() foi adicionado.

Depois de atualizar o pacote, publique a nova migration e execute-a com a aplicação em modo de manutenção:

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

A migration adiciona is_default, classifica cada linha antiga com item_id = '0' como padrão da classe, cria os índices que incluem o discriminador e então remove o índice único anterior. Ela nunca escreve chaves ou payloads das configurações na saída da migration.

Os esquemas 1.x anteriores codificavam da mesma forma os padrões da classe e as linhas de um proprietário real com identificador 0. Portanto, a migration não consegue distinguir uma sobrescrita inserida manualmente de um padrão e classifica ambas como padrões. Depois da migration, revise os dados antigos conhecidos de proprietários com identificador 0 e defina is_default = false nas linhas que forem sobrescritas reais dos modelos.

Não execute a versão antiga do pacote com o esquema atualizado. Ela não grava o discriminador e armazenaria padrões como sobrescritas. Implante a migration e a versão compatível do pacote na mesma janela de manutenção.

O rollback só é seguro antes que exista uma sobrescrita real de proprietário com identificador 0. A migration para antes de alterar o esquema quando encontra item_id = '0' com is_default = false, porque o esquema antigo não pode representar essa linha sem mudar seu sentido. Remova ou exporte essas sobrescritas antes do rollback. Um rollback seguro restaura o índice único anterior e remove is_default.

Substituir o modelo de armazenamento​

O modelo de configurações interno é final. Configure uma substituição em vez de estendê-lo:

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,
];
}
}

Depois, atualize a configuração:

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

A substituição deve continuar compatível com o esquema publicado. Mantenha os atributos preenchíveis e o PayloadCast, a menos que o novo modelo implemente uma serialização equivalente.

No mínimo, o modelo substituto deve preservar estes comportamentos:

RequisitoMotivo
Preencher item_type, item_id, is_default, key e payloadO armazenamento grava esses atributos
Usar a conexão e a tabela configuradasA migration e o repositório devem acessar as mesmas linhas
Converter item_id para stringInteiros, strings, UUID e ULID compartilham uma coluna
Converter is_default para booleanAs resoluções lazy e eager devem ler o mesmo discriminador de escopo
Converter payload com PayloadCast ou equivalenteLeituras e escritas devem preservar o comportamento JSON

Veja também​