Сложный запрос к бд

Общие вопросы по использованию второй версии фреймворка. Если не знаете как что-то сделать и это про Yii 2, вам сюда.
Ответить
Artikk
Сообщения: 742
Зарегистрирован: 2017.02.10, 09:12

Сложный запрос к бд

Сообщение Artikk »

Здравствуйте. Есть бд: http://clip2net.com/s/3QFXXT9 news. В ней есть поле с номером категории.
В модели news я сделал:

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

public function  getCategory(){
        return $this->hasMany(Category::ClassName(), ['id' => 'category_id']);
    }
А в модели category:

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

public function  getNews(){
        return $this->hasMany(News::ClassName(), ['category_id' => 'id']);
    }
вот сами категории http://c2n.me/3QFY4wv

вот мой запрос в контроллере:

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

$query = News::find()->where(['status' => '1']);
$pages = new Pagination(['totalCount' => $query->count(), 'pageSize' => 20, 'forcePageParam' => false, 'pageSizeParam' => false]);
$news = $query->offset($pages->offset)->orderBy(['id'=>SORT_DESC])->limit($pages->limit)->all();
так я получаю ссылку и название подкатегории:

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

<?php foreach($news as $item):?>
            <div class="news_wd">
                <p class="catz"><a href="<?=\yii\helpers\Url::to(['category/view', 'id'=> $item['category_id']]) ?>"><?= $item->category[0]->name?></a></p>
                <p class="catz2"><a href="<?=\yii\helpers\Url::to(['news/view', 'id'=> $item['id']]) ?>"><?= $item->title?></a></p>
            </div>
            <hr>
            <?php endforeach;?>
а как мне получить еще и саму категорию(родителя получается)?
Artikk
Сообщения: 742
Зарегистрирован: 2017.02.10, 09:12

Re: Сложный запрос к бд

Сообщение Artikk »

неужели никто не знает?
Аватара пользователя
VeerUP
Сообщения: 17
Зарегистрирован: 2013.10.25, 10:35

Re: Сложный запрос к бд

Сообщение VeerUP »

В вашем случае в модели News я так понимаю связь для категорий должна быть HAS_ONE
В модели Category можно реализовать связь:

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

public function getParentCategory()
{
    return $this->hasOne(static::className(), ['id' => 'parent_id']);
}
В виде в итоге получится:

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

$item->category->name // категория
$item->category->parentCategory->name // родительская категория
Последний раз редактировалось VeerUP 2017.12.27, 15:41, всего редактировалось 1 раз.
Loveorigami
Сообщения: 977
Зарегистрирован: 2014.08.27, 21:54

Re: Сложный запрос к бд

Сообщение Loveorigami »

А как у вас реализовано хранение дерева категорий? Исходя из этого - получайте родителя, зная потомка.
Например, для nestedSets - https://github.com/paulzi/yii2-nested-sets#selection

+ зачем тут

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

public function  getCategory(){
        return $this->hasMany(Category::ClassName(), ['id' => 'category_id']);
    }
hasMany()?
Должно быть hasOne(), т.к. у новости 1 категория.
Artikk
Сообщения: 742
Зарегистрирован: 2017.02.10, 09:12

Re: Сложный запрос к бд

Сообщение Artikk »

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

public function getParentCategory()
{
    return $this->hasOne(static::className(), ['id' => 'parent_id']);
}
это в модель category или news? вставил в category, не работает.
контроллер

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

public function actionIndex(){


		$query = News::find()->where(['status' => '1']);
		$pages = new Pagination(['totalCount' => $query->count(), 'pageSize' => 20, 'forcePageParam' => false, 'pageSizeParam' => false]);
		$news = $query->offset($pages->offset)->orderBy(['id'=>SORT_DESC])->limit($pages->limit)->all();


		$this->setMeta('Название','ключи', 'описание');
		return $this->render('index', compact('news', 'pages'));
	}
модель news

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

public function  getCategory(){
        return $this->hasMany(Category::ClassName(), ['id' => 'category_id']);
    }

модель category

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

  public function  getNews(){
        return $this->hasMany(News::ClassName(), ['category_id' => 'id']);
    }

    public function getParentCategory()
    {
        return $this->hasOne(static::className(), ['id' => 'parent_id']);
    }

вид:

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

<?php foreach($news as $item):?>
            <div class="news_wd">
                <?= print_r($item->category->name)?>
                <p class="catz"><?= $item->category->name?> <a href="<?=\yii\helpers\Url::to(['category/view', 'id'=> $item['category_id']]) ?>"><?= $item->category[0]->name?></a></p>
                <p class="catz2"><a href="<?=\yii\helpers\Url::to(['news/view', 'id'=> $item['id']]) ?>"><?= $item->title?></a></p>
            </div>
            <hr>
            <?php endforeach;?>
как решить?
Аватара пользователя
VeerUP
Сообщения: 17
Зарегистрирован: 2013.10.25, 10:35

Re: Сложный запрос к бд

Сообщение VeerUP »

Как уже было написано, в модели News у категорий должна быть связь hasOne
Artikk
Сообщения: 742
Зарегистрирован: 2017.02.10, 09:12

Re: Сложный запрос к бд

Сообщение Artikk »

модель news

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


public static function tableName()
    {
        return 'news';
    }


    public function  getCategory(){
        return $this->hasOne(Category::ClassName(), ['id' => 'category_id']);
    }

сделал. <?= $item->category->name?> так вызвал подкатегорию. а как категорию теперь вызвать?
Artikk
Сообщения: 742
Зарегистрирован: 2017.02.10, 09:12

Re: Сложный запрос к бд

Сообщение Artikk »

$item->category->parentCategory->name вызвал так. спасибо. а можете объяснить почему has one именно?
Аватара пользователя
VeerUP
Сообщения: 17
Зарегистрирован: 2013.10.25, 10:35

Re: Сложный запрос к бд

Сообщение VeerUP »

В вашем случае нет смысла использовать hasMany, так как судя по структуре таблицы у одной новости может быть только одна категория. Советую почитать: http://stuff.cebe.cc/yii2docs-ru/guide- ... ional-data
Artikk
Сообщения: 742
Зарегистрирован: 2017.02.10, 09:12

Re: Сложный запрос к бд

Сообщение Artikk »

Спасибо. и последний вопрос, а если у меня например будет такое:
Контроллер

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

public function actionView($id){

		$cat = Category::findOne($id);
		if(empty($cat)){
			throw new \yii\web\HttpException(404, 'Такой категории нет!');
		}
		$this->setMeta($cat->name .'Название',$cat->keywords, $cat->description);
		return $this->render('view', compact('cat', 'news', 'pages'));
	}
Модель category

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

public static function tableName()
    {
        return 'category';
    }

    public function getParentCategory()
    {
        return $this->hasOne(static::className(), ['id' => 'parent_id']);
    }
так я получаю <?= $cat->name?> имя подкатегории, а как мне тогда категорию получить?
Artikk
Сообщения: 742
Зарегистрирован: 2017.02.10, 09:12

Re: Сложный запрос к бд

Сообщение Artikk »

$cat->parentCategory->name точно также, понял)
Loveorigami
Сообщения: 977
Зарегистрирован: 2014.08.27, 21:54

Re: Сложный запрос к бд

Сообщение Loveorigami »

Это в том случае, если у вас один уровень вложенности
Artikk
Сообщения: 742
Зарегистрирован: 2017.02.10, 09:12

Re: Сложный запрос к бд

Сообщение Artikk »

да, понял) не подскажите, есть вообще готовые расширения какието для меню. чтобы было несколько уровней вложенности?
Artikk
Сообщения: 742
Зарегистрирован: 2017.02.10, 09:12

Re: Сложный запрос к бд

Сообщение Artikk »

и еще вопрос, а как тут получить категорию. рядом с подкатегорией?

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

<?php echo $form->field($model, 'category_id')->dropDownList(\yii\helpers\ArrayHelper::map(\app\models\Category::find()->where(['!=', 'parent_id', '0'])->all(), 'id', 'name'))?>
вот так я получаю подкатегории.
Artikk
Сообщения: 742
Зарегистрирован: 2017.02.10, 09:12

Re: Сложный запрос к бд

Сообщение Artikk »

есть варианты как это сделать? а точнее вставить в dropDownList
Artikk
Сообщения: 742
Зарегистрирован: 2017.02.10, 09:12

Re: Сложный запрос к бд

Сообщение Artikk »

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

<?php
    $cat = \app\models\Category::find()->where(['!=', 'parent_id', '0'])->all();
    
    foreach($cat as $c){
        $listData[] = ["id" => $c->id, "name" => $c->parentCategory->name.': '.$c->name];
    }
    $data = \yii\helpers\ArrayHelper::map($listData, 'id', 'name');

    ?>
    <?php echo $form->field($model, 'category_id')->dropDownList($data)?>
вроде так решил
Ответить