Удаление записей из связанных таблиц

Общие вопросы по использованию второй версии фреймворка. Если не знаете как что-то сделать и это про Yii 2, вам сюда.
Ответить
guru_nemo
Сообщения: 64
Зарегистрирован: 2017.04.10, 21:28

Удаление записей из связанных таблиц

Сообщение guru_nemo »

Подскажите, как лучше удалить несколько записей из двух связанных (один к одному) таблиц.
Приходит массив id-шников. Надо удалить из одной таблицы все записи с этими id-шниками и из связной с ней, где тоже записи с такими id-шниками.
можно простым перебором сначала из одной, потом из другой.
А есть ли какой-то способ с join. Ну или чтобы удалить записи, передав сразу массив id-шников.

Аватара пользователя
Alexum
Сообщения: 681
Зарегистрирован: 2016.09.26, 10:00

Re: Удаление записей из связанных таблиц

Сообщение Alexum »

Настройка каскадного удаления в БД по ключу. Либо $model->unlinkAll('Название связи', true); Удалить скопом можно при помощи статического метода Класс_модели::deleteAll(['id' => [1,2,3,4,5]]).

guru_nemo
Сообщения: 64
Зарегистрирован: 2017.04.10, 21:28

Re: Удаление записей из связанных таблиц

Сообщение guru_nemo »

Alexum писал(а):
2017.05.16, 21:56
Настройка каскадного удаления в БД по ключу. Либо $model->unlinkAll('Название связи', true); Удалить скопом можно при помощи статического метода Класс_модели::deleteAll(['id' => [1,2,3,4,5]]).
Благодарю за подсказку, почитаю про эти методы поподробнее.

guru_nemo
Сообщения: 64
Зарегистрирован: 2017.04.10, 21:28

Re: Удаление записей из связанных таблиц

Сообщение guru_nemo »

$model->unlinkAll() удаляет только одну запись из двух связанных таблиц?
если использовать Класс_модели::deleteAll(['id' => [1,2,3,4,5]]), то придётся сначала удалить записи из одной таблице, а потом из другой?

Аватара пользователя
Alexum
Сообщения: 681
Зарегистрирован: 2016.09.26, 10:00

Re: Удаление записей из связанных таблиц

Сообщение Alexum »

guru_nemo писал(а):
2017.05.17, 06:37
$model->unlinkAll() удаляет только одну запись из двух связанных таблиц?
Да, например можно переопределить в основной модели метод beforeDelete() и разрывать связь там (но удалять основные модели придётся в цикле через ->delete() а не deleteAll(), т.к. при deleteAll() не вызывается beforeDelete()).
guru_nemo писал(а):
2017.05.17, 06:37
если использовать Класс_модели::deleteAll(['id' => [1,2,3,4,5]]), то придётся сначала удалить записи из одной таблице, а потом из другой?
Всё верно.

Однако самым простым и эффективным остаётся вариант с настройкой каскадного удаления по ключу в БД.

guru_nemo
Сообщения: 64
Зарегистрирован: 2017.04.10, 21:28

Re: Удаление записей из связанных таблиц

Сообщение guru_nemo »

Однако самым простым и эффективным остаётся вариант с настройкой каскадного удаления по ключу в БД.
но для этого придётся настраивать через админку БД. Или это можно как-то сделать средствами yii2?

Аватара пользователя
Alexum
Сообщения: 681
Зарегистрирован: 2016.09.26, 10:00

Re: Удаление записей из связанных таблиц

Сообщение Alexum »

guru_nemo писал(а):
2017.05.17, 11:39
но для этого придётся настраивать через админку БД.
Нет доступа к админке?
guru_nemo писал(а):
2017.05.17, 11:39
Или это можно как-то сделать средствами yii2?
Миграция, либо SQL-запросом сделать ключ с "ON DELETE CASCADE".

Аватара пользователя
PartyPoison
Сообщения: 67
Зарегистрирован: 2017.04.27, 11:04

Re: Удаление записей из связанных таблиц

Сообщение PartyPoison »

guru_nemo писал(а):
2017.05.17, 11:39
Однако самым простым и эффективным остаётся вариант с настройкой каскадного удаления по ключу в БД.
но для этого придётся настраивать через админку БД. Или это можно как-то сделать средствами yii2?
Добавить ключи можно с помощью миграций, также указать действие при обновлении удалении cascade restrict и т д.

Пример миграции:

Код: Выделить всё

class m170412_093436_add_adv_company_struct extends Migration
{
    public function safeUp()
    {

        $this->createIndex('fk_adv_company_site1_idx', 'adv_company', 'site_id');
        $this->addForeignKey('fk_adv_company_site1', 'adv_company', 'site_id', 'site', 'id', 'CASCADE', 'RESTRICT');

        $this->createIndex('fk_banner_item_has_adv_company_adv_company1_idx', 'banner_item_has_adv_company', 'adv_company_id');
        $this->createIndex('fk_banner_item_has_adv_company_banner_item1_idx', 'banner_item_has_adv_company', 'banner_item_id');

        $this->addForeignKey('fk_banner_item_has_adv_company_banner_item1', 'banner_item_has_adv_company',
            'adv_company_id', 'adv_company', 'id', 'CASCADE', 'CASCADE');
        $this->addForeignKey('fk_banner_item_has_adv_company_adv_company1', 'banner_item_has_adv_company',
            'banner_item_id', 'banner_item', 'id', 'CASCADE', 'CASCADE');
    }


}

guru_nemo
Сообщения: 64
Зарегистрирован: 2017.04.10, 21:28

Re: Удаление записей из связанных таблиц

Сообщение guru_nemo »

т.е. если связь в БД будет указанна как cascade, то при удалении одной записи из связных таблиц, автоматически удаляется и связанная с ней из другой таблицы? тогда как в этом случае записывается удаление для нескольких строк?

Аватара пользователя
Alexum
Сообщения: 681
Зарегистрирован: 2016.09.26, 10:00

Re: Удаление записей из связанных таблиц

Сообщение Alexum »

guru_nemo писал(а):
2017.05.17, 15:34
т.е. если связь в БД будет указанна как cascade, то при удалении одной записи из связных таблиц, автоматически удаляется и связанная с ней из другой таблицы? тогда как в этом случае записывается удаление для нескольких строк?
Если не нужны beforeDelete() и afterDelete(), то вызываете Класс_модели::deleteAll(['id' => [1,2,3,4,5]]) для основных записей. Из связанной таблицы БД сама удалит записи.

Аватара пользователя
dsn
Сообщения: 63
Зарегистрирован: 2011.05.11, 11:28
Контактная информация:

Re: Удаление записей из связанных таблиц

Сообщение dsn »

Лучше удалять связанные данные методом beforeDelete - так вы можете попутно указать что еще нужно удалить при удалении записи из бд и вызывать у связаной модели так же метод beforeDelete - может почистить картинки или рейтинг

Код: Выделить всё

    public function beforeDelete()
    {
        if (parent::beforeDelete()) {
            // Clear recept Ingridient Lists
            if($this->receptIngridientLists) {
                foreach ($this->receptIngridientLists as $model) {
                    $model->delete();
                }
            }
            // Clear recept Description Lists
            if($this->receptDescriptionLists) {
                foreach ($this->receptDescriptionLists as $model) {
                    $model->delete();
                }
            }
            return true;
        } else {
            return false;
        }
    }
Кулинарные рецепты с фото на food-list.ru

Ответить