信息
我在保存具有许多 MANY_MANY 关系的模型时遇到了一些问题。我有一个页面,您可以在其中添加产品属性以及产品属性级别。我现在要做的是在产品的更新页面上添加对此的支持。因此,当我进入更新页面时,我将看到所有产品属性,并且对于每个产品属性,都会有一个下拉列表,其中包含该特定产品属性的相关产品属性级别。
数据库
产品
- ID
- ETC
产品属性
- ID
- ETC
产品属性级别
- ID
- product_attribute_id ## FK
- ETC
ProductProductAttributeLevel -- 这是数据透视表
- product_id ## FK PK
- product_attribute_level_id ## FK PK
活动记录
产品:
class Product extends S360ActiveRecord {
public function behaviors() {
return array('CAdvancedArBehavior' => array(
'class' => 'application.extensions.CAdvancedArBehavior')
);
}
public function rules() {
return array(
array('attributeLevels', 'safe'),
);
}
public function relations() {
return array(
'attributeLevels' => array(self::MANY_MANY,
'ProductAttributeLevel',
'product_product_attribute_level(product_id,product_attribute_level_id)'
),
);
}
}
产品属性:
class ProductAttribute extends S360ActiveRecord {
public function relations() {
return array(
'levels' => array(self::HAS_MANY, 'ProductAttributeLevel', 'product_attribute_id'),
);
}
}
产品属性级别:
class ProductAttributeLevel extends S360ActiveRecord {
public function relations() {
return array(
'productAttribute' => array(self::BELONGS_TO, 'ProductAttribute', 'product_attribute_id'),
'products' => array(self::MANY_MANY, 'Product', 'product_product_attribute_level(product_attribute_level_id,product_id)'),
);
}
}
ProductProductAttributeLevel:
class ProductProductAttributeLevel extends S360ActiveRecord {
public function relations()
{
return array(
'productAttributeLevel' => array(self::BELONGS_TO, 'ProductAttributeLevel', 'product_attribute_level_id'),
'product' => array(self::BELONGS_TO, 'Product', 'product_id'),
);
}
}
我的 ProductController 更新产品的方法如下所示:
public function actionUpdate($id) {
$model = $this->loadModel($id);
$this->performAjaxValidation($model);
if (isset($_POST['Product'])) {
$model->attributes = $_POST['Product'];
if ($model->save()) {
$this->redirect(array('index'));
}
}
$this->render('update', array('model' => $model));
}
我的表单视图中的相关部分:
<?php
$form=$this->beginWidget('S360ActiveForm', array(
'id' => 'product-form',
'enableAjaxValidation' => true,
));
?>
<?php $attributes = ProductAttribute::model()->findAllByAttributes(array('survey_id' => $model->parent_id)); if ($attributes): ?>
<div class="span6">
<?php foreach ($attributes as $attribute) {
echo $form->dropDownListRow($model, 'attributeLevels',
CMap::mergeArray(
array('0' => Yii::t('backend','No attribute level')),
CHtml::listData($attribute->levels, 'id', 'label')
),
array('class' => 'span5')
);
}?>
</div>
<?php endif; ?>
问题
我得到这个 CDBException:
CDbCommand 未能执行 SQL 语句:SQLSTATE[23000]:完整性约束违规:1452 无法添加或更新子行:外键约束失败(
product_product_attribute_level
,CONSTRAINTproduct_product_attribute_level_ibfk_2
FOREIGN KEY (product_attribute_level_id
) REFERENCESproduct_attribute_level
(id
) ON DELE)。执行的 SQL 语句是: insert into product_product_attribute_level (product_id, product_attribute_level_id) values ('5', '0')
问题是,虽然 ID 为“0”的 product_attribute_level 不存在,但 ID 从“1”开始。我将如何更改它以使其插入正确的 ID 号?
我想要的例子
假设我有 2 个产品属性;属性 1 和属性 2。Attribute1 具有产品属性级别 Attribute1_Level1 和 Attribute1_Level2。Attribute2 具有产品属性级别 Attribute2_Level1、Attribute2_Level2 和 Attribute2_Level3。
当我进入我的产品编辑/更新页面时,我想看到这个: 属性 http://img201.imageshack.us/img201/9252/screenshot20130207at103.png Attribute2 Dropdown http://img405.imageshack.us/img405 /9252/screenshot20130207at103.png
产品属于调查。产品属性也属于调查,因此获取产品可以拥有的所有产品属性很容易:
$attributes = ProductAttribute::model()->findAllByAttributes(array('survey_id' => $product->survey_id));
在此之后,我需要获取属于每个属性的所有产品属性级别,这也很容易:
foreach ($attributes as $attribute) {
echo $form->dropDownList($attribute, 'label',
CHtml::listData($attribute->levels, 'id', 'label'),
$htmlOptions
);
}
问题是如何将它与产品连接起来,并根据我从不同下拉列表中选择的内容相应地更新其“$product->attributeLevels”关系。$product->attributeLevels 应该是 ProductAttributeLevel 的列表,并且应该通过表“product_product_attribute_level”存储。