Skip to content

Commit e501c35

Browse files
author
abluchet
committed
Fix embeddable entities eager loading with groups
1 parent 6166a56 commit e501c35

File tree

5 files changed

+40
-10
lines changed

5 files changed

+40
-10
lines changed

features/main/operation.feature

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,24 @@ Feature: Operation support
1212
"""
1313
"This is a custom action for 42."
1414
"""
15+
16+
@createSchema
17+
@dropSchema
18+
Scenario: Select a resource and it's embedded data
19+
Given there are 1 embedded dummy objects
20+
When I send a "GET" request to "/embedded_dummies_groups/1"
21+
Then the response status code should be 200
22+
And the response should be in JSON
23+
And the header "Content-Type" should be equal to "application/ld+json; charset=utf-8"
24+
And the JSON should be equal to:
25+
"""
26+
{
27+
"@context": "/contexts/EmbeddedDummy",
28+
"@id": "/embedded_dummies/1",
29+
"@type": "EmbeddedDummy",
30+
"name": "Dummy #1",
31+
"embeddedDummy": {
32+
"dummyName": "Dummy #1"
33+
}
34+
}
35+
"""

src/Bridge/Doctrine/Orm/Extension/EagerLoadingExtension.php

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -242,15 +242,17 @@ private function addSelect(QueryBuilder $queryBuilder, string $entity, string $a
242242
continue;
243243
}
244244

245-
//the field test allows to add methods to a Resource which do not reflect real database fields
246-
if ($targetClassMetadata->hasField($property) && (true === $propertyMetadata->getAttribute('fetchable') || $propertyMetadata->isReadable())) {
247-
$select[] = $property;
248-
}
249-
245+
// If it's an embedded property see below
250246
if (!array_key_exists($property, $targetClassMetadata->embeddedClasses)) {
247+
//the field test allows to add methods to a Resource which do not reflect real database fields
248+
if ($targetClassMetadata->hasField($property) && (true === $propertyMetadata->getAttribute('fetchable') || $propertyMetadata->isReadable())) {
249+
$select[] = $property;
250+
}
251+
251252
continue;
252253
}
253254

255+
// It's an embedded property, select relevent subfields
254256
foreach ($this->propertyNameCollectionFactory->create($targetClassMetadata->embeddedClasses[$property]['class']) as $embeddedProperty) {
255257
$propertyMetadata = $this->propertyMetadataFactory->create($entity, $property, $propertyMetadataOptions);
256258
$propertyName = "$property.$embeddedProperty";

tests/Bridge/Doctrine/Orm/Extension/EagerLoadingExtensionTest.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -97,8 +97,8 @@ public function testApplyToCollection()
9797
$relatedClassMetadataProphecy = $this->prophesize(ClassMetadata::class);
9898

9999
foreach ($relatedNameCollection as $property) {
100-
if ('id' !== $property) {
101-
$relatedClassMetadataProphecy->hasField($property)->willReturn(!\in_array($property, ['notindatabase', 'embeddedDummy'], true))->shouldBeCalled();
100+
if ('id' !== $property && 'embeddedDummy' !== $property) {
101+
$relatedClassMetadataProphecy->hasField($property)->willReturn(!\in_array($property, ['notindatabase'], true))->shouldBeCalled();
102102
}
103103
}
104104
$relatedClassMetadataProphecy->hasField('embeddedDummy.name')->willReturn(true)->shouldBeCalled();
@@ -183,8 +183,8 @@ public function testApplyToItem()
183183
$relatedClassMetadataProphecy = $this->prophesize(ClassMetadata::class);
184184

185185
foreach ($relatedNameCollection as $property) {
186-
if ('id' !== $property) {
187-
$relatedClassMetadataProphecy->hasField($property)->willReturn(!\in_array($property, ['notindatabase', 'embeddedDummy'], true))->shouldBeCalled();
186+
if ('id' !== $property && 'embeddedDummy' !== $property) {
187+
$relatedClassMetadataProphecy->hasField($property)->willReturn(!\in_array($property, ['notindatabase'], true))->shouldBeCalled();
188188
}
189189
}
190190
$relatedClassMetadataProphecy->hasField('embeddedDummy.name')->willReturn(true)->shouldBeCalled();

tests/Fixtures/TestBundle/Entity/EmbeddableDummy.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ class EmbeddableDummy
3030
* @var string The dummy name
3131
*
3232
* @ORM\Column(nullable=true)
33+
* @Groups({"embed"})
3334
*/
3435
private $dummyName;
3536

tests/Fixtures/TestBundle/Entity/EmbeddedDummy.php

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,18 @@
1515

1616
use ApiPlatform\Core\Annotation\ApiResource;
1717
use Doctrine\ORM\Mapping as ORM;
18+
use Symfony\Component\Serializer\Annotation\Groups;
1819
use Symfony\Component\Validator\Constraints as Assert;
1920

2021
/**
2122
* Embedded Dummy.
2223
*
2324
* @author Jordan Samouh <[email protected]>
2425
*
25-
* @ApiResource(attributes={"filters"={"my_dummy.search", "my_dummy.order", "my_dummy.date", "my_dummy.range", "my_dummy.boolean", "my_dummy.numeric"}})
26+
* @ApiResource(
27+
* attributes={"filters"={"my_dummy.search", "my_dummy.order", "my_dummy.date", "my_dummy.range", "my_dummy.boolean", "my_dummy.numeric"}},
28+
* itemOperations={"get", "put", "delete", "groups"={"method"="GET", "path"="/embedded_dummies_groups/{id}", "normalization_context"={"groups"={"embed"}}}}
29+
* )
2630
* @ORM\Entity
2731
*/
2832
class EmbeddedDummy
@@ -40,6 +44,7 @@ class EmbeddedDummy
4044
* @var string The dummy name
4145
*
4246
* @ORM\Column(nullable=true)
47+
* @Groups({"embed"})
4348
*/
4449
private $name;
4550

@@ -55,6 +60,7 @@ class EmbeddedDummy
5560
* @var EmbeddableDummy
5661
*
5762
* @ORM\Embedded(class="EmbeddableDummy")
63+
* @Groups({"embed"})
5864
*/
5965
public $embeddedDummy;
6066

0 commit comments

Comments
 (0)