Статейка деревянная в том смысле, что она всего лишь является самым простым примером для создания EAV. Но мне не хватило ее функционала и я пошел дальше=)) А так статья отличная и автором я восхищаюсь=)
Смотрите мою логику (возможно она не правильная):
1) Открываю страницу и вывожу на нее атрибуты присвоенные товару
2) Так как атрибутов у меня "пачка" я вывожу каждый из них в цикле
3) У модели атрибута есть свойство ИМЯ и связь по которой я получаю значение атрибута
Теперь как это реализовано в коде:
1) Вывожу атрибуты товара. Связь многие ко многим.
Model Product.php
Код: Выделить всё
public function relations()
{
return array(
'productAttributes' => array(self::MANY_MANY, 'Attribute', '{{products_and_attributes}}(product_id, attribute_id)'),
);
}
ProductController.php
Код: Выделить всё
$model = $this->loadModel($this->_model, $id);
$this->render('attributes', array(
'model' => $model,
'attributes' => $model->productAttributes,
));
2) Вывожу атрибуты
Код: Выделить всё
foreach ($attributes as $attr){
echo $attr->name;
}
3) Пытаюсь получить значения атрибутов. У каждого атрибута для данного товара только ОНО значение, значит я получу только ОДНУ запись из БД, а значит HAS_ONE с указанием к какому товару этот атрибут. Верно?
Model Attribute.php
Код: Выделить всё
public function relations()
{
return array(
'attrValue' => array(self::HAS_ONE, 'AttributesValue', 'attribute_id', 'condition'=>'product_id=:prod_id', 'params'=>array(':prod_id' => 3)),
);
}
Model AttributesValue.php
Код: Выделить всё
<?php
/**
* This is the model class for table "{{attributes_value}}".
*
* The followings are the available columns in table '{{attributes_value}}':
* @property string $id
* @property string $product_id
* @property string $attribute_id
* @property string $value
*
* The followings are the available model relations:
* @property Products $product
* @property Attributes $attribute
*/
class AttributesValue extends CActiveRecord
{
/**
* @return string the associated database table name
*/
public function tableName()
{
return '{{attributes_value}}';
}
/**
* @return array validation rules for model attributes.
*/
public function rules()
{
// NOTE: you should only define rules for those attributes that
// will receive user inputs.
return array(
array('product_id, attribute_id, value', 'required'),
array('product_id, attribute_id', 'length', 'max'=>11),
// The following rule is used by search().
// @todo Please remove those attributes that should not be searched.
array('id, product_id, attribute_id, value', 'safe', 'on'=>'search'),
);
}
/**
* @return array relational rules.
*/
public function relations()
{
// NOTE: you may need to adjust the relation name and the related
// class name for the relations automatically generated below.
//return array(
// 'product' => array(self::BELONGS_TO, 'Products', 'product_id'),
// 'attribute' => array(self::HAS_ONE, 'Attributes', 'attribute_id'),
//);
}
/**
* @return array customized attribute labels (name=>label)
*/
public function attributeLabels()
{
return array(
'product_id' => 'Product',
'attribute_id' => 'Attribute',
'value' => 'Value',
);
}
/**
* Retrieves a list of models based on the current search/filter conditions.
*
* Typical usecase:
* - Initialize the model fields with values from filter form.
* - Execute this method to get CActiveDataProvider instance which will filter
* models according to data in model fields.
* - Pass data provider to CGridView, CListView or any similar widget.
*
* @return CActiveDataProvider the data provider that can return the models
* based on the search/filter conditions.
*/
public function search()
{
// @todo Please modify the following code to remove attributes that should not be searched.
$criteria=new CDbCriteria;
$criteria->compare('product_id',$this->product_id,true);
$criteria->compare('attribute_id',$this->attribute_id,true);
$criteria->compare('value',$this->value,true);
return new CActiveDataProvider($this, array(
'criteria'=>$criteria,
));
}
/**
* Returns the static model of the specified AR class.
* Please note that you should have this exact method in all your CActiveRecord descendants!
* @param string $className active record class name.
* @return AttributesValue the static model class
*/
public static function model($className=__CLASS__)
{
return parent::model($className);
}
}
И обращаюсь я к этому всему вот так.
Код: Выделить всё
foreach ($attributes as $attr){
echo $attr->name;
echo $attr->attrValue->value;
}
То есть получаю модели атрибутов для товара, а потом из моделей атрибутов я хочу получать по связи attrValue значение этого атрибута для данного товара. Но мне пишет ошибку которая заскринена в первом посту=(
Из нее я могу понять только то, что связи нет или она не является объектом... как-то так.