Yii2: назначение динамических свойств модели и отображение их в сетке

Короче говоря, само приложение действительно простое, имеет только три таблицы.

Товар:

id
name

атрибут

id
name
slug

Атрибут продукта

id
attribute_id
product_id
value

Как вы можете догадаться, атрибуты могут быть абсолютно случайными, с любым контентом, и их может быть любое количество. Каждому продукту назначен одинаковый набор глобальных атрибутов. Некоторые пусты, некоторые заполнены.

То, что я хочу сделать, это отобразить их в стандартном Gridview, так же, как если бы это была обычная модель с динамически заданными столбцами и значениями. По сути, атрибуты должны служить столбцами.

Я пытался расширить основную модель продукта и использовать в ней класс 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 другим способом, чтобы они не повторялись. Увидеть ниже.

Имена верны, но параметры неверны

1

Решение

Хорошо, я думаю, у меня есть твоя идея …

Итак, я думаю, что вы можете сгенерировать атрибут в модели Product (мы назовем его ProductAttributeArr), который будет массивом, затем извлечь атрибуты из таблицы Attribute в базе данных в соответствии с таблицей Product Attribute и сохранить их в ProductAttributeArr.

Затем вы можете создать функцию, которая динамически генерирует параметры для базы GridView на основе содержимого ProductAttributeArr. Таким образом, это должно работать.

1

Другие решения

Отвечаю сам, так как обратной связи нет, и после еще нескольких копаний я нашел самое быстрое, но, возможно, не самое удачное решение.

Поскольку свойства в основной модели Product добавляются благодаря классу ProductDynamic, я добавил следующее в 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'];
}
}
0

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector