Yii2:分配动态属性以建模并在网格中显示它们

时间:2017-08-10 13:38:17

标签: php yii2 yii2-advanced-app

为了简短起见,应用程序本身非常简单,只有三个表。

产品:

id
name

属性

id
name
slug

产品属性

id
attribute_id
product_id
value

正如您可能猜测的那样,属性可能是完全随机的,任何内容都可能有任何数量。每个产品都分配了相同的全局属性集。有些是空的,有些是空的。

我想要做的是在标准网格视图中显示它们,就像它是普通模型一样,具有动态预先指定的列和值。基本上说 - 属性应该作为列。

我试图扩展主要的产品型号并在其上使用ActiveDataProvider类,但无济于事,我为每一行重复了自定义属性值,好像缺少某些东西。这是我根据SO的另一个问题创建的课程。

namespace common\models;

use Yii;
use common\models\Attribute;
use common\models\Product;

class ProductDynamic extends Product {


public function init() {
    parent::init();
    $attrExists = ProductAttribute::find()->select(['slug','value'])->joinWith(['attributeModel'])->all();
    if ($attrExists) {
        foreach ($attrExists as $at) {
            $this->dynamicFields[$at['slug']] = $at['value'];
        }
    }
}

private $dynamicFields = [];

public function __get($name) {
    if (array_key_exists($name, $this->dynamicFields))
        return $this->dynamicFields[$name];
    else
    return parent::__get($name);
}

public function __set($name, $value) {
    if (array_key_exists($name, $this->dynamicFields))
        $this->dynamicFields[$name] = $value;
    else
        parent::__set($name, $value);
}

public function rules() {
    return array_merge(parent::rules, $this->dynamicRules);
}

}

我的问题是 - 你会怎么做?如何为模型分配属性,使它们充当ActiveDataProvider可用的标准数据库加载属性?我想我需要以其他方式检索ProductAttributes,这样它们就不会重复了。见下文。

The names are correct but the parameters are all wrong

2 个答案:

答案 0 :(得分:1)

好的,我想我有你的想法......

所以,我认为你可以在Product的模型中生成一个属性(我们称之为ProductAttributeArr),这个属性是一个数组,然后根据Product Attribute表从数据库的Attribute表中检索属性并将它们存储在ProductAttributeArr。

然后,您可以创建一个函数,根据ProductAttributeArr的内容动态生成GridView的参数。这样它应该可以工作。

答案 1 :(得分:0)

由于没有任何反馈,我自己回答,经过一些挖掘,我发现了最快,但也许不是最好的解决方案。

由于ProductDynamic类添加了主要Product模型中的属性,因此我在Product中添加了以下内容以指定正确的列值。当然,如果您有任何意见,请务必提供另一种更简单的方式。

public function afterFind() {
    $attrs = ProductAttribute::find()->select(['slug', 'value'])->joinWith(['attributeModel'])->where(['product_id' => $this->id])->all();

    foreach ($attrs as $a) {
        $this->{$a['slug']} = $a['value'];
    }
}