8

Symfony 2.2 と最新バージョンの FOSRestBundle を使用しています。そのため、ほとんどのアクションを機能させることができましたが、PUT 呼び出しのリクエストを渡している FormBuilder に問題があるようです。

私はリクエストオブジェクトをチェックしましたが、それは私のBackbone.jeモデルからのものです(.save())しかし、フォームにバインドした後、エンティティは必要なフィールドのためにflush()がエラーをスローするIDのみを返します満たされません。

コントローラーでのアクション:

header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS ');
header('Allow GET, POST, PUT, DELETE, OPTIONS ');
header('Access-Control-Allow-Credentials: true');
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Headers: Content-Type, *');

use FOS\RestBundle\Controller\FOSRestController;
use FOS\RestBundle\Controller\Annotations as Rest;
use FOS\RestBundle\Routing\ClassResourceInterface;
use FOS\Rest\Util\Codes;
use Symfony\Component\HttpFoundation\Request;
use Greenthumbed\ApiBundle\Entity\Container;
use Greenthumbed\ApiBundle\Form\ContainerType;

class ContainerController extends FOSRestController implements ClassResourceInterface
{
/**
 * Put action
 * @var Request $request
 * @var integer $id Id of the entity
 * @return View|array
 */
public function putAction(Request $request, $id)
{
    $entity = $this->getEntity($id);
    $form = $this->createForm(new ContainerType(), $entity);
    $form->bind($request);

    if ($form->isValid()) {
        $em = $this->getDoctrine()->getManager();
        $em->persist($entity);
        $em->flush();

        return $this->view(null, Codes::HTTP_NO_CONTENT);
    }

    return array(
        'form' => $form,
    );
}

/**
 * Get entity instance
 * @var integer $id Id of the entity
 * @return Container
 */
protected function getEntity($id)
{
    $em = $this->getDoctrine()->getManager();

    $entity = $em->getRepository('GreenthumbedApiBundle:Container')->find($id);

    if (!$entity) {
        throw $this->createNotFoundException('Unable to find Container entity');
    }

    return $entity;
}

呼び出されるフォーム:

namespace Greenthumbed\ApiBundle\Form;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;

class ContainerType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('name')
            ->add('description')
            ->add('isVisible')
            ->add('type')
            ->add('size')
            ->add('creationDate')
            ->add('userId')
        ;
    }

    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'Greenthumbed\ApiBundle\Entity\Container',
            'csrf_protection' => false,
        ));
    }

    public function getName()
    {
        return 'greenthumbed_apibundle_containertype';
    }
}

私はこれまですべてを試してきましたが、私は Symfony にかなり慣れていないため、リクエストによって受け取った値が $entity に含まれていない理由を理解できません。

参考までに: リクエストの ID を使用して Container クラスをインスタンス化し、セッターを使用してそれに値を入力するなど、手動で試してみましたが、問題なく動作します。Symfony が示唆するように、正しい方法で物事を行いたいだけです。終わり。

事前にどうもありがとうございました。

4

4 に答える 4

6

私と同じ問題が発生していると思います。間違いはフォームの名前にあります。

フォーム定義では、名前は「greenthumbed_apibundle_containertype」です。public function getName() { return 'greenthumbed_apibundle_containertype'; }

したがって、リクエストをこのフォームにバインドするには、json は次のようになります。

{"greenthumbed_apibundle_containertype": [{"key": "value"}]}

Backbone .save() メソッドはこの種の json を出荷するので

{"key":"value","key2":"value2"}

フォームから名前を削除する必要があります。

public function getName()
{
    return '';
}

一般に、次のようなプレースホルダーを使用してjsonを投稿する場合

"something":{"key":"value"}

フォーム名は正確に「何か」でなければなりません

ここで私自身の質問から

于 2013-12-14T15:19:08.637 に答える
0

http://symfony.com/doc/current/cookbook/routing/method_parameters.htmlを参照してください

残念ながら、ほとんどのブラウザーは PUT および DELETE 要求の送信をサポートしていないため、人生はそれほど単純ではありません。幸いなことに、Symfony2 はこの制限を回避する簡単な方法を提供します。クエリ文字列または HTTP リクエストのパラメーターに _method パラメーターを含めることにより、Symfony2 はルートを照合するときにこれをメソッドとして使用します。フォームの送信方法が GET または POST でない場合、フォームにはこのパラメーターの非表示フィールドが自動的に含まれます。詳細については、フォーム ドキュメントの関連する章を参照してください。

およびhttp://symfony.com/doc/current/book/forms.html#book-forms-ching-action-and-method

フォームのメソッドが GET または POST ではなく、PUT、PATCH、または DELETE である場合、Symfony2 はこのメソッドを格納する「_method」という名前の非表示フィールドを挿入します。フォームは通常の POST リクエストで送信されますが、Symfony2 のルーターは「_method」パラメーターを検出でき、リクエストを PUT、PATCH、または DELETE リクエストとして解釈します。詳細については、クックブックの章「ルートで GET および POST 以外の HTTP メソッドを使用する方法」を参照してください。

于 2013-11-28T19:23:41.583 に答える