Я боролся с этим в течение нескольких дней, поэтому я надеюсь, что кто-то может помочь.Symfony2 встроенная форма OneToMany отношения, как сохранить связанные данные
У меня есть отношение OneToMany между таблицей. Ресурсы и мой FOSUserBundle предоставляют пользовательский объект, так что один пользователь может разместить много ресурсов.
Примечание: сущности, были отредактированы для краткости, однако я не считаю, что я удалил что-нибудь важное для этого вопроса
Мои ресурсы объект:
<?php
namespace SFI\MainBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity(repositoryClass="SFI\MainBundle\Entity\ResourcesRepository")
* @ORM\Table(name="resources")
*/
class Resources {
/**
* @ORM\Column(name="id", type="integer", nullable=false)
* @ORM\Id()
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
protected $id;
/**
* @ORM\Column(type="string", length=255)
*/
protected $name;
/**
* @ORM\Column(type="string", length=255)
*/
protected $type;
/**
* @ORM\Column(type="string", length=255)
*/
protected $link;
/**
* @ORM\Column(type="text")
*/
protected $description;
/**
* @ORM\Column(type="datetime")
*/
protected $created_time;
/**
* @ORM\ManyToOne(targetEntity="SFI\UserBundle\Entity\User", inversedBy="created_by")
* @ORM\JoinColumn(name="created_by", referencedColumnName="id")
*/
protected $created_by;
---rest of getters and setters---
/**
* Set created_by
*
* @param \SFI\UserBundle\Entity\User $createdBy
* @return Resources
*/
public function setCreatedBy(\SFI\UserBundle\Entity\User $createdBy = null)
{
$this->created_by = $createdBy;
return $this;
}
/**
* Get created_by
*
* @return \SFI\UserBundle\Entity\User
*/
public function getCreatedBy()
{
return $this->created_by;
}
}
Моя сущность Пользователь:
<?php
namespace SFI\UserBundle\Entity;
use FOS\UserBundle\Model\User as BaseUser;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
/**
* @ORM\Entity(repositoryClass="SFI\UserBundle\Entity\UserRepository")
* @ORM\Table(name="fos_user")
*/
class User extends BaseUser
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
public function __construct()
{
parent::__construct();
}
/**
* @ORM\Column(type="string", length=255)
*
* @Assert\NotBlank(message="Please enter your name.", groups={"Registration", "Profile"})
* @Assert\Length(
* min=3,
* max="255",
* minMessage="The name is too short.",
* maxMessage="The name is too long.",
* groups={"Registration", "Profile"}
*)
*/
protected $name;
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set name
*
* @param string $name
* @return User
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* @return string
*/
public function getName()
{
return $this->name;
}
/**
* @ORM\OneToMany(targetEntity="SFI\MainBundle\Entity\Resources", mappedBy="created_by")
*/
protected $created_by;
/**
* Add created_by
*
* @param \SFI\MainBundle\Entity\Resources $createdBy
* @return User
*/
public function addCreatedBy(\SFI\MainBundle\Entity\Resources $createdBy)
{
$this->created_by[] = $createdBy;
return $this;
}
/**
* Remove created_by
*
* @param \SFI\MainBundle\Entity\Resources $createdBy
*/
public function removeCreatedBy(\SFI\MainBundle\Entity\Resources $createdBy)
{
$this->created_by->removeElement($createdBy);
}
/**
* Get created_by
*
* @return \Doctrine\Common\Collections\Collection
*/
public function getCreatedBy()
{
return $this->created_by;
}
}
У меня есть несколько типов форм, но основной, с которыми я работаю, это ResourceType:
<?php
namespace SFI\MainBundle\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
class ResourceType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
//Setting date and time
$created_at = new \DateTime('now');
$builder
->add('name', 'text', array(
'required' => true,
'attr' => array(
'class' => 'form-control',
'placeholder' => 'Resource name',
),
))
->add('type', 'choice', array(
'required' => true,
'empty_value' => 'Choose a type',
'choices' => array('w' => 'Website', 'v' => 'Video', 'a' => 'Audio'),
'attr' => array(
'class' => 'form-control',
),
))
->add('link', 'text', array(
'required' => true,
'attr' => array(
'class' => 'form-control',
'placeholder' => 'Add a link',
),
))
->add('description', 'textarea', array(
'required' => true,
'attr' => array(
'class' => 'textarea',
'style' => 'width: 100%; height: 200px; font-size: 14px; line-height: 18px; border: 1px solid #dddddd; padding: 10px;',
'placeholder' => 'Write a description...',
),
))
->add('created_time', 'datetime', array(
'disabled' => true,
'data' => $created_at,
))
->add('save', 'submit', array(
'attr' => array('class' => 'btn btn-primary'),
));
}
public function getName()
{
return 'resource';
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'SFI\MainBundle\Entity\Resources',
));
}
}
Мой контроллер для вида ресурса части:
public function resourcesAction(Request $request)
{
$breadcrumbs = $this->get("white_october_breadcrumbs");
$breadcrumbs->addItem("SFI Portalen", $this->get("router")->generate("sfi_static_index"));
$breadcrumbs->addItem("Teacher Dashboard", $this->get("router")->generate("sfi_teacher_dashboard"));
$breadcrumbs->addItem("Resources");
$em = $this->getDoctrine()->getManager();
$resource = new Resources();
$newResourceForm = $this->createForm(new ResourceType(), $resource);
$newResourceForm->handleRequest($request);
if ($newResourceForm->isValid()) {
$session = $this->getRequest()->getSession();
//$session->getFlashBag()->add('notice', 'Form processed');
$session->getFlashBag()->add('notice', 'Form processed, testing, no persist');
//$em->persist($resource);
//$em->flush();
return $this->redirect($this->generateUrl('sfi_teacher_resources'));
}
return $this->render('SFIMainBundle:Teacher:resources.html.twig', array(
'form' => $newResourceForm->createView(),
));
}
Что мне нужно сделать, это связать эти объекты при создании нового ресурса, чтобы «назначить» его вошедшего пользователя через отношение в таблицах.
Я изучил встроенные формы и другие предложения по документации Symfony, но я не могу окунуться в то, как применять то, что я читал к этому конкретному примеру. Я следовал примеру с задачами, тегами и категориями, и все это, но я не могу понять, как это применимо к моей ситуации, имея объект User в другом комплекте и тип формы пользователя, который связывает пользователя с их и добавляет дополнительное полное поле имени, наследуя исходный тип формы FOSUserBundle.
У меня также есть смешное ощущение, что я не занимался или «правильно формулировал» отношения в своем коде, чтобы было легче понять, какие объекты связаны.
Любая помощь была бы высоко оценена! Также, пожалуйста, дайте мне знать, если вам нужен другой код или дополнительная информация.
Не то, чтобы это вызывало какие-либо ошибки, но использование одного и того же имени отношения между двумя объектами является путаным. Подумайте о переименовании своего объекта 'User', чтобы вместо свойства' created_by' как нечто вроде 'resources' вместо свойства' created_by'. – sjagr
Я изменил это, я согласен, это облегчает ситуацию. Я также изменю заголовок, так как сейчас нет ошибки в том, как я показываю форму, я просто хотел бы знать, что мне еще нужно, чтобы создать форму, которая будет сохранять данные с правильной связью. – TuxMeister