Login to bookmark this video
Buy Access to Course
07.

Order By with a OneToMany

Share this awesome video!

|

Keep on Learning!

Let's finish this! Ultimately, we need to create the same $notes structure, but with the real data. Above the foreach add a new $notes variable. Inside, add a new entry to that and start populating it with id => $note->getId():

// ... lines 1 - 12
class GenusController extends Controller
{
// ... lines 15 - 94
public function getNotesAction(Genus $genus)
{
$notes = [];
foreach ($genus->getNotes() as $note) {
$notes[] = [
'id' => $note->getId(),
];
}
// ... lines 104 - 114
}
}

Hey! Where's my autocompletion on that method!? Check out the getNotes() method in Genus. Ah, there's no @return - so PhpStorm has no idea what that returns. Sorry PhpStorm - my bad. Add some PhpDoc with @return ArrayCollection|GenusNote[]:

114 lines | src/AppBundle/Entity/Genus.php
// ... lines 1 - 11
class Genus
{
// ... lines 14 - 105
/**
* @return ArrayCollection|GenusNote[]
*/
public function getNotes()
{
return $this->notes;
}
}

This will autocomplete any methods from ArrayCollection and auto-complete from GenusNote if we loop over these results.

Now we get autocompletion for getId(). Next, add username => $note->getUsername() and I'll paste in the other fields: avatarUri, note and createdAt. Ok, delete that hardcoded stuff!

// ... lines 1 - 12
class GenusController extends Controller
{
// ... lines 15 - 94
public function getNotesAction(Genus $genus)
{
$notes = [];
foreach ($genus->getNotes() as $note) {
$notes[] = [
'id' => $note->getId(),
'username' => $note->getUsername(),
'avatarUri' => '/images/'.$note->getUserAvatarFilename(),
'note' => $note->getNote(),
'date' => $note->getCreatedAt()->format('M d, Y')
];
}
$data = [
'notes' => $notes
];
return new JsonResponse($data);
}
}

Deep breath: moment of truth. Refresh! Ha! There are the 15 beautiful, random notes, courtesy of the AJAX request, Alice and Faker.

Ordering the OneToMany

But wait - the order of the notes is weird: these should really be ordered from newest to oldest. That's the downside of using the $genus->getNotes() shortcut: you can't customize the query - it just happens magically in the background.

Well ok, I'm lying a little bit: you can control the order. Open up Genus and find the $notes property. Add another annotation: @ORM\OrderBy with {"createdAt"="DESC"}:

115 lines | src/AppBundle/Entity/Genus.php
// ... lines 1 - 11
class Genus
{
// ... lines 14 - 45
/**
* @ORM\OneToMany(targetEntity="GenusNote", mappedBy="genus")
* @ORM\OrderBy({"createdAt" = "DESC"})
*/
private $notes;
// ... lines 51 - 113
}

I know, the curly-braces and quotes look a little crazy here: just Google this if you can't remember the syntax. I do!

Ok, refresh! Hey! Newest ones on top, oldest ones on the bottom. So we do have some control. But if you need to go further - like only returning the GenusNotes that are less than 30 days old - you'll need to do a little bit more work.