Ошибка отправки формы OneToMany в базу данных (Symfony2 / Doctrine)

У меня есть форма, которая загружает файл, и я пытаюсь "прикрепить" к нему правильный идентификатор/объект задания, но, похоже, я не совсем понимаю концепцию отношений таблиц:

Мой файловый класс

/**
 * @ORM\ManyToOne(targetEntity="Job", inversedBy="file")
 */
protected $job;

Мой рабочий класс:

/**
 * @ORM\OneToMany(targetEntity="File", mappedBy="job")
 */
protected $file;

public function __construct()
{
    $this->file = new ArrayCollection();
}

Я отправляю форму и ввожу все в базу данных:

$em = $this->getDoctrine()->getManager();
    $file = new File();
    $form = $this->createFormBuilder($file)
        ->add('file')
        ->add('job','text')
        ->add('save', 'submit', array('label' => 'Create Task'))
        ->getForm();

    $form->handleRequest($request);

    if ($form->isValid()) {


        $job = $em->getRepository("AppBundle:Job")->find($form->getData()->getJob());

        $file->setFile($form->getData()->getFile());
        $file->setPath($form->getData()->getPath());
        $file->setJob($job);

        $em->persist($file);
        $em->flush();

        return $this->redirectToRoute("pendingJobs");
    }

Отправка формы завершается фатальной ошибкой:

Уловимая фатальная ошибка: аргумент 1, переданный в AppBundle\Entity\File::setJob(), должен быть экземпляром AppBundle\Entity\Job, заданной строкой, вызываемой в /var/www/html/web2gdv/vendor/symfony/symfony/src /Symfony/Component/PropertyAccess/PropertyAccessor.php в строке 410 и определено

Я попытался отладить то, что было отправлено с помощью

if ($form->isValid()) {

        dump($form->getData());
        die();
}

но доходит ли до сути?!

Что я делаю неправильно?

Любая подсказка приветствуется!

ОБНОВЛЕНИЕ

Благодаря @julien-bourdic я обновил свою форму следующим образом:

 /**
 * @Route("/job/pending", name="pendingJobs")
 */
public function jobAction(Request $request)
{
    $this->denyAccessUnlessGranted('ROLE_ADMIN', null, 'Unable to access this page!');

    $em = $this->getDoctrine()->getManager();
    $file = new File();
    $form = $this->createFormBuilder($file)
        ->add('file')
        ->add('job','entity',array(
            'class' => 'AppBundle:Job',
            'choice_label' => 'id',
        ))
        ->add('save', 'submit', array('label' => 'Create Task'))
        ->getForm();

    $form->handleRequest($request);

    if ($form->isValid()) {

        $job = $em->getRepository("AppBundle:Job")->find($form->getData()->getJob());

        $file->setFile($form->getData()->getFile());
        $file->setPath($form->getData()->getPath());
        $file->setJob($job);

        $em->persist($file);
        $em->flush();

        return $this->redirectToRoute("pendingJobs");
    }



    $jobs = $em->getRepository("AppBundle:Job")->findBy(array(
        'receipt' => true,
        'receiptStatus' => true,
    ));

    return $this->render(
        'default/pending.html.twig',
        array(
            'jobs' => $jobs,
            'form' => $form->createView(),
        )
    );


}

Вся цель этого класса состоит в том, чтобы иметь таблицу, где последняя кнопка каждой строки является формой загрузки. Как я могу заполнить несколько форм из одного класса, возможно ли это? Что я должен отправить функции render?


person PrimuS    schedule 16.11.2015    source источник
comment
Можем ли мы увидеть вашу полную работу, пожалуйста?   -  person Julien Bourdic    schedule 16.11.2015
comment
Вот оно, довольно большое: pastebin.com/hEFykA41   -  person PrimuS    schedule 16.11.2015
comment
Для вашего обновления: Нравится таблица заданий с кнопкой загрузки файла в каждой строке?   -  person Julien Bourdic    schedule 16.11.2015
comment
Вот именно... Легче с этим справиться в отдельном контроллере?   -  person PrimuS    schedule 17.11.2015
comment
Это другой вопрос ^^ Но чтобы ответить, да, определенно проще обрабатывать форму создания и обновления, если вы делаете это с одним объектом в другом контроллере.   -  person Julien Bourdic    schedule 17.11.2015
comment
Ладно, посмотрю, когда будет немного свободного времени :)   -  person Julien Bourdic    schedule 17.11.2015


Ответы (3)


Попробуйте явно определить свое поле job в своей форме:

->add('job','entity',array(
        'class'=>'AppBundle:Job',
        'property'=>'id',
)
person Julien Bourdic    schedule 16.11.2015
comment
ИДЕАЛЬНО! изменил property на choice_label, так как он устарел, но он работает. Дополнительный вопрос: как заполнить несколько форм? Я обновлю свой вопрос! - person PrimuS; 16.11.2015

Проблема в том, что find() возвращает массив, а не Job. Используйте findOne().

$job = $em->getRepository("AppBundle:Job")->find($form->getData()->getJob());
// $job is and Array

делать вместо этого

$job = $em->getRepository("AppBundle:Job")->findOne($form->getData()->getJob());
// $job is Job
person Stepashka    schedule 16.11.2015
comment
Хотя это может быть правильным (скорее, findOneBy, я думаю), это не то, что является причиной фатального исхода, поскольку оно не проходит дальше $form->handleRequest($request); - person PrimuS; 16.11.2015

У вас есть add('job', 'text') и должен быть тип сущности, а не текст

Сначала вам нужно иметь «работу» в БД. Затем вы можете изменить на

$form = $this->createFormBuilder($file)
    ->add('file')
    ->add('job','entity', array('class' => 'YourBundle:Job'))
    ->add('save', 'submit', array('label' => 'Create Task'))
    ->getForm();

или короткий

$form = $this->createFormBuilder($file)
    ->add('file')
    ->add('job')
    ->add('save', 'submit', array('label' => 'Create Task'))
     ->getForm();

вы получите поле выбора на поле задания

person ailushyk    schedule 16.11.2015