Doctrine Entities and traits. Right way

doctrine, doctrine-orm, php, symfony, traits

Solution

I fixed the problem using

trait Commentable
{
    /**
     * List of comments
     *
     * @var Comment[]|ArrayCollection
     *
     * @ORM\ManyToMany(targetEntity="XXXX\Entity\Comment")
     * @ORM\OrderBy({"createdAt" = "DESC"})
     */
    protected $comments;

    /**
     * Constructor
     */
    public function __construct()
    {
        $this->comments = new ArrayCollection();
    }

    /**
     * Get Comments
     *
     * @return Comment[]|ArrayCollection
     */
    public function getComments()
    {
        return $this->comments;
    }

    /**
     * Add comment to the entity
     *
     * @param Comment $comment
     */
    public function addComment(Comment $comment)
    {
        $this->comments->add($comment);
    }
}

Problem

I have a Comment entity (for user comments) and I want to add a new feature (Commentable) in my old entities. I created a trait Commentable: ``` trait Commentable { /** * List of comments * * @var Comment[]|ArrayCollection * * @ORM\OneToMany(targetEntity="Comment") */ protected $comments; /** * Constructor */ public function __construct() { $this->comments = new ArrayCollection(); } /** * Get Comments * * @return Comment[]|ArrayCollection */ public function getComments() { return $this->comments; } /** * Add comment to the entity * * @param Comment $comment */ public function addComment(Comment $comment) { $this->comments->add($comment); } } ``` and in the old entities I do something like this: ``` class Image { use Commentable { Commentable::__construct as private __commentableConstruct; } /** some stuff **/ } ``` The Comment class looks like: ``` class Comment { /** * Identifier * * @var int * * @ORM\Id * @ORM\Column(type="integer") * @ORM\GeneratedValue(strategy="IDENTITY") */ protected $id; /** * Comment owner * * @var User * * @ORM\ManyToOne(targetEntity="User", inversedBy="comments") * @ORM\JoinColumn(name="user_id", referencedColumnName="id") */ protected $user; /** * Comment content * * @var string * * @ORM\Column(type="text") */ protected $content; /** * @var Image * * @ORM\ManyToOne(targetEntity="Image", inversedBy="comments") */ protected $image; /** all the classes using Commentable **/ /** some stuff */ } ``` I think the idea is not bad. I can create new behaviours and easily add it to entities. But I don't like the idea on the Comment entity. Adding all the classes using the commentable trait is not 'usefull'. I'm receiving this error... but I don't know how I can fix that with traits: ``` OneToMany mapping on field 'comments' requires the 'mappedBy' attribute. ```

Original source