Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Conditional Relationship in Symfony2

Let's say I have a Post entity, and a Comment entity. A comment can be approved or not by an admin (which is a flag in the db). The post entity has:

/**
 * @ORM\OneToMany(targetEntity="Comment", mappedBy="post")
 */
protected $comments;

And I also want a second attribute which will look like:

/**
 * @ORM\OneToMany(targetEntity="Comment", mappedBy="post")
 */
protected $approvedComments;

How is it possible to load only the approved comments here?

like image 544
Thanasis Pap Avatar asked Dec 02 '14 14:12

Thanasis Pap


3 Answers

Idea #1

You could use Inheritance mapping: https://www.doctrine-project.org/projects/doctrine-orm/en/latest/reference/inheritance-mapping.html

The idea would to have separate classes for each type (approved and non-approved), but to store everything in a single table (SINGLE_TABLE inheritance).

You will need to have additional column which will store class type discriminator.

Then, you would have:

/**
 * @ORM\OneToMany(targetEntity="ApprovedComment", mappedBy="post")
 */
protected $approvedComments;

/**
 * @ORM\OneToMany(targetEntity="NonApprovedComment", mappedBy="post")
 */
protected $nonApprovedComments;

The obvious downside is creation of additional classes.

Idea #2

You could just tweak you Query/QueryBuilder like:

`SELECT p, c FROM AcmeDemoBundle:Post p LEFT JOIN p.comments c WITH c.approved = FALSE`

This idea seems more reasonable.

like image 196
Jovan Perovic Avatar answered Oct 13 '22 23:10

Jovan Perovic


This can not be achieved through relationships as you describe it. 2 tables can not be related "conditionally" as the relations are based on primary keys.

You have at least solutions here

  1. Leave the "comments" field on the entity with the annotations, remove the annotations from the approved comments field as it is the same as comments as understood by the ORM. You would then have the ->getComments() function to get all comments and you could add a function "getApprovedCommentsForPost($post)" in your repostitory class to retrieve those approved ones.
  2. You could distinguish between comments with single inheritance, so you would have a Comment class and an ApprovedComment class in one table for example, then you could make 2 relations on your entity (read here doctrine-orm.readthedocs.org/en/latest/reference/inheritance-mapping.html#single-table-inheritance)
  3. You could use doctrine filters to filter out unapproved comments by default when retrieving data from Comments repository
like image 35
Bartłomiej Wach Avatar answered Oct 14 '22 00:10

Bartłomiej Wach


You cannot define that contraint in your entity. Here is the related documentation:

http://doctrine-orm.readthedocs.org/en/latest/reference/annotations-reference.html#annref-onetomany

As you can see there is no option which is related to conditions. You have to define this condition using QueryBuilder.

like image 26
András Avatar answered Oct 13 '22 23:10

András