Короче говоря, само приложение действительно простое, имеет только три таблицы.
Товар:
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 другим способом, чтобы они не повторялись. Увидеть ниже.
Хорошо, я думаю, у меня есть твоя идея …
Итак, я думаю, что вы можете сгенерировать атрибут в модели Product (мы назовем его ProductAttributeArr), который будет массивом, затем извлечь атрибуты из таблицы Attribute в базе данных в соответствии с таблицей Product Attribute и сохранить их в ProductAttributeArr.
Затем вы можете создать функцию, которая динамически генерирует параметры для базы GridView на основе содержимого ProductAttributeArr. Таким образом, это должно работать.
Отвечаю сам, так как обратной связи нет, и после еще нескольких копаний я нашел самое быстрое, но, возможно, не самое удачное решение.
Поскольку свойства в основной модели 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'];
}
}