我几天都在努力解决这个问题,所以我希望有人可以提供帮助。
我在表资源和我的FOSUserBundle提供的User实体之间有一个OneToMany关系,这样一个用户可以发布很多资源。
注意:为简洁起见,实体已经过编辑,但我不相信我删除了对此问题重要的内容
我的资源实体:
<?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(),
));
}
我需要做的是在创建新资源时将这些实体联系起来,然后分配&#34;它通过表格中的关系登录用户。
我已经查看了有关Symfony文档的嵌入式表单和其他建议,但我无法理解如何将我读到的内容应用于此特定示例。我已经按照示例了解了任务,标签和类别以及所有这些,但我无法理解它如何适用于我的情况,将User实体放在另一个包中,以及一个与用户相关的用户表单类型到他们的学校,只需添加一个额外的全名字段,同时继承FOSUserBundle的原始表格类型。
我也有一种有趣的感觉,我无法解决或排除&#34;我的代码中的关系正确,以便更容易理解哪些对象相关。
任何帮助将不胜感激!如果您需要其他代码或更多信息,请告知我们。
答案 0 :(得分:2)
您应该能够在持久化Resources实体之前手动设置用户。
if ($newResourceForm->isValid()) {
...
$resource->setCreatedBy($this->getUser());
$em->persist($resource);
$em->flush();
...
}
Symfony使用控制器中的 $ this-&gt; getUser()快捷方式(参见http://symfony.com/doc/current/book/security.html#retrieving-the-user-object)。我假设您在用户登录时只允许使用此表单。
此外,如果您使用的是Doctrine,我建议您使用它来为您生成实体和getter / setter,因为它会生成符合Symfony约定的合理名称。例如,您的实体最终会被命名为“资源”和“资源”。 vs.&#39;资源&#39;,你的变量将是camelCased($ createdBy vs. $ created_by)。
答案 1 :(得分:1)
好的,基于Jason的建议,以及sjagr的前一个建议,我已经重新命名了一些事情以保持一致性和更好理解,并且我写了以下内容,它正常工作!
谢谢大家的帮助!
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 Resource();
$createdBy = $em->getRepository('SFIUserBundle:User')->find($this->getUser()->getId());
$newResourceForm = $this->createForm(new ResourceType(), $resource);
$newResourceForm->handleRequest($request);
if ($newResourceForm->isValid()) {
//Getting current date and time
$created_time = new \DateTime('now');
$resource->setCreatedTime($created_time);
$resource->setCreatedBy($createdBy);
$session = $this->getRequest()->getSession();
$session->getFlashBag()->add('notice', 'Form processed');
$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(),
));
}
我只需要在 setCreatedBy 中传递当前用户的整个对象,并且关系正常。
再次感谢大家!