ManyToOne使用FOSUSerBundle忽略排除策略

时间:2014-07-07 18:56:43

标签: entity-framework symfony serialization doctrine-orm

为API类型事物构建JSON响应,以检索在我的实体的实体中包含ManyToOne关系的特定数据集,该实体扩展了FOSUSerBundle的用户实体(在我的案例中称为Account)。

问题是,需要包含在响应中作为字段的Account实体,但我不想包含所有密码和角色类型的东西。

我现在已经在互联网上浏览了几个小时,而且我已经跟着许多指南,我每次都清理了我的缓存,但无济于事;所以我最终在这里:

// app/config/config.yml
jms_serializer:
  metadata:
    auto_detection: true
    directories:
      FOSUserBundle:
        namespace_prefix: "FOS\\UserBundle"
        path: "%kernel.root_dir%/Resources/serializer/FOS"  

我已经在下面尝试了User.Model.ymlModel.User.yml以及User.Entity.yml并且徒劳地认为文件名实际上很重要

// app/Resources/serializer/FOS/Entity.User.yml
FOS\UserBundle\Model\User:
  exclusion_policy: ALL
  properties:
    id:
      expose: true

我得到的仍然是这样的:

{
   "status":"ok",
   "api_version":"1.0",
   "code":200,
   "data":{
      "video":{
         "id":1,
         "published":true,
         "visibility":true,
         "title":"Megaman 2",
         "slug":"megaman-2",
         "summary":"A rap song about Megaman",
         "description":"A rap song\r\nAbout megaman",
         "youtube_id":"R6L9bUouDr8",
         "date_published":"2014-07-02T14:09:26-0700",
         "date_created":"2014-07-02T14:09:26-0700",
         "date_updated":"2014-07-02T14:09:26-0700",
         "author_id":3,
         "author":{
            "id":3,
            "username":"kharrison",
            "username_canonical":"kharrison",
            "email":"(sorry private)",
            "email_canonical":"(sorry, private)",
            "enabled":true,
            "salt":"(sorry, private)",
            "password":"(sorry, private)",
            "last_login":"2014-07-04T15:17:34-0700",
            "locked":false,
            "expired":false,
            "roles":[
               "ROLE_SUPER_ADMIN"
            ],
            "credentials_expired":false,
            "display_name":"Kyle Harrison",
            "slug":"kyle-harrison",
            "bio":"Test"
         }
      }
   }
}

"作者"字段,是我通过JMSSerializer运行的帐户实体

我想排除所有这些,除了用户ID,显示名称和slug。

最后这就是API的工作原理:

// My/Bundle/Controller/BaseAPIController.php
    //......... other code

    /**
     * @param string $status
     * @param integer $code
     * @return Response
     */
    public function render_api($status, $code)
    {
        $this->apiResponse->setStatus($status);
        $this->apiResponse->setCode($code);

        return new Response($this->apiResponse->serialize($this->get('jms_serializer')), $this->apiResponse->getCode(), ["Content-type"=>"application/json"]);
    }

    //............. other code

最后,这称之为:

// My/Bundle/Models
class APIResponse {

    protected $status;
    protected $apiVersion;
    protected $code;
    protected $data;

    public function __construct($apiVersion, $status = "OK", $code = 500)
    {
        $this->status = $status;
        $this->code = $code;
        $this->apiVersion = $apiVersion;
        $this->data = [];
    }

    // ... getters and setters

    /**
     * @return mixed
     */
    public function serialize($serializer) {
        return $serializer->serialize($this, "json");
    }

}

3 个答案:

答案 0 :(得分:2)

  

我已经尝试User.Model.ymlModel.User.yml了   User.Entity.yml以及文件名实际上是徒劳的   的事项。

实际上,这很重要。它是命名空间和类名的串联。在这种情况下,您尝试配置FOS\UserBundle\Model\User类,因此文件名应为Model.User.yml。 (FOS\UserBundle\应从文件名中排除,因为您在namespace_prefix中将其config.yml配置为

还要确保您的Account类没有重新声明(覆盖)属性,因为序列化程序配置仅在为实际声明属性的类配置它时才有效。

答案 1 :(得分:1)

好的,实际的答案,不可能通过我提供的信息到达。但Nic的答案确实引导我走向解决方案。序列化程序如何查看和解密配置文件的描述引出了我手头的真正问题。

这是我未能展示的内容:

<?php

namespace [PRIVATE]\[PRIVATE]Bundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use FOS\UserBundle\Model\User as BaseUser;
use JMS\Serializer\Annotation\ExclusionPolicy;
use JMS\Serializer\Annotation\Expose;
use JMS\Serializer\Annotation\Groups;
use JMS\Serializer\Annotation\VirtualProperty;

/**
 * Account
 *
 * @ORM\Table()
 * @ORM\Entity(repositoryClass="[PRIVATE]\[PRIVATE]Bundle\Entity\AccountRepository")
 */
class Account extends BaseUser
{

问题在于Alias我提供了FOS\UserBundle\Model\User命名空间。我不再记得为什么我这样写了。但是,当我删除Alias并重新编写延伸以代替它时:

<?php

namespace [PRIVATE]\[PRIVATE]Bundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use FOS\UserBundle\Model\User;
use JMS\Serializer\Annotation\ExclusionPolicy;
use JMS\Serializer\Annotation\Expose;
use JMS\Serializer\Annotation\Groups;
use JMS\Serializer\Annotation\VirtualProperty;

/**
 * Account
 *
 * @ORM\Table()
 * @ORM\Entity(repositoryClass="[PRIVATE]\[PRIVATE]Bundle\Entity\AccountRepository")
 */
class Account extends User
{

结合Nic的回答中新的正确文件名,JMSSerializerBundle的基于配置的排除策略完全开始,FOSUserBundle项目的每个实例现在都被完全隐藏,除了我现在明确告诉它暴露的字段。

这正是我想要的:)

感谢大家的帮助!干杯

〜ķ

答案 2 :(得分:0)

我不确定这是你想要它的确切方式,更多的方法:

方法1:仅选择所需的属性(通过实体管理器),然后序列化获得的数组。

这就是我用我称之为API的方式(除了控制器之外,它不是一个类)