2012-01-04 15 views
8

私たちはSymfony2を使ってAPIを作成しています。レコードを更新する際には、JSON入力がシリアル化された更新されたエンティティを表すことが期待されます。 JSONデータにはいくつかのフィールドは含まれません(たとえば、CreatedAtは、エンティティが作成されたときに一度しか設定されず、更新されません)。例えば、ここでの例JSONのPUT要求である:ここシリアライズされたJSONからDoctrine Entityを更新するにはどうすればよいですか?

{"id":"1","name":"anyname","description":"anydescription"} 

は、(我々はJMSシリアライザバンドルを使用している)上にJSONに応じてエンティティを更新する必要がコントローラ上のPHPコードである:

$supplier = $serializer->deserialize(
    $this->get('request')->getContent(), 
    'WhateverEntity', 
    'json' 
); 

EntityMangerは、これが更新要求であることを(正確に)理解しています(実際には、SELECTクエリが暗黙的に起動されます)。 EntityManagerは、CreatedAtプロパティをNULL化する必要があると推測します(正しくはありません)。以前のものを保持する必要があります。

この問題を解決するにはどうすればよいですか?

答えて

8

Doctrine\ORM\Mapping\ClassMetadata APIを使用してエンティティの既存のフィールドを検出します。 あなたは(私はJMSSerializerBundleがどのように動作するかわかりません)、次のことが可能です。 http://jmsyst.com/bundles/JMSSerializerBundle

でインストールの指示に従ってくださいいずれかの独自のシリアライザサービスを作成したり、使用するJMSSerializerBundleを変更

//Unserialize data into $data 
$metadata = $em->getMetadataFactory()->getMetadataFor($FQCN); 
$id = array(); 
foreach ($metadata->getIdentifierFieldNames() as $identifier) { 
    if (!isset($data[$identifier])) { 
     throw new InvalidArgumentException('Missing identifier'); 
    } 
    $id[$identifier] = $data[$identifier]; 
    unset($data[$identifier]); 
} 
$entity = $em->find($metadata->getName(), $id); 
foreach ($metadata->getFieldNames() as $field) { 
    //add necessary checks about field read/write operation feasibility here 
    if (isset($data[$field])) { 
     //careful! setters are not being called! Inflection is up to you if you need it! 
     $metadata->setFieldValue($entity, $field, $data[$field]); 
    } 
} 
$em->flush(); 
14

をJMSSerializerBundleを使用して単純なオブジェクトコンストラクタではなく、doctrineオブジェクトコンストラクタです。

<service id="jms_serializer.object_constructor" alias="jms_serializer.doctrine_object_constructor" public="false"/> 

これは基本的にOcramiusソリューションはありませんが、JMSSerializerBundlesがデシリアライズ使用して正確に何を処理します。

関連する問題