Doctrine Mongo ODM合并用于外部修改的数据

时间:2012-07-06 12:57:23

标签: rest doctrine-odm symfony-2.1

我正在编写一个Symfony2应用程序,允许移动用户通过REST服务创建和更新“Homes”。我使用MongoDB作为存储层,使用Doctrine MongoDB ODM来处理文档。

GET /homes/{key}POST /homes方法正常运行。当我尝试使用PUT /homes/{key}更新现有主页时出现问题。

这是当前的代码:

/**
 * PUT /homes/{key}
 *
 * Updates an existing Home.
 *
 * @param Request $request
 * @param string $key
 * @return Response
 * @throws HttpException
 */
public function putHomeAction(Request $request, $key)
{
    // check that the home exists
    $home = $this->getRepository()->findOneBy(array('key' => (int) $key));

    // disallow create via PUT as we want to generate key ourselves
    if (!$home) {
        throw new HttpException(403, 'Home key: '.$key." doesn't exist, to create use POST /homes");
    }

    // create object graph from JSON string
    $updatedHome = $this->get('serializer')->deserialize(
        $request->getContent(), 'Acme\ApiBundle\Document\Home', 'json'
    );

    // replace existing Home with new data
    $dm = $this->get('doctrine.odm.mongodb.document_manager');
    $home = $dm->merge($updatedHome);
    $dm->flush();

    $view = View::create()
        ->setStatusCode(200)
        ->setData($home);

    $response = $this->get('fos_rest.view_handler')->handle($view);
    $response->setETag(md5($response->getContent()));
    $response->setLastModified($home->getUpdated());

    return $response;
}

传递给操作的JSON字符串由JMSSerializer成功反序列化为我的Document对象图,但是当我尝试合并& flush,我收到错误:

Notice: Undefined index:  in ..../vendor/doctrine/mongodb-odm/lib/Doctrine/ODM/MongoDB/Mapping/ClassMetadataInfo.php line 1265

我一直在尝试按照此处的文档:http://docs.doctrine-project.org/projects/doctrine-mongodb-odm/en/latest/reference/working-with-objects.html#merging-documents

在尝试合并之前,我需要对反序列化的Home做些什么吗?合并错误的方法吗?

感谢。

1 个答案:

答案 0 :(得分:1)

我发现这样做的唯一方法是在文档类中创建一个方法,该方法将更新的文档(例如$updatedHome)作为参数,然后将所需的字段复制到现有文档中(例如$home)。

如上所述,代码:

// replace existing Home with new data
$dm = $this->get('doctrine.odm.mongodb.document_manager');
$home = $dm->merge($updatedHome);
$dm->flush();

可以替换为:

// replace existing Home with new data
$home->copyFromSibling($updatedHome);
$this->getDocumentManager()->flush();

然后它会起作用。