簡體   English   中英

Symfony2內嵌形式的OneToMany關系,如何持久保存相關數據

[英]Symfony2 embedded form OneToMany relationship, how to persist related data

我已經為此苦苦掙扎了幾天,所以希望有人能幫上忙。

我在表資源和我提供的FOSUserBundle用戶實體之間有一個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(),
      ));
  }

我需要做的是在創建新資源時關聯這些實體,以通過表中的關系將其“分配”給登錄用戶。

我已經研究了Symfony文檔中的嵌入式表格和其他建議,但是我無法確定如何將閱讀的內容應用於該特定示例。 我已經按照示例介紹了任務,標簽,類別以及所有其他內容,但是我無法理解它如何適用於我的情況,將User實體放在另一個包中,並且將用戶與他們的用戶聯系起來的User表單類型學校,並在繼承FOSUserBundle原始表單類型的同時添加了一個額外的全名字段。

我也有一種奇怪的感覺,我沒有在我的代碼中正確解決或“布局”該關系,以使其更容易理解哪些對象相關。

任何幫助將非常感激! 另外,如果您需要其他代碼或更多信息,請告訴我。

在保留資源實體之前,您應該只能夠手動設置用戶。

  if ($newResourceForm->isValid()) {
    ...
    $resource->setCreatedBy($this->getUser());
    $em->persist($resource);
    $em->flush();
    ...
  }

Symfony利用了控制器中的$ this-> getUser()快捷方式(請參閱http://symfony.com/doc/current/book/security.html#retrieving-the-user-object )。 我假設您僅在用戶登錄后才允許此表單。

另外,如果您使用的是Doctrine,我建議您使用它來為您生成實體和getter / setter,因為它會生成與Symfony約定相稱的明智名稱。 例如,您的實體最終將被命名為“資源”與“資源”,變量將被駝峰化($ createdBy與$ created_by)。

好的,因此,根據傑森的建議以及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中傳遞當前用戶的整個對象,並且該關系可以正常工作。

再次謝謝大家!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM