在Symfony中,我正在爲Angular2編寫一個API。我使用帶有JMSSerializerBundle的FOSRestBundle。現在,我有一個實體「用戶」,其實體字段「地址」與OneToOne關聯。而且我無法保存用戶的地址。Symfony REST API - 實體關聯字段 - >值無效
所以我首先做一個用戶對象的GET,它返回的地址爲json的整個對象。然後,我使用完全相同的對象執行PUT請求。在我的PUT功能我用Symfony的形式來驗證數據和有它返回一個錯誤:
{
"children": {
"address": {
"errors": [
"This value is not valid."
]
}
}
}
我有我的用戶實體其他一些領域,當我離開了地址欄的完美救了我形式建設者。順便說一句:我遺漏了其他領域,不超載代碼量。
我使用這些版本:
- 的symfony:3.1
- JMS /串行:1.1
- friendsofsymfony /休息束:2.0
我一直在尋找2天現在,我無法找到任何有助於解決此問題的方法。我使用日期轉換像FOSRestBundle說:http://symfony.com/doc/current/bundles/FOSRestBundle/2-the-view-layer.html#data-transformation
我希望我制定了我的問題足夠好,給了足夠的信息。
這裏是我的簡化代碼:
用戶等級:
use Doctrine\ORM\Mapping as ORM;
use JMS\Serializer\Annotation as JMS;
/**
* @ORM\Entity
*/
class User
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* @ORM\OneToOne(targetEntity="Address", cascade={"persist", "remove"}, orphanRemoval=true)
* @JMS\Type("AppBundle\Entity\Address")
*/
private $address;
Address類:
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity
*/
class Address
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @ORM\Column(type="string")
*/
private $street;
/**
* @ORM\Column(type="string")
*/
private $number;
/**
* @ORM\Column(type="string")
*/
private $postalCode;
/**
* @ORM\Column(type="string")
*/
private $city;
/**
* @ORM\Column(type="string")
*/
private $country;
用戶類型類:
use FOS\RestBundle\Form\Transformer\EntityToIdObjectTransformer;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class UserType extends AbstractType
{
/**
* @param FormBuilderInterface $builder
* @param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
// Data transformation needed for relationship entities
$addressTransformer = new EntityToIdObjectTransformer($options['em'], 'AppBundle:Address');
$builder
->add($builder->create('address', TextType::class)->addModelTransformer($addressTransformer))
;
}
/**
* @param OptionsResolver $resolver
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'AppBundle\Entity\User',
'csrf_protection' => false,
'allow_extra_fields' => true,
'em' => null
));
}
/**
* {@inheritdoc}
*/
public function getName()
{
return 'user';
}
}
UserController類:
use AppBundle\Entity\User;
use AppBundle\Form\UserType;
use FOS\RestBundle\Controller\Annotations as Rest;
use FOS\RestBundle\View\View;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
/**
* Class UserController
* @package AppBundle\Controller
*/
class UserController extends Controller
{
/**
* @Rest\View
* @Route("https://stackoverflow.com/users/{id}")
* @Method("PUT")
*/
public function putAction(Request $request, $id)
{
$user = $this->getEntity($id);
$form = $this->createForm(UserType::class, $user, array(
'method' => 'PUT',
'em' => $this->getDoctrine()->getManager()
));
$form->handleRequest($request);
if ($form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($user);
$em->flush();
$response = new Response();
$response->setStatusCode(204);
$response->setContent('User saved!');
return $response;
}
return View::create($form, 400);
}
/**
* @Rest\View
* @Route("https://stackoverflow.com/users/{id}", requirements={"id": "\d+"})
* @Method("GET")
*/
public function getAction($id)
{
$user = $this->getEntity($id);
return array('user' => $user);
}
/**
* Get the User entity object by the given ID and return it
*
* @param $id
*
* @return User
*/
private function getEntity($id)
{
$user = $this->getDoctrine()->getRepository('AppBundle:User')->find($id);
if (!$user instanceof User) {
throw new NotFoundHttpException('User not found');
}
return $user;
}
而且JSON對象,我GET和PUT看起來是這樣的:
{
"user":
{
"id":1,
"address": {
"id":1,
"street":"Teststreet",
"number":"1",
"postalCode":"9999",
"city":"Citytest",
"country":"Countrytest"
}
}
}
我config.yml:
fos_rest:
param_fetcher_listener: true
body_listener:
array_normalizer: fos_rest.normalizer.camel_keys
format_listener:
rules:
path: ^/
fallback_format: json
prefer_extension: false
priorities: [json, xml]
body_converter:
enabled: false
validate: false
view:
view_response_listener: force
formats:
json: true
xml: true
templating_formats:
html: true
force_redirects:
html: true
failed_validation: HTTP_BAD_REQUEST
default_engine: twig
mime_types:
json: ['application/json', 'application/json;version=1.0', 'application/json;version=1.1']
routing_loader:
default_format: json
serializer:
serialize_null: true
nelmio_api_doc: ~
jms_serializer:
metadata:
directories:
FOSUB:
namespace_prefix: "FOS\\UserBundle"
path: "%kernel.root_dir%/serializer/FOSUserBundle"