我在使用组序列化具有许多关系的实体时遇到问题。 以这种方式序列化相关实体时遇到问题。
假设我有两个实体:产品和相关元素。
/**
*
* @Serializer\ExclusionPolicy("none")
*/
class Product {
/**
* Primary key
* @var integer $id
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*
* @Serializer\Groups({"list","details"})
* @Serializer\Type("integer")
*/
protected $id;
/**
* @Serializer\Groups({"list","details"})
* @Serializer\Type("string")
*/
protected $name;
/**
* @ORM\Column(name="description", type="string", length=4096, nullable=true)
*
* @Serializer\Groups({"details"})
* @Serializer\Type("string")
*/
protected $description;
/**
* @var ArrayCollection
*
* @ORM\OneToMany(targetEntity="Madden\ProjectBundle\Entity\ProjectResource", mappedBy="project")
* @Serializer\Groups({"details"})
* @Serializer\Type("ArrayCollection<Element>")
*/
protected $details1;
/**
* Relation to project tasks
* @ORM\OneToMany(targetEntity="Madden\ProjectBundle\Entity\ProjectTask", mappedBy="project")
* @Serializer\Exclude()
* @Serializer\Type("ArrayCollection<Element>")
*/
protected $details2;
...
}
元素实体具有类似的结构:
/**
*
* @Serializer\ExclusionPolicy("none")
*/
class Element {
/**
* Primary key
* @var integer $id
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*
* @Serializer\Groups({"list","details"})
* @Serializer\Type("integer")
*/
protected $id;
/**
* @Serializer\Groups({"list","details"})
* @Serializer\Type("string")
*/
protected $name;
/**
* @ORM\Column(name="description", type="string", length=4096, nullable=true)
*
* @Serializer\Groups({"details"})
* @Serializer\Type("string")
*/
protected $description;
...
}
我的问题是,当我使用'详细信息'组实体序列化产品时,我想仅序列化元素的ID,但是当您看到实体已定义与Product相同的组时(如果我需要元素对象的详细信息)因为我希望在我的所有实体上都有统一的组,并阻止制作数百个组,如'product_details','element_details'等。
当我访问关系或类似的东西时,有没有办法最终更改序列化组?处理程序可能或类似的东西?
关心并感谢您的帮助
答案 0 :(得分:7)
不幸的是,你不能真的(但继续阅读;-)),至少没有改变序列化程序库。罪魁祸首是,在您开始序列化过程的那一刻,组列表被固定在GroupExclusionStrategy
(由Context
引用)内。实际上,代码中存在一个断言,阻止在(反)序列化运行后修改排除策略。
但是当它发生时,我在我的项目中也遇到了完全相同的问题,并且我对序列化代码进行了必要的修改。我已经清理了一些代码并将其上传到Github(https://github.com/andreasferber/serializer/tree/recursion-groups)。
它添加了新的属性元数据,您可以在下载到子对象时添加,删除或覆盖组。使用注释看起来像这样:
/**
* @Serializer\RecursionGroups(set={"foo", "bar"}, add={"baz"}, remove={"Default"})
*/
private $myProperty;
您也应该能够使用XML或Yaml元数据,但是这是未经测试的,因为我没有使用它们,我还没有添加测试用例。看一下参考文档。由于我还没有做过任何优化,如果你的实体非常庞大并且嵌套得很深,那么它可能会对性能产生明显的影响。
如果您觉得这很有用,或者您有任何建议,请告诉我,因为如果我不仅需要这样做,我会添加一些测试并尝试将其提交到上游。
答案 1 :(得分:1)
official documentation实际上描述了这方面的解决方案。
据说@aferber提出的解决方案在许多方面似乎更好:更容易维护,更简洁,更灵活......
答案 2 :(得分:0)
您需要使用setGroups
。
不需要官方文档中使用的_group
后缀。
$context->setGroups([
'Default', //if you want
// use this linked entity but show only its id
'group_of_linked_field',
'group_of_linked_field' => [
'id' // you will need to define this group first
],
// use this linked entity and show fields as described
'group_of_other_linked_field',
'group_of_other_linked_field' => [
// just as an example
'Default',
'details',
],
]);
这与addGroup
或addGroups
一起不起作用!他们都不接受关联数组。 setGroups
是您(唯一的?)解决方案。