情報
多くの MANY_MANY リレーションシップを持つモデルを保存する際に問題が発生しています。製品属性と製品属性レベルを追加できるページがあります。私が今やりたいことは、製品の更新ページにこれのサポートを追加することです。したがって、更新ページに入ると、すべての製品属性が表示され、各製品属性について、その特定の製品属性に関連する製品属性レベルのドロップダウン リストが表示されます。
データベース
製品
- ID
- 等
製品属性
- ID
- 等
製品属性レベル
- ID
- product_attribute_id ## FK
- 等
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) 値 ('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 /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」を介して保存する必要があります。