/** * Применение фильтров по связанным данным модели. * Поскольку модель имеет 2 связи многие ко многим - необходимо иметь возможность осуществлять строгую * фильтрацию по обеим связям. На чистом AR это сделать крайне проблематично, в силу этого часть запроса * сформирована вручную. * * @param ActiveQuery $query * @param array $tagIds * @param array $authorIds */ public static function applyFilterForRelatedData(ActiveQuery $query, array $tagIds = [], array $authorIds = []) { if ($tagIds && $authorIds) { // Строгая фильтрация по обеим полям // Произведение фильтруемого количества меток на количество авторов - даст требуемое значение // для фильтрации по обеим критериям $cnt = count($tagIds) * count($authorIds); $query->addSelect([Book::tableName() . '.*', 'COUNT(book_at_tag.book_id) AS cntTag', 'COUNT(book_at_author.book_id) AS cntAuthor'])->leftJoin('book_at_tag', '`book`.`id` = `book_at_tag`.`book_id`')->leftJoin('book_at_author', '`book`.`id` = `book_at_author`.`book_id` ')->andFilterWhere(['tag_id' => array_values($tagIds), 'author_id' => array_values($authorIds)])->groupBy(['book_at_tag.book_id', 'book_at_author.book_id'])->having('cntTag = ' . $cnt)->andHaving('cntAuthor = ' . $cnt); } elseif ($tagIds || $authorIds) { if ($tagIds) { // Применение фильтра по наличию всех меток в $tagIds для объекта $query. $term = 'tag'; $list = $tagIds; } else { // Применение фильтра по наличию всех авторов в $authorIds для объекта $query. $term = 'author'; $list = $authorIds; } $query->addSelect([Book::tableName() . '.*', 'COUNT(' . Book::tableName() . '.id) AS cnt'])->joinWith($term . 's')->andFilterWhere([$term . '_id' => array_values($list)])->groupBy('book_id')->having('cnt = ' . count($list)); } }
public function down() { echo "m151129_133034_books_table_create cannot be reverted.\n"; $this->dropTable(\app\models\Book::tableName()); }
public function safeDown() { $this->dropForeignKey('fk_book_author', Book::tableName()); }
public function init() { $this->tableName = Book::tableName(); parent::init(); }
/** * @inheritdoc */ public function init() { parent::init(); if ($this->scenario == 'update') { $data = Book::find()->where([Book::tableName() . '.id' => $this->id])->joinWith(['categories' => function ($query) { $query->select(['id', 'name']); $query->asArray(); }, 'users' => function ($query) { $query->select(['id', 'name', 'surname']); $query->asArray(); }])->one(); $this->categories = []; $this->users = []; if ($data && $data->categories) { foreach ($data->categories as $category) { $this->categories[] = $category['id']; $this->categoriesCurrent[$category['id']] = $category['name']; } } if ($data && $data->users) { foreach ($data->users as $user) { $this->users[] = $user['id']; $this->usersCurrent[$user['id']] = $user['name'] . ' ' . $user['surname']; } } } }
/** * @param int $state * @return $this */ public function status($state = Book::STATUS_ACTIVE) { $this->andWhere([Book::tableName() . '.status' => $state]); return $this; }