Установка основной строки в отношении один ко многим

В некоторых случаях у вас может быть строка по умолчанию или основная строка с one to many отношения. Который определяется по столбцу, как primary, И если вы измените основной ряд, вы установите тот, который вы хотите 1 и другие, чтобы 0;

Вот пример, показывающий мой подход к решению этой проблемы с помощью Yii2,

Пример: у нас есть две таблицы User а также UserAddress

Это функция в UserAddress учебный класс. Это работа, чтобы сделать текущий UserAddress в качестве основного адреса для User,

public function makePrimary() {
    $addresses = $this -> getUser() -> getUserAddresses() -> all();

    foreach ( $addresses As $address ) {
        $address -> is_primary = 0;
        $address -> save();
    }

    $this -> is_primary = 1;
    $this -> save();
}

Теперь мой вопрос, это хороший подход, который вы обычно делаете? Если нет, можете ли вы предложить лучший подход для достижения того же результата?

2 ответа

Благодаря Balaji Viswanath, Его ответ напоминает мне другое решение, которое может достичь того же. Но я думаю, что лучше.

Вот код (Функции находятся внутри UserAddress модельный класс)

public function makePrimary() {
    self::updateAll(['is_primary' => 0], 'is_primary=1 AND user_ID=' . $this -> user_ID);
    // or just
    // self::updateAll(['is_primary' => 0], 'user_ID=' . $this -> user_ID);

    $this -> is_primary = 1;
    $this -> save();
}

С вышеупомянутым решением. Я полагаю, что достиг той же цели с помощью только 2 запросов Balaji Viswanath делает с решением, которое он придумал.

При вашем подходе производительность имеет большое значение, так как чем больше число строк адресов, тем больше нагрузка на сервер.

Предположим, у вас есть 50 адресных строк для одного пользователя. Согласно вашему коду выполнение запроса выглядит следующим образом

  1. выполнить запрос для получения пользовательской записи при вызове $this->getUser()
  2. выполнить запрос для получения адресов пользователей при вызове getUserAddresses()->all()
  3. перебрать все 50 строк адреса и выполнить 50 запросов на обновление, чтобы установить для is_primary значение 0
  4. выполнить запрос для сохранения текущей выбранной строки как is_primary = 1

Таким образом, в общей сложности база данных MySQL запрашивалась около 53 раз.

Но рассмотрим следующий подход. Я предполагаю, что getUser () связан с getUserAddresses () через "user_id", а имя таблицы адресов - "user_addresses"

public function makePrimary() {
    \Yii::$app->db->createCommand()->update('user_addresses', array(
        'is_primary'=>0,
    ), 'user_id=:id', array(':id'=>$this->user_id)); //Set is_primary as 0 for all addresses in one go

    $this -> is_primary = 1;
    $this -> save();
}

Здесь вы можете обновить is_primary как 0 для всех строк, используя один запрос на обновление. Таким образом, всего вы использовали 2 запроса для выполнения задачи

Другие вопросы по тегам