私はあなたと同じ問題を抱えていましたが、私はそれを理解しました。
まず、多対多の関係ではなく、1 対多/多対 1 の関係 (中間エンティティを使用) を選択することをお勧めします。なんで?これにより、列などの追加の列が可能になるためposition
です。このようにして、画像を好きなように並べ替えることができます。多対多の関係では、リンク テーブルには 2 つの列しかありません。関連付けられたテーブルの ID です。
Doctrineのドキュメントから:
(...) 追加の属性をアソシエーションに関連付けたい場合がよくあります。その場合、アソシエーション クラスを導入します。その結果、直接的な多対多の関連付けはなくなり、3 つの参加クラス間の 1 対多/多対 1 の関連付けに置き換えられます。
そこで、これを製品マッピング ファイルに追加しました: (ご覧のとおり、構成ファイル形式として YAML を使用しています)
oneToMany:
images:
targetEntity: MyBundle\Entity\ProductImage
mappedBy: product
orderBy:
position: ASC
そして、新しい ProductImage マッピング ファイルを作成しました。
MyBundle\Entity\ProductImage:
type: entity
table: product_images
id:
id:
type: integer
generator: { strategy: AUTO }
fields:
position:
type: integer
manyToOne:
product:
targetEntity: MyBundle\Entity\Product
inversedBy: images
image:
targetEntity: Application\Sonata\MediaBundle\Entity\Media
コマンド ライン ( php app/console doctrine:generate:entities MyBundle
) を使用して、対応するエンティティ (Product
およびProductImage
) を作成/更新しました。
次に、管理クラスを作成/更新しました。ProductAdmin.php:
class ProductAdmin extends Admin
{
protected function configureFormFields(FormMapper $formMapper)
{
$formMapper
// define other form fields
->add('images', 'sonata_type_collection', array(
'required' => false
), array(
'edit' => 'inline',
'inline' => 'table',
'sortable' => 'position',
))
;
}
ProductImageAdmin.php:
class ProductImageAdmin extends Admin
{
protected function configureFormFields(FormMapper $formMapper)
{
$formMapper
->add('image', 'sonata_type_model_list', array(
'required' => false
), array(
'link_parameters' => array(
'context' => 'product_image'
)
))
->add('position', 'hidden')
;
}
両方をサービスとして追加することを忘れないでください。ProductImage フォームへのリンクをダッシュボードに表示したくない場合は、show_in_dashboard: false
タグを追加します。(これを行う方法は、使用する構成形式 (yaml/xml/php) によって異なります)
この後、管理フォームは正しく機能しましたが、製品を保存しようとするとまだ問題がありました。すべての問題を解決するには、次の手順を実行する必要がありました。
まず、Product エンティティのカスケード永続操作を構成する必要がありました。繰り返しますが、これを行う方法は構成形式によって異なります。私は yaml を使用しているので、images
1 対多の関係でカスケード プロパティを追加しました。
oneToMany:
images:
targetEntity: MyBundle\Entity\ProductImage
mappedBy: product
orderBy:
position: ASC
cascade: ["persist"]
それでうまくいきました(またはそう思った)がproduct_id
、データベースの が に設定されていることに気付きましたNULL
。クラスにprePersist()
andpreUpdate()
メソッドを追加することでこれを解決しました。ProductAdmin
public function prePersist($object)
{
foreach ($object->getImages() as $image) {
$image->setProduct($object);
}
}
public function preUpdate($object)
{
foreach ($object->getImages() as $image) {
$image->setProduct($object);
}
}
...そして、エンティティのaddImages()
メソッドに1行追加しました:Product
public function addImage(\MyBundle\Entity\ProductImage $images)
{
$images->setProduct($this);
$this->images[] = $images;
return $this;
}
これは私にとってはうまくいきました。今では、製品への/からの画像の追加、変更、並べ替え、削除などを行うことができます。