#laravel #eloquent
#laravel #красноречивый
Вопрос:
У меня есть следующая таблица:
$table->boolean('prop_enabled');
$table->boolean('prop1_enabled')->nullable();
$table->boolean('prop2_enabled')->nullable();
$table->boolean('prop3_enabled')->nullable();
Мое требование заключается в том, что когда prop_enabled
false
, тогда prop1_enabled
prop2_enabled
и prop3_enabled
значения должны быть установлены null
во время вставки или обновления строки.
Подходит ли мой дизайн таблицы для решения проблемы? Если моя таблица подходит для решения проблемы, какой подход лучше подходит для выполнения моих требований? У меня есть варианты создания триггера в базе данных или переопределения Create
и save
метода из Model
класса.
Комментарии:
1. вам не нужно будет переопределять эти методы, в моделях есть события, которые вы можете прослушивать, например
saving
, событие2. Спасибо @lagbox, если я использую прослушиватель событий, будет ли 2 запроса для каждого создания? 1-й для создания строки, 2-й запрос для обновления новой строки на основе столбца prop_enabled
3. нет…
saving
выполняется до сохранения модели4. вы также можете просто игнорировать другие поля независимо от их значений в базе данных, когда
prop_enabled
значение false с помощью mutator . Что будет менее тяжелым для производительности и позволит избежать проблем, связанных с массовым назначением и методами вставки / обновления в обход модели
Ответ №1:
Я считаю, что лучшим подходом является решение Observer. Использование мутатора требует большого количества мутаторов для защиты вашей структуры данных и / или бизнес-логики, которые могут его игнорировать. Наблюдатель использует события, и вы можете только обойти его запуск, избегая использования eloquent.
Вы можете подключиться к saving
событию в моделях. Это позволит просмотреть модель перед ее сохранением, затем изменить ее, если ваш случай верен, и тем самым создать оптимальную вставку запроса 1. Независимо от того, какова ваша бизнес-логика, это сработает перед созданием или обновлением.
class YourModelObserver {
public function saving(YourModel $model) {
if ($model->prop_enabled === false) {
$model->prop1_enabled = false;
$model->prop2_enabled = false;
$model->prop3_enabled = false;
}
}
}
В провайдере вы должны зарегистрировать своего слушателя.
public function boot()
{
YourModel::observe(YourModelObserver::class);
}
Моя самая большая проблема с вашим дизайном — это обычный запах кода, который я видел раньше. Именование переменных после чисел, когда у вас их несколько, мне кажется неправильным. Что произойдет, если вы получите 4. prop и как вы будете их показывать и обновлять? Альтернативным подходом было бы иметь их в более общем виде в другой таблице, когда у них было имя или ключ вместо того, чтобы быть prop1 или prop2 и иметь логику, связанную с их созданием или обновлением. Если вы уверены, что prop1, prop2 и prop3 не изменят дизайн, это хорошо на данный момент.
Комментарии:
1. Спасибо @mrhn за вашу поддержку и ваш комментарий по поводу запаха кода. Я просто хочу сделать свойство более общим, я бы не стал использовать это наименование в проекте.
2. К вашему сведению, в текущем проекте, над которым я работаю, у них были свойства person1, person2 и person3, и это создало столько проблем, что оно было разработано именно так.