FileUpload と Image という 2 つの Propel ベース (Propel 1.6) モデル クラスがあります。
<table name="file_upload">
<column name="id" type="integer" required="true" primaryKey="true" autoIncrement="true" />
<column name="name" type="varchar" size="500" required="false" />
<column name="mime_type" type="varchar" size="100" required="true" />
<column name="data" type="blob" required="false" lazyLoad="true" />
</table>
<table name="image">
<column name="id" type="integer" required="true" primaryKey="true" autoIncrement="true" />
<column name="file_upload_id" type="integer" required="true" />
<foreign-key foreignTable="file_upload" onDelete="restrict">
<reference local="file_upload_id" foreign="id" />
</foreign-key>
</table>
新しいイメージ $image、新しい FileUpload $upload をインスタンス化するとき、$upload を $image の下に登録してから、$image (2 番目) と $upload (1 番目) の両方のカスケード保存を期待して $image を保存してみてください ...
$image = new Image();
$upload = new FileUpload();
// [set required properties in both models]
$image->setFileUpload( $image );
$image->save();
次の外部キー違反エラーが発生します。
UPDATE ステートメントを実行できません [UPDATE
image
SETFILE_UPLOAD_ID
=:p1,UPDATED_AT
=:p2 WHERE image.ID=:p3] [ラップ: SQLSTATE[23000]: 整合性制約違反: 1452 子行を追加または更新できません: 外部キー制約が失敗します (DATABASENAME
.image
, 制約image_FK_1
外部キー (file_upload_id
) 参照file_upload
(id
))]
$upload->save() が BaseFileUpload->doSave() を呼び出すため、このエラーが発生することがわかりました。これにより、特に $image->save() が再トリガーされます。
if ($this->collImages !== null) {
foreach ($this->collImages as $referrerFK) {
if (!$referrerFK->isDeleted()) {
$affectedRows += $referrerFK->save($con);
}
}
}
...つまり、FileUpload は、それ自体が参照されるだけで、他のオブジェクトを参照していない場合でも、他のオブジェクトからの逆参照をミラーリングします。
Image->save() をオーバーライドして、リンクされた FileUpload のすべてのミラーリングされた参照を最初にクリアしてから、parent::save() を呼び出すと、問題は解決します。
public function save( PropelPDO $con = null )
{
$upload = $this->getFileUpload();
if ( null !== $upload && $upload->isModified() ) {
$upload->clearAllReferences();
$upload->save( $con );
$this->setFileUpload( $upload );
}
return parent::save( $con );
}
このアプローチは機能しますが、ハッキリと感じます。$upload オブジェクトが保存されると、外部参照を簡単に復元できるため、ここでのみ使用することもできます。それ以外の場合は、それほど単純ではない可能性があります。
$upload->save() からの $image->save() の保存の再トリガーを防止するクリーンな方法はありますか? Propel のデフォルトの動作にあまり干渉することはありませんか? ありがとう。