JMSSerializerBundleでシリアル化したいエンティティが2つあります。 Music
エンティティには、exclusion_policy: NONE
のマッピングファイルがあります。
Music
エンティティには、User
からのエンティティFOSUserBundle
のフィールドがあります。 User
エンティティにはexclusion_policy: ALL
のマッピングファイルがあり、いくつかのフィールドがexpose: true
に設定されているため、シリアル化されます。
問題は、User
フィールドが完全にシリアル化されることです。 User
エンティティのマッピングファイルを変更してもかまいません。
これはそれがどのように見えるかです:
#My/Bundle/Resources/config/serializer/Entity.Music.yml
xxx\xxx\Entity\Music:
exclusion_policy: NONE
#My/Bundle/Resources/config/serializer/Entity.User.yml
xxx\xxx\Entity\User:
exclusion_policy: ALL
properties:
id:
expose: true
username:
expose: true
username_canonical:
exclude: true
email:
exclude: true
email_canonical:
exclude: true
enabled:
exclude: true
salt:
exclude: true
password:
exclude: true
last_login:
exclude: true
confirmation_token:
exclude: true
password_requested_at:
exclude: true
groups:
exclude: true
locked:
exclude: true
expired:
exclude: true
expires_at:
exclude: true
roles:
expose: true
credentials_expired:
exclude: true
credentials_expired_at:
exclude: true
独自のマッピングファイルを参照しないのはなぜですか?それとも私はどこかで間違っていますか?
サードパーティのメタデータドキュメントを読みました。シリアライザーサービスに新しいディレクトリを追加するように指示するだけです。私はそれを実行しましたが、FOS\UserBundle\Entity
クラスを拡張する必要があり、除外しようとしている親保護フィールドにもアクセスできません。
xxx\xxx\Entity\User:
はあなたの自分の名前空間とクラスを参照しているに違いありません。
もしそうなら、それは間違った方法です。
ルールは、プロパティが存在するクラスに適用する必要があります。
構成で公開したプロパティを考えると、FOSUserBundle
を使用していると思います。
したがって、FOS\UserBundle\Model\User
にルールを適用する必要があります。
次に、JMSSerializer
構成を追加して、指定された名前空間のシリアライザーメタデータが存在する場所を示す必要があります。
次のようになります。
jms_serializer:
metadata:
auto_detection: true
directories:
FOSUserBundle:
namespace_prefix: "FOS\\UserBundle"
path: "@YourUserBundle/Resources/config/serializer/fos"
fos/
ディレクトリにModel.User.ymlがあるはずです
次のようなもので:
FOS\UserBundle\Model\User:
exclusion_policy: ALL
properties:
id:
expose: true
groups: [list, details]
username:
expose: true
groups: [details]
email:
expose: true
groups: [me]
roles:
expose: true
groups: [details]
詳細:
メタデータを介してSerializerにルールを適用する場合、Serializerは、メタデータ内のdefinedであるクラス内でdeclaredであるプロパティを検索します。
例:
class Foo {
protected $foo;
}
class Bar extends Foo {
protected $bar;
}
メタデータは次のようになります。
Foo:
exclusion_policy: ALL
properties:
foo:
expose: true
Bar:
exclusion_policy: ALL
properties:
bar:
expose: true
以下の例IS正しい方法ではありません
Bar:
exclusion_policy: ALL
properties:
foo:
expose: true
bar:
expose: true
これを行うと、プロパティbar
のルールのみが適用(および公開)されます。
シリアライザーを間違った方法で取得していたというこの問題がありました。 JMSSerializerBundle
が必要であり、構成を有効にするにはサービスを使用します。
したがって、代わりに:
//In controller we can use $this instead of $container
$serializer = $this->get('jms_serializer'); //JMSSerializerBundle
私が使用した:
$serializer = SerializerBuilder::create()->build(); //JMSSerializer
最初の方法を使用すると、構成がロードされます。 Propel
を使用しているので、すべてのBaseObject
フィールドを無視する必要がありました。
#app/config.yml
jms_serializer:
metadata:
auto_detection: true
directories:
Propel:
namespace_prefix: ""
path: "@MySupporterBundle/Resources/config/serializer"
BaseObject
には名前空間がなく、これを機能させるには次のパッケージが必要であることに注意してください(メタデータ1.2より前にバグがありました)。
"jms/serializer": "0.12.*",
"jms/serializer-bundle" : "0.12.*@dev",
"jms/metadata" : "1.3.*",
だから私はこのファイルを作りました:
#My/SupporterBundle/Resources/config/serializer/BaseObject.yml
BaseObject:
exclusion_policy: ALL
また、特定のオブジェクト(モデル名前空間内)にはファイルが必要です(デフォルトの名前空間はMy/OtherBundle)。
My/OtherBundle/Resources/config/serializer/Model.om.BaseClass.yml My/OtherBundle/Resources/config/serializer/Model.Class.yml
注:新しいシリアライザーファイルを作成するときは、キャッシュをクリアする必要があります