botjaeger
botjaeger

Reputation: 95

Implementing custom OrderBy for ManyToOne relation

Unfortunately, the OrderBy attribute is not supported for ManyToOne relations. Is there a way to implement a custom one? Similar to the Attributes approach?

I already tried SQLFilter but as it turns out, it will not work for ORDER BY sentence.

I'm using API-platform too.

EDIT: Implementing OrderBy on Companies.applications

#[ORM\OrderBy(['candidate.firstName' => 'DESC'])]
#[Groups(['opening:read'])]
#[ORM\OneToMany(mappedBy: 'job', targetEntity: Application::class)]
private Collection $applications;

Applications entity has this property

#[ORM\ManyToOne(inversedBy: 'applications')]
#[ORM\JoinColumn(nullable: false)]
private ?User $candidate = null;

returns an error Warning: Undefined array key \"candidate.firstName\" and based on this doctrine docs

The referenced field names have to exist on the targetEntity class of the #[ManyToMany] or #[OneToMany] attribute.

Upvotes: 0

Views: 50

Answers (1)

Brent
Brent

Reputation: 153

The doctrine docs is quite clear, as you noted yourself, that this cannot be done. Maybe with some fancy AST Walkers, but I wouldn't recommend that.

The DQL Snippet in OrderBy is only allowed to consist of unqualified, unquoted field names and of an optional ASC/DESC positional statement. Multiple Fields are separated by a comma (,). The referenced field names have to exist on the targetEntity class of the #[ManyToMany] or #[OneToMany] attribute.

You could denormalize your Application entity a little bit and add a $firstName property on that specific entity, that copies that value from the User entity when creating/updating the entity.

You could then rewrite your Company entity to:

#[ORM\OrderBy(['firstName' => 'DESC'])]
#[Groups(['opening:read'])]
#[ORM\OneToMany(mappedBy: 'job', targetEntity: Application::class)]
private Collection $applications;

But having that denormalization step is really a preference and might also not be a preferable method for some.

Upvotes: 1

Related Questions