为了简短起见,应用程序本身非常简单,只有三个表。
产品:
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,这样它们就不会重复了。见下文。
答案 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'];
}
}