wandam
wandam

Reputation: 162

Create an entity that will be used by many other entities (Doctrine 2)

enter image description here How can I do this?

My Entities:

Product entity

/**
 * @ORM\Entity
 * @ORM\Table(name="products")
 */
class Product
{

    /**
     * @ORM\Id()
     * @ORM\Column(name="id", type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     * @var int
     */
    private $id;

    /**
     * @ORM\Column(type="string", length=512)
     * @var string
     */
    private $name;

    /**
     * (??)
     * @var ArrayCollection
     */
    private $images;
}

Article entity

/**
 * @ORM\Entity
 * @ORM\Table(name="articles")
 */
class Article
{

    /**
     * @ORM\Id()
     * @ORM\Column(name="id", type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     * @var int
     */
    private $id;

    /**
     * @ORM\Column(type="string", length=512)
     * @var string
     */
    private $title;

    /**
     * (??)
     * @var ArrayCollection
     */
    private $images;
}

Image entity

/**
 * @ORM\Entity
 * @ORM\Table(name="images")
 */
class Image
{

    /**
     * @ORM\Id()
     * @ORM\Column(name="id", type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     * @var int
     */
    private $id;

    /**
     * @ORM\Column(type="string", length=512)
     * @var string
     */
    private $name;

    /**
     * @ORM\Column(type="string", length=1024)
     * @var string
     */
    private $path;
}

I don't know how to create a link tables with additional fields like the picture. Which association should I use? How to manage these relations in entities?

Upvotes: 3

Views: 105

Answers (1)

Francesco Panina
Francesco Panina

Reputation: 343

Usually when you need a many to many approach Doctrine let you define such behaviour with a simple annotation.

@ORM\ManyToMany(targetEntity="full_qualified_namespace")
@ORM\JoinTable(
      name="game_schemas_players",
      joinColumns={@ORM\JoinColumn(name="this_field_name", referencedColumnName="id")},
      inverseJoinColumns={@ORM\JoinColumn(name="that_field_anem", referencedColumnName="id")}
  )

This will instruct Doctrine to create a relation the current entity and the target entity.

But that's not your case. For what I can see from your model you need to add some field on the 'middle' entity.

Here what you may want to do:

class Product
{
    [...]

     /**
     * @var ArrayCollection | ProductImage[]
     *
     * @ORM\OneToMany(targetEntity="ProductImage", mappedBy="product")
     */
    private $productImages;
}

class Image
{
    [...]

     /**
     * @var ArrayCollection | ProductImage[]
     *
     * @ORM\OneToMany(targetEntity="ProductImage", mappedBy="image")
     */
    private $productImages;
}

as you can see as defined here either Product and Image have a oneToMany relation with a middle entity which will be named ProductImage**. The last step will be to implement such entity:

class ProductImage
{
    [...]

     /**
     * @var Image
     *
     * @ORM\ManyToOne(targetEntity="Image", mappedBy="image")
     * @ORM\JoinColumn(name="image_id", referencedColumnName="id")
     */
    private $image;

     /**
     * @var Product
     *
     * @ORM\ManyToOne(targetEntity="Product", mappedBy="product")
     * @ORM\JoinColumn(name="product_id", referencedColumnName="id")
     */
    private $product;

     /**
     * @ORM\Column(type="string", length=1024)
     * @var string
     */
    private $position;

}

The owning side of the relation both for Product and Image is still ProductImage.


As a side note in your entity is common practice to implement an add method in this fashion:

public function __contructor(){
    $this->productImages = new ArrayCollection();
}

/**
 * Add ProductImage
 *
 * @param ProductImage $productImage
 * @return $this
 */
public function addDocument(ProductImage $productImage)
{
    $productImage->addProductImage($productImage);

    $this->documents->add($document);

    return $this;
}

and then you can use such method with the following approach:

$product = new Product();

$image = new Image();

$productImage = new ProductImage($product,$image);

$product->addProductImage($productImage);

Don't forget to provide the usual setter method as Doctrine need them to initialize the entity.

Hope it helps, Regards.

Upvotes: 1

Related Questions