Поведінка Yii2 Behaviors для збереження пов’язаних даних «багато хто до багатьох» (many to many)

Там все добре, але мене не влаштовувало: неможливість видалити всі дані з таблиці зв'язку, один запис обов'язково залишається надмірна перевантаженість на користь зайвого на мій погляд прагнення до універсалізації. На смак і колір взагалі. Тому я ризикнув написати свій варіантBehaviors Yii2 many to many.
Отже, що нам дано. Є три таблиці:post,tag таpost_has_tag, для них згенеруємо три моделі Post, Tag та PostHasTag, таблиці наприклад такі:
Код моделей наводити не буду, думаю, що генерація моделей за допомогою Gii не має складності. Остання таблиця є таблицею зв'язку між постами і тегами, і вона має лише два поля:post_id іtag_id, з назв полів зрозуміло що має зберігатися. Ось з цією таблицею ми і працюватимемо, поведінка повинна вміти віддавати потрібні дані з цієї таблиці, а також зберігати і при необхідності видаляти їх. Так, і в поведінку як параметри потрібно передавати ім'я зв'язку та ім'я атрибуту моделі.
Що б хотілося: насамперед це простота використання, ну і щоб усе зберігалося, оновлювалося, видалялося, транзакції щоб були, ось власне і все. Так, і мова тут піде саме про тип зв'язку «many to many» через таблицю зв'язку, в якій тільки два стовпці - значення первинних ключів зв'язаних таблиць. Поведінки для роботи зі зв'язками один до одного і до багатьох ми напишемо наступного разу.
Перше що потрібно зробити, це в моделі Post позначити зв'язок багато до багатьох через таблицю зв'язкуpost_has_tag, згідно з документацією Yii2 це робиться таким чином:
Далі необхідно в тій самій моделі Postоголосити поведінку, де tags - це ім'я вищезазначеного зв'язку, а tag_list - ім'я неіснуючого поки атрибута моделі, як він у моделі потім з'явиться буде розказано трохи нижче, підключення дуже просте:
Ну і щоб закінчити з моделлю, до правил валідації додамо safe - атрибутtag_list :
Підготовчі заходи для моделі завершено, залишилося підготувати виставу. Для маніпуляцій з тегами, як і з іншими сутностями, з якими власник зв'язку співвідноситься як один до багатьох абобагато до багатьох, зручно використовувати JQUERY плагін Chosen. Для інтеграції цього плагіна з Yii2 є кілька вже готових рішень, одне з яких ми підключимо в нашому відображенні.
- tag_list - ім'я атрибуту моделі
- items - масив тегів, відсортованих на ім'я, і за допомогою методу хелпера ArrayHelper::map приведений до виду ключ (id) - значення (title):
Підготовчі роботи закінчені, настав час приступати до розробки самогоПоведіння. Для початку оголосимо дві властивості:
Далі створимо методevents() і призначимо у ньому обробники подій. У нашому випадку обробник подій буде один -changeRelations.
Магічний метод __get() повертатиме масив айдишників тегів, що належать відповідній посаді:
Магічний метод __set() встановлює приватну властивість $this->_values:
Ну і останній метод у нашій поведінці, який зберігає та видаляє дані із пов'язаної моделі. Метод документований.
На завершення повний код нашої поведінки, який для прикладу можна помістити в папку components\behaviors поточної програми:
Підсумовуючи вищенаписане, можна сказати, що ми отримали поведінку відповідно до наших вимог. Просте у використанні та виконуючевсе, що було задумано :).