Symfony Entity query builder that checks for free spots

68 views Asked by At

First off all: I know the title isn't helping, but it's the best I can think of.
So I've got two entities in Symfony one is called Team and the other one Slot

the Slot entity has a name, a start and end date and all that stuff. Besides that he has an int field called amount where you can set the amount of teams that are able to participate in that slot/round. It also has a OneToMany Connection (bidirectional) to the Team entity.

The Team Entity stores the team name and all that stuff and has a ManyToOne Connection to the Slot entity (what a surprise ;))

However, I would like to have the possibility to asign a team to a timeslot by simply selecting it in a dropdown. So in the form I add something like this:

->add('slot', 'entity', array(
    'label'             => 'Zeitslot',
    'class'             => 'FooChallengeBundle:Slot',
    'property'          => 'output',
    'query_builder'     => function(\Foo\ChallengeBundle\Entity\SlotRepository $er) {
        return $er->createQueryBuilder('u')
                ->where('u.bookable = 1')
                ->andWhere('u.hide = 0');
    }
))

This work's like a charm! The only problem I have left, is to figure out if the slot is taken or not. Let's say for example, we've set the amount of the slot to 3. Let's assume further that there are already 3 teams assigned to that slot. In that case I don't want to show the option in the dropdown. So what do I have to do in the QueryBuilder to measure that? I've tried to add an having() which unfortunately didn't do the job.
Oh Bonus stuff:

  • if there are 4 team assigned to a slot with only let's say two places, it shouldn't accept any further (like when the full amount is reached). This could happen if someone changes the amount in the admin.
  • Of course the slot has to be still selectable, if your team (the team that is currently edited) is the last possible team. (like the amount would be 7, there are 7 teams assigned already, if your team is one of them, you still need to be able to select that entry).
1

There are 1 answers

1
Richard On BEST ANSWER

A having will work fine like so:

    $qb->select('s')
        ->from('FooChallengeBundle:Slot', 's')
        ->join('s.teams', 't')
        ->groupBy('s')
        ->having('count(t) < s.amount')
        ->getQuery()
        ->getResult();