Reputation: 401
How to make array of MongoId's in Symfony 3.2 Doctrine ODM serialized/deserialized properly ?
Document
namespace Acme\StoreBundle\Document;
use Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB;
/**
* @MongoDB\Document(collection="Voter")
*/
class Voter
{
/**
* @MongoDB\Id
*/
protected $id;
/**
* @MongoDB\Collection
*/
protected $inlist;
/**
* Get id
*
* @return id $id
*/
public function getId()
{
return $this->id;
}
public function setId($id)
{
$this->id = $id;
return $this;
}
/**
* Set inlist
*
* @param collection $inlist
* @return $this
*/
public function setInlist($inlist)
{
$this->inlist = $inlist;
return $this;
}
/**
* Get inlist
*
* @return collection $inlist
*/
public function getInlist()
{
return $this->inlist;
}
}
Controller:
/**
* @Route("/voter/{id}")
* @Method({"GET"})
*/
public function getAction($id)
{
$product = $this->get('doctrine_mongodb')
->getRepository('AcmeStoreBundle:Voter')
->find($id);
if (!$product) {
throw $this->createNotFoundException('No product found for id ' . $id);
}
$serializer = $this->get('serializer');
$data = $serializer->serialize(
$product,
'json'
);
$response = new JsonResponse();
$response->setContent($data);
return $response;
}
Serialized Json:
{
"id": "593e99a8de6c84f5ecec3094",
"inlist": [
{
"timestamp": 1417718686,
"pID": 3335,
"inc": 9127278,
"$id": "5480ab9e282e26070d8b456e"
},
{
"timestamp": 1417718686,
"pID": 3335,
"inc": 9127273,
"$id": "5480ab9e282e26070d8b4569"
},
{
"timestamp": 1417718686,
"pID": 3335,
"inc": 9127272,
"$id": "5480ab9e282e26070d8b4568"
},
{
"timestamp": 1417718686,
"pID": 3335,
"inc": 9127275,
"$id": "5480ab9e282e26070d8b456b"
},
{
"timestamp": 1417718686,
"pID": 3335,
"inc": 9127274,
"$id": "5480ab9e282e26070d8b456a"
},
{
"timestamp": 1411754988,
"pID": 2674,
"inc": 9127271,
"$id": "5425abec8f3723720a8b4567"
}
]
}
I want it to be serialized to be an array of (string) id's, and deserialize it back to array of MongoId's:
{
"id": "593e99a8de6c84f5ecec3094",
"inlist": ['5425abec8f3723720a8b4567', '5480ab9e282e26070d8b456b' ...]
}
Upvotes: 0
Views: 179
Reputation: 401
setter/getter way worked for me even with serializer / deserializer
/**
* Set actions
*
* @param collection $actions
* @return $this
*/
public function setActions($actions)
{
$re = [];
foreach ($actions as $action) {
$action['cid'] = new \MongoId($action['cid']);
$re[] = $action;
}
$this->actions = $re;
return $this;
}
/**
* Get actions
*
* @return collection $actions
*/
public function getActions()
{
$re = [];
foreach ($this->actions as $action) {
$action['cid'] = (string)$action['cid'];
$re[] = $action;
}
return $re;
}
Upvotes: 0
Reputation: 2966
Since you mentioned "right way" in the comments here's how I would do it:
class VoterAPIRepresentation
{
public $id;
public $inlist = [];
public function __construct(Voter $voter)
{
$this->id = (string) $voter->id;
foreach ($voter->inlist as $i) {
$this->inlist[] = (string) $i['$id'];
}
}
}
Above class is responsible for data representation in API since entity itself shouldn't be concerned with that. Then in controller:
public function getAction($id)
{
$product = $this->get('doctrine_mongodb')
->getRepository('AcmeStoreBundle:Voter')
->find($id);
if (!$product) {
throw $this->createNotFoundException('No product found for id ' . $id);
}
$serializer = $this->get('serializer');
$data = $serializer->serialize(
new VoterAPIRepresentation($product),
'json'
);
$response = new JsonResponse();
$response->setContent($data);
return $response;
}
Pro of this approach is that if you change the entity you don't need to be concerned with any endpoints and data they're returning since these two beings are not connected. On the other hand writing such classes is quite boring BUT it pays off for complex objects and representations.
Upvotes: 1