When defining a relationship, there is a property on the related model (not a DB column), but I would like to sort by it (in the @OrderBy
annotation).
I have a base model that is extended using single table inheritance. The property in question is basically an order
property that is specified in each child class, but is not saved to the DB.
(I don't want to add an order
column to the DB table, since the ordering depends purely on which child class the discriminator is mapped to. There is already a unique constraint so that each child class can be used no more than once in the relationship.)
Here's a really simplified version of my code...
Base entity:
/**
* @ORM\Entity
* @ORM\Table(name="base")
* @ORM\InheritanceType("SINGLE_TABLE")
* @ORM\DiscriminatorColumn(name="class_name", type="string")
*
* @ORM\DiscriminatorMap({
* "Base" = "Models\Base",
* "ChildA" = "Models\ChildB",
* "ChildB" = "Models\ChildA"
* })
**/
class Base
{
/** @ORM\Column(type="string") **/
protected $class_name;
/**
* @ORM\ManyToOne(targetEntity="Related", inversedBy="collection")
**/
protected $related;
// this is just a plain ol' property (not in the DB)
protected $order;
public function getClassName()
{
return $this->class_name;
}
}
Children:
/**
* @ORM\Entity
* @ORM\Table(name="child_a")
**/
class ChildA extends Base
{
$order = 1;
}
/**
* @ORM\Entity
* @ORM\Table(name="child_b")
**/
class ChildB extends Base
{
$order = 2;
}
Related entity:
/**
* @ORM\Entity
* @ORM\Table(name="related")
**/
class Related
{
/**
* @ORM\OneToMany(targetEntity="Base", mappedBy="related")
* @ORM\OrderBy({"order"="ASC"})
**/
protected $collection;
public function getCollection()
{
$em = App::make('Doctrine\ORM\EntityManagerInterface');
// map each Base instance to the appropriate child class
return $this->collection->map(function ($base) use ($em) {
$class_name = $base->getClassName();
return $em->find($class_name, $base->getId());
});
}
}
Is it possible to use the order
property for ordering the collection
relationship? (Ordering based on class_name
using a switch
-like construct would also be valid, but I haven't found any way to do that either, and it would be harder to maintain.)
Thanks in advance!
The directive beginning with ORM is very much telling Doctrine you're doing referencing a property that has a relationship with a table field. You can't use ORM directives on fields that don't exist. Doctrine annotations: OrderBy
You would have to implement this in a function, best in the model itself (within your getCollection() function), or if you're using a framework like Symfony place it in a function of the repository class for this entity. You'd have to use PHP sorting functions to do this. SQL/DQL won't work either because the property isn't related to a field in the table.