Mauro
Mauro

Reputation: 1487

Doctrine Entities and traits. Right way

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.

Upvotes: 3

Views: 6851

Answers (2)

Mauro
Mauro

Reputation: 1487

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);
    }
}

Upvotes: 3

Yoann Chambonnet
Yoann Chambonnet

Reputation: 1333

It's not a trait matter, it's a mapping / doctrine related problem.

Your annotation "@OneToMany" misses a configuration according to the documentation

I guess that in your Image class, you should overwrite the property that you use for mapping.

Upvotes: 0

Related Questions