Добавляем редактирование many-to-many в Yii2

27.11.2015

В фреймворке Yii2 есть инструмент gii, который умеет генерировать модели на основе структуры БД, а также контроллеры и формы для CRUD. 

Но сгенерированный CRUD (англ. create, read, update, delete — «создание, чтение, обновление, удаление») не делает редактирование связей между объектами. В этой небольшой заметке мы разберемся как это можно добавить.

Пример: есть компании (Company), платформы, для которых они разрабатывают, (Platform) и связи (PlatformCompany).

В класс Company добавляем аттрибут для платформ, сеттер, геттер и добавляем сохранение платформ в afterSave.

class Company extends ActiveRecord {
   protected $platforms = [];
     /**
     * @param array $platforms
     */
    public function setPlatforms(array $platforms)
    {
        $this->platforms = $platforms;
    }
    public function getPlatforms()
    {
        if (!count($this->platforms))
            return $this->platforms
                = ArrayHelper::getColumn($this->getPlatformCompanies()->all(), 'platform_id');
        else
            return $this->platforms;
    }
    public function afterSave($insert, $changedAttributes)
    {
        $this->updatePlatforms();
        parent::afterSave($insert, $changedAttributes);
    }

    protected function updatePlatforms()
    {
        PlatformCompany::deleteAll(array('company_id' => $this->id));
        if (is_array($this->cats))
            foreach ($this->platforms as $id) {
                $platformCompany = new PlatformCompany();
                $platformCompany->company_id = $this->id;
                $platformCompany->platform_id = $id;
                $platformCompany->save();
            }
    }

updatePlatforms можно сделать одним sql запросом через batchInsert, но тогда без валидации:

    protected function updatePlatforms()
    {
        PlatformCompany::deleteAll(array('company_id' => $this->id));
        if (is_array($this->cats)) {
            $rows = [];
            foreach ($this->platforms as $id) {
                $rows[] = [$this->id, $id];
            }
            Yii::$app->db->createCommand()->batchInsert(
                PlatformCompany::tableName(), ['company_id', 'platform_id'], $rows)->execute();
        }
    }

Осталось добавить в форму (_form.php) поле:

<?= $form->field($model, 'platforms')->checkBoxList(ArrayHelper::map(Platform::find()->all(), 'id', 'name')) ?>

Готово.


3 оценки
Комментарии
Георгий:
Спасибо за статью.
У Вас в методе updatePlatforms() строка
if (is_array($this->cats)) {

Я так понимаю там должно было быть $this->platforms ??

Оставить комментарий