у меня есть таблица Stream, которая в себе агрегирует посты с соц. сетей.
Есть так же свои собственные сущности типа новости/аудио/видео/фото постов
которые представлены в виде отдельных таблиц, но с небольшой денормализирующей линковокой в таблице Stream
в каждой из этих таблиц есть поле статуса (показывать или не показывать пост)
вот возникла задача синхронизировать статус поста. Те если выключат пост в Stream, то зеркально надо выключить и прилинкованный пост в новости/аудио/видео/фото. Так же и надо изменить состояние в таблице Stream, если изменилось состояние в какой-то связанной таблице.
делать изменение статуса всех связанных таблиц в одной модели мне кажется не верным и совершенно кривым.
делать это путем выполнения в контролере серии методов из моделей вроде как лучше, но все равно мне это решение не нравится
в каком-то контролере можно упустить обновление в какой-нибудь модели.
в общем прошу совета как лучше и правильней организовать обновление статуса в нескольких таблицах
P.S.: всплывает идея использовать события, но я как-то не очень вкурил как они в Yii работают.
В коде держать такие вещи смысла нет. Пусть это делает база данных. Напишите хранимую процедуру и вызывайте ее триггером по событию - ON UPDATE. В процедуре следует сверять изменилось ли состояние status, чтобы лишний раз не обновлять записи.
В случае Yii - лучше это делать действительно в модели (только помнить, что AR-события не во всех случаях срабатывают). Это вполне ок, учитывая тот факт, что данные внезапно могут быть модифицированы не только из одного контроллера. Ну, например, дополнительное API какое-нибудь потребуется - и трындец. А так меньше логики таскать придется в случае чего.
Плюс ко всему прочему если в каждой модели повесить обработчик afterUpdate, к примеру, то можно выстраивать мощные цепочки типа обновилась модель - сработал обработчик, пнул связанную модель, сработал уже ее обработчик итд.
PS. В Yii2, кстати, уже из коробки идут oldAttributes, что позволяет без лишних телодвижений проверять изменение конкретного поля.
Я в таких случаях всегда думаю примерно так: а что будет, если БД может модифицироваться не только из одного скрипта?
И выходит, что либо всю работу с БД придется протаскивать через какое-то Yii-api, либо перевесить логику на БД и успешно сохранять консистентность при любых обстоятельствах. Хоть через вебинтерфейс работа идет, хоть из перлового скрипта, хоть через консоль БД: данные всегда находятся в нужном состоянии.
По личному опыту - триггеры в БД лучше событий AR.
Действительно события не всегда срабатывают, в частности у меня были проблемы с afterUpdate и afterSave. Возможно я что то делал неверно, но не стал заморачиваться и искать причину, а переделал все на триггеры. Перестали пропадать данные со статистик, перестали оставаться непонятные записи(хотя должны были удаляться).
Если честно сам поначалу боялся что тяжело и так далее, а на самом деле оказалось намного проще, ну и еще + выигрыш в производительности (по сравнению с тем же AR).
Да тут будут проблемы, но я сомневаюсь что это нельзя обойти. С внешними ключами триггеры еще могут блокировать удаление и роллбеки, ну и собственно вести себя непредсказуемо.