Activerecord Yii2从连接表中获取列并在gridview中使用

Activerecord Yii2从连接表中获取列并在gridview中使用,activerecord,yii2,Activerecord,Yii2,我的部分方案如图所示: 连接表映射了哪些项目属于哪个类别,其中“特色”列将该项目标记为该类别中的特色项目 我需要做的是获取特定类别中所有项目的列表,包括来自连接表的“featured”属性,并将数据传递到gridview中进行显示 我已经为category\u item表创建了一个模型,并尝试实现提出的解决方案,但是如何访问数据并将其传递到gridview 类别模型 public function getCategoryItems() { return $this->hasMany

我的部分方案如图所示:

连接表映射了哪些项目属于哪个类别,其中“特色”列将该项目标记为该类别中的特色项目

我需要做的是获取特定类别中所有项目的列表,包括来自连接表的“featured”属性,并将数据传递到gridview中进行显示

我已经为
category\u item
表创建了一个模型,并尝试实现提出的解决方案,但是如何访问数据并将其传递到gridview

类别模型

public function getCategoryItems()
{
    return $this->hasMany(CategoryItem::className(), ['category_id' => 'id']);
}

public function getItems()
{
    return $this->hasMany(Item::className(), ['id' => 'item_id'])->viaTable('{{%category_item}}', ['category_id' => 'id']);
}
public function search($params)
{
    $query = Category::find()->with('items')->with('categoryItems');

    $dataProvider = new ActiveDataProvider([
        'query' => $query,
    ]);

    $this->load($params);

    if (!$this->validate()) {
        return $dataProvider;
    }

    $query->andFilterWhere([
        'id' => $this->id,
        'type' => $this->type,
    ]);

    $query->andFilterWhere(['like', 'title', $this->title])
        ->andFilterWhere(['like', 'description', $this->description]);

    return $dataProvider;
}
public function getItemCategories()
{
    return $this->hasMany(CategoryItem::className(), ['item_id' => 'id']);
}

public function getCategories()
{
    return $this->hasMany(Category::className(), ['id' => 'category_id'])->viaTable('{{%category_item}}', ['item_id' => 'id']);
}
类别搜索模型

public function getCategoryItems()
{
    return $this->hasMany(CategoryItem::className(), ['category_id' => 'id']);
}

public function getItems()
{
    return $this->hasMany(Item::className(), ['id' => 'item_id'])->viaTable('{{%category_item}}', ['category_id' => 'id']);
}
public function search($params)
{
    $query = Category::find()->with('items')->with('categoryItems');

    $dataProvider = new ActiveDataProvider([
        'query' => $query,
    ]);

    $this->load($params);

    if (!$this->validate()) {
        return $dataProvider;
    }

    $query->andFilterWhere([
        'id' => $this->id,
        'type' => $this->type,
    ]);

    $query->andFilterWhere(['like', 'title', $this->title])
        ->andFilterWhere(['like', 'description', $this->description]);

    return $dataProvider;
}
public function getItemCategories()
{
    return $this->hasMany(CategoryItem::className(), ['item_id' => 'id']);
}

public function getCategories()
{
    return $this->hasMany(Category::className(), ['id' => 'category_id'])->viaTable('{{%category_item}}', ['item_id' => 'id']);
}
项目模型

public function getCategoryItems()
{
    return $this->hasMany(CategoryItem::className(), ['category_id' => 'id']);
}

public function getItems()
{
    return $this->hasMany(Item::className(), ['id' => 'item_id'])->viaTable('{{%category_item}}', ['category_id' => 'id']);
}
public function search($params)
{
    $query = Category::find()->with('items')->with('categoryItems');

    $dataProvider = new ActiveDataProvider([
        'query' => $query,
    ]);

    $this->load($params);

    if (!$this->validate()) {
        return $dataProvider;
    }

    $query->andFilterWhere([
        'id' => $this->id,
        'type' => $this->type,
    ]);

    $query->andFilterWhere(['like', 'title', $this->title])
        ->andFilterWhere(['like', 'description', $this->description]);

    return $dataProvider;
}
public function getItemCategories()
{
    return $this->hasMany(CategoryItem::className(), ['item_id' => 'id']);
}

public function getCategories()
{
    return $this->hasMany(Category::className(), ['id' => 'category_id'])->viaTable('{{%category_item}}', ['item_id' => 'id']);
}
控制器

public function actionCategory($id = null)
{
    if($id == null) {
        $dataProvider = new ActiveDataProvider([
            'query' => Category::find()->all(),
        ]);

        return $this->render('category', [
                'dataProvider' => $dataProvider,
        ]);
    } else {

        $category = Category::findOne($id);

        if($category) {
            $searchModel = new CategorySearch();

            $itemsDataProvider = new ActiveDataProvider([
                'query' =>  $searchModel->search(['CategorySearch'=>['id'=>$id]]),
            ]);

            return $this->render('editCategory', [
                'itemsDataProvider' => $itemsDataProvider
                'model' => $category,
            ]);
        } else {
            throw new NotFoundHttpException('The requested page does not exist.');
        }
    }
}
查看

<div class="row">
    <div class="col-md-12">
        <h2>Items</h2>
        <?= GridView::widget([
            'dataProvider' => $itemsDataProvider,
            'columns' => [

                'id',
                'name',
                'categoryItems.id',
                [
                    'attribute' => 'items.description',
                    'format' => 'html',
                    'value' => 'description',
                ],
                [
                    'label'=>'Highlights',
                    'format'=>'raw',
                    'value'=>function($data) use ($model) {
                        if(TagFeaturedItem::find()->where(['item_id'=>$data->id, 'tag_id'=>$model->id])->all()) {
                            return Html::a('Remove as Highlighted', ['/highlights/category/'.$model->id.'/remove/'.$data->id], ['class'=>'btn btn-xs btn-danger']);
                        } else {
                            return Html::a('Add as Highlighted',['/highlights/category/'.$model->id.'/add/'.$data->id], ['class'=>'btn btn-xs btn-primary']);
                        }
                    },
                ],
            ],
        ]); ?>
    </div>
</div>

项目
一般来说,视图文件是试图找到解决方案时的混合匹配。
TagFeaturedItem模型来自该视图的早期版本,请参见

在我看来,您的项目中可能存在一些设计缺陷,我将不探讨这些缺陷;我将集中讨论如何将相关数据导入gridview的问题

您可以在gridview中创建一个自定义列,然后获取相关数据,您可以向gridview列数组中添加如下内容:

    [
            'label'=>'featured',
            'format'=>'raw',
            'value'=>function($data)
            {
                $categories = $data->categories; 

                $content = "";
                foreach($categories as $category)
                    $content .= $category->title."<br/>";

                return $content;
            }
    ],
[
“标签”=>“特色”,
'格式'=>'原始',
'value'=>函数($data)
{
$categories=$data->categories;
$content=“”;
foreach($categories作为$category)
$content.=$category->title.“
”; 返回$content; } ],

请注意,
$data
表示数据提供程序返回的模型,在上面的示例中是从项目模型返回的

我非常有兴趣了解可能存在哪些设计缺陷(需要修复和学习),请详细说明。另外,获取相关数据并不麻烦,而是从联接表中获取并显示“featured”列。@jimmy您的控制器actionCategory有点奇怪。至少到现在为止我还没有这样看。通常,有一个actionIndex和actionUpdate方法。你已经把它们组合成了一个动作,我用这种方法来实现一个更平坦的url结构。我的url应该类似于
突出显示/类别
,应该映射到经典的
类别/索引
突出显示/类别/1
应该映射到
类别/更新/1
。但我也有
亮点/关键词
。问题是,在这个项目中,对于特定的客户机,类别/关键字是相同的(以编程方式),并且具有相同的操作。因此,我将它们合并到一个表中,其中有一个标志用于区分类型。@jimmy,而且您在使用CategorySearch时,已经有了某个类别…@jimmy,我想您通常会使用urlManager规则来解决这个问题。您还可以向我们显示视图文件吗?谢谢。这整件事不会导致错误?您只想访问功能标志吗?我看到另一个类TagFeaturedItem…是的,我可以通过
$category->items
关系获取类别项目,但是
featured
列当然丢失了。啊,对不起,对我来说太难了。。。想知道为什么
'categoryItems.id
'和
'items.description'
有效。为什么
newActiveDataProvider(['query'=>$searchModel->search(['CategorySearch'=>['id'=>$id]]),])工作。查询不应该是一个QueryInterface实现吗?我想在这个问题上从头开始,因为我自己一直在尝试在互联网上搜索所有的文章和建议。对于这种类型的问题,文档很少/不存在,所以现在我正在寻找一个解决方案,我可以扔掉迄今为止编写的任何代码,实现一些有效的东西。