with-related-behavior или транзакция

Общие вопросы по использованию фреймворка. Если не знаете как что-то сделать и это про Yii, вам сюда.
Ответить
Nicolai6120
Сообщения: 143
Зарегистрирован: 2014.08.13, 15:08

with-related-behavior или транзакция

Сообщение Nicolai6120 »

Всем привет. В очередной раз уперся в ограничение функционала with-related-behavior.
Нужно сохранить post и все его post->tags, но сохранять нужно естественно только уникальные тэги. Поставив рулю unique на модель Tag я проблему не решил, так как это приводит к тому, что валидация не проходит и соответственно бихэвиор откатывает все сохраненные до этого тэги и сам пост. Как выйти из положения?
Последний раз редактировалось Nicolai6120 2014.11.04, 11:45, всего редактировалось 2 раза.
Nicolai6120
Сообщения: 143
Зарегистрирован: 2014.08.13, 15:08

Re: with-related-behavior и unique validator

Сообщение Nicolai6120 »

Мне пока что видится только ручное обертывание в транзакцию и на каждый тэг делать по 3 запроса, первый проверяет есть ли он уже в таблице, второй в случае если тэг уникальный делает запись в таблицу-связку, третий делает запись в таблицу тэгов. Тут же вопрос, если я обновляю пост и добавил к старым тегам еще парочку, соответсвенно при записи я должен буду контролить на уникальность не только записи в таблице тегов, но и таблице-связке, так как там уже были записи связанные с текущим постом.

with-related-behavior не дает возможности пропустить при создании поста тот тег, который не уникален и уже есть в базе
Также он не дает возможности при апдейте поста удалить тот тег, который был убран из списка тэгов данного поста.

Предполагаю, что нужно будет вручную обернуть все в транзакцию и делать в цикле нужные проверки для каждого отдельного тэга, при этом количество запросов на 1 тэг будет до 7 штук:

1) проверить не был ли тег добавлен ранее к этому посту (в таком случае уже будет существовать запись в таблице-связке 'post_tag')
2) проверить уникальность добавленных новых тэгов в таблице 'tag'
3) добавить уникальные теги в таблицу-связку 'post_tag'
4) добавить уникальные теги в таблицу тэгов 'tag'
5) удалить убранные теги из таблицы-связки 'post_tag'
6) проверить связан ли убранный тег с каким-нибудь еще постом через таблицу-связку 'post_tag'
7) если не связан, удалить тэг из таблицы тэгов 'tag'
Ekstazi
Сообщения: 1428
Зарегистрирован: 2009.08.20, 22:54
Откуда: Молдова, Бельцы
Контактная информация:

Re: with-related-behavior или транзакция

Сообщение Ekstazi »

А вы не думали обойтись без этого поведения для этой задачи ? То есть вручную реализовать сохранение тегов в afterSave, можно даже упростить:
1) удаляем все связи тегов post_tag для текущего поста
2) связываем и добавляем новые записи в таблицу tag, если их еще там нет.

Таблицу tag не обязательно чистить, это не проблема. На мой взгляд это избыточно, да и запросов меньше. Есть еще один способ - с поведением, но очень костыльный и не рекоммендую: переопределить метод save у модели (как я понимаю у Tag). Ну вы там сами разберетесь, куда копать я сказал.
Nicolai6120
Сообщения: 143
Зарегистрирован: 2014.08.13, 15:08

Re: with-related-behavior или транзакция

Сообщение Nicolai6120 »

Большое спасибо за ответ! сохранение тегов в afterSave не дает возможности произвести откат транзакции, в случае, если не все связанные модели прошли валидацию. Стоит заметить, что в моей задаче есть два случая:
1) тэг не прошел валидацию на уникальность
2) тэг не прошел валидацию по длине
В первом случае его просто нужно пропустить при добавлении в таблицу тэгов.
Во втором случае нужно откатить все сохранение, вернуть пользователя на форму и показать ошибки.

Я так и понял, что придется отказаться от него...

Спасибо!
Ekstazi
Сообщения: 1428
Зарегистрирован: 2009.08.20, 22:54
Откуда: Молдова, Бельцы
Контактная информация:

Re: with-related-behavior или транзакция

Сообщение Ekstazi »

Ну вы все еще можете переопределить метод save и validate и там отслеживать это. А на счет транзакций - можете глянуть мой TransactionBehavior, может быть он вам поможет.
Ответить