symfony3 当我坚持一篇新文章时,user_id 外键在我的文章 table 中保持为空

symfony3 when I persist a new article, the user_id foreign key stay null in my article table

我说明一下我的情况:

我有两个实体,一个叫做 "User" fosuserBundle handle,另一个叫做 "Article"。我希望在创建新文章时也保留外键 "fosUserId"。

这是我的用户实体:

<?php

namespace AppBundle\Entity;

use ArticleBundle\Entity\Article;
use Doctrine\Common\Collections\ArrayCollection;
use FOS\UserBundle\Model\User as BaseUser;
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 * @ORM\Table(name="fos_user")
 */
class User extends BaseUser
{
    /**
     * @ORM\OneToMany(targetEntity="ArticleBundle\Entity\Article", mappedBy="fosUserId")
     */
    private $articles;

    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    public function __construct()
    {
        parent::__construct();
        $this->articles = new ArrayCollection();
    }

    /**
     * Set $articles
     *
     *@Param array $articles
     *
     * Return User
     */
    public function setArticles($articles)
    {
        $this->articles = $articles;
    }

    /**
     * Get articles
     *
     * @return array
     */
    public function getArticles()
    {
        return array('articles' => $this->articles);
    }

    /**
     * Add article
     *
     * @param \ArticleBundle\Entity\Article $article
     *
     * @return User
     */
    public function addArticle(\ArticleBundle\Entity\Article $article)
    {
        $this->articles[] = $article;

        return $this;
    }

    /**
     * Remove article
     *
     * @param \ArticleBundle\Entity\Article $article
     */
    public function removeArticle(\ArticleBundle\Entity\Article $article)
    {
        $this->articles->removeElement($article);
    }
}

这是我的文章实体:

<?php

namespace ArticleBundle\Entity;

use AppBundle\Entity\User;
use Doctrine\ORM\Mapping as ORM;

/**
 * Article
 *
 * @ORM\Table(name="article")
 * @ORM\Entity(repositoryClass="ArticleBundle\Repository\ArticleRepository")
 */
class Article
{
    /**
     * @var int
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @ORM\ManyToOne(targetEntity="AppBundle\Entity\User", inversedBy="articles", cascade={"persist"})
     * @ORM\JoinColumn(name="fosUserId", referencedColumnName="id")
     */
    private $fosUserId;

    /**
     * @var string
     *
     * @ORM\Column(name="name", type="string", length=255)
     */
    private $name;

    /**
     * @var string
     *
     * @ORM\Column(name="category", type="string", length=255)
     */
    private $category;

    /**
     * @var string
     *
     * @ORM\Column(name="brand", type="string", length=255)
     */
    private $brand;

    /**
     * @var string
     *
     * @ORM\Column(name="model", type="string", length=255)
     */
    private $model;

    /**
     * @var bool
     *
     * @ORM\Column(name="gender", type="boolean")
     */
    private $gender;

    /**
     * @var string
     *
     * @ORM\Column(name="description", type="text", nullable=true)
     */
    private $description;

    /**
     * @var int
     *
     * @ORM\Column(name="quantity", type="integer")
     */
    private $quantity;

    /**
     * @var int
     *
     * @ORM\Column(name="price", type="integer")
     */
    private $price;

    /**
     * @var string
     *
     * @ORM\Column(name="imageFile", type="string", length=255)
     */
    private $imageFile;

    /**
     * @var \DateTime
     *
     * @ORM\Column(name="added", type="datetime")
     */
    private $added;

    /**
     * @var \DateTime
     *
     * @ORM\Column(name="updated", type="datetime", nullable=true)
     */
    private $updated;

    /**
     * @var \DateTime
     *
     * @ORM\Column(name="deleted", type="datetime", nullable=true)
     */
    private $deleted;

    /**
     * @var \DateTime
     *
     * @ORM\Column(name="sold", type="datetime", nullable=true)
     */
    private $sold;

    /**
     * Get id
     *
     * @return int
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Set fosUserId
     *
     * Return integer
     */
    public function setFosUserId($fosUserId)
    {
        $this->fosUserId = $fosUserId;

        return $this;
    }

    /**
     * Get fosUserId
     *
     * Return Article
     */
    public function getFosUserId()
    {
        return $this->fosUserId;
    }

    /**
     * Set name
     *
     * @param string $name
     *
     * @return Article
     */
    public function setName($name)
    {
        $this->name = $name;

        return $this;
    }

    /**
     * Get name
     *
     * @return string
     */
    public function getName()
    {
        return $this->name;
    }

    /**
     * Set category
     *
     * @param string $category
     *
     * @return Article
     */
    public function setCategory($category)
    {
        $this->category = $category;

        return $this;
    }

    /**
     * Get category
     *
     * @return string
     */
    public function getCategory()
    {
        return $this->category;
    }

    /**
     * Set brand
     *
     * @param string $brand
     *
     * @return Article
     */
    public function setBrand($brand)
    {
        $this->brand = $brand;

        return $this;
    }

    /**
     * Get brand
     *
     * @return string
     */
    public function getBrand()
    {
        return $this->brand;
    }

    /**
     * Set model
     *
     * @param string $model
     *
     * @return Article
     */
    public function setModel($model)
    {
        $this->model = $model;

        return $this;
    }

    /**
     * Get model
     *
     * @return string
     */
    public function getModel()
    {
        return $this->model;
    }

    /**
     * Set gender
     *
     * @param boolean $gender
     *
     * @return Article
     */
    public function setGender($gender)
    {
        $this->gender = $gender;

        return $this;
    }

    /**
     * Get gender
     *
     * @return bool
     */
    public function getGender()
    {
        return $this->gender;
    }

    /**
     * Set description
     *
     * @param string $description
     *
     * @return Article
     */
    public function setDescription($description)
    {
        $this->description = $description;

        return $this;
    }

    /**
     * Get description
     *
     * @return string
     */
    public function getDescription()
    {
        return $this->description;
    }

    /**
     * Set quantity
     *
     * @param integer $quantity
     *
     * @return Article
     */
    public function setQuantity($quantity)
    {
        $this->quantity = $quantity;

        return $this;
    }

    /**
     * Get quantity
     *
     * @return int
     */
    public function getQuantity()
    {
        return $this->quantity;
    }

    /**
     * Set price
     *
     * @param integer $price
     *
     * @return Article
     */
    public function setPrice($price)
    {
        $this->price = $price;

        return $this;
    }

    /**
     * Get price
     *
     * @return int
     */
    public function getPrice()
    {
        return $this->price;
    }

    /**
     * Set imageFile
     *
     * @param string $imageFile
     *
     * @return Article
     */
    public function setImageFile($imageFile)
    {
        $this->imageFile = $imageFile;

        return $this;
    }

    /**
     * Get imageFile
     *
     * @return string
     */
    public function getImageFile()
    {
        return $this->imageFile;
    }

    /**
     * Set added
     *
     * @param \DateTime $added
     *
     * @return Article
     */
    public function setAdded($added)
    {
        $this->added = $added;

        return $this;
    }

    /**
     * Get added
     *
     * @return \DateTime
     */
    public function getAdded()
    {
        return $this->added;
    }

    /**
     * Set updated
     *
     * @param \DateTime $updated
     *
     * @return Article
     */
    public function setUpdated($updated)
    {
        $this->updated = $updated;

        return $this;
    }

    /**
     * Get updated
     *
     * @return \DateTime
     */
    public function getUpdated()
    {
        return $this->updated;
    }

    /**
     * Set deleted
     *
     * @param \DateTime $deleted
     *
     * @return Article
     */
    public function setDeleted($deleted)
    {
        $this->deleted = $deleted;

        return $this;
    }

    /**
     * Get deleted
     *
     * @return \DateTime
     */
    public function getDeleted()
    {
        return $this->deleted;
    }

    /**
     * Set sold
     *
     * @param \DateTime $sold
     *
     * @return Article
     */
    public function setSold($sold)
    {
        $this->sold = $sold;

        return $this;
    }

    /**
     * Get sold
     *
     * @return \DateTime
     */
    public function getSold()
    {
        return $this->sold;
    }
}

这是我的表单类型文章类型:

<?php

namespace ArticleBundle\Form\Type;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\FileType;
use Symfony\Component\Form\Extension\Core\Type\IntegerType;
use Symfony\Component\Form\Extension\Core\Type\MoneyType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;

class ArticleType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('name', TextType::class)
            ->add('category', TextType::class)
            ->add('brand', TextType::class)
            ->add('model', TextType::class)
            ->add('gender', ChoiceType::class, array(
                'choices'  => array(
                    'Male' => true,
                    'Female' => false,
                )
            ))
            ->add('description', TextareaType::class)
            ->add('quantity', IntegerType::class)
            ->add('price', MoneyType::class)
            ->add('imageFile', FileType::class)
            ->add('submit', SubmitType::class)
        ;
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'ArticleBundle\Entity\Article'
        ));
    }

    public function getBlockPrefix()
    {
        return 'articlebundle_article';
    }


}

最后是我的 ArticleController :

<?php

namespace ArticleBundle\Controller;

use ArticleBundle\Entity\Article;
use ArticleBundle\Form\Type\ArticleType;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;

class ArticleController extends Controller
{
    /**
     * @Route("/add", name="add")
     */
    public function addArticle(Request $request)
    {
        $article = new Article();

        $form = $this->createForm(ArticleType::class, $article);
        $form->handleRequest($request);

        if ($form->isSubmitted() && $form->isValid()) {
            $article->setFosUserId($this->getUser());
            $article->setAdded(\DateTime::createFromFormat('Y-m-d H:i:s', date('Y-m-d H:i:s')));

            $em = $this->getDoctrine()->getManager();
            $em->persist($article);
            $em->flush();

            return $this->render('article/add.html.twig', [
                'form' => $form->createView(),
            ]);
        }
        return $this->render('article/add.html.twig', [
            'form' => $form->createView(),
        ]);
    }
}

我的问题是,当我刷新实体管理器 ($em->flush) 时,它在我的数据库中记录了我的 Article 对象,但没有 fosUserId 作为显示 NULL 的外键。

你的建议对我帮助很大。 谢谢

好的,我想我找到了问题,但这很奇怪,因为你应该有一个错误。我不确定您是否激活了错误显示。

但是,问题就在这里,你设置了一个不存在的属性:

public function setFosUserId($fosUserId)
{
    $this->user = $fosUserId; // Wrong attribute

    return $this;
}

而不是:

public function setFosUserId($fosUserId)
{
    $this->fosUserId = $fosUserId; // Right attribute

    return $this;
}

您需要更改几项内容。

首先,正如@YaatSuka 在 his/her 回答中所建议的,您的 AppBundle\User-Entity 在 setFosUserId 函数中有一个错误:

public function setFosUserId($fosUserId)
{
    $this->user = $fosUserId; // Should be: $this->fosUserId = $fosUserId;

    return $this;
}

第二: 在您的 Controller 中,您只是获取用户的 ID,而您应该使用实体:

$user = $this->container->get('security.token_storage')->getToken()->getUser()->getId();

应该是:

$user = $this->container->get('security.token_storage')->getToken()->getUser();

或者,由于您继承了基本的 Symfony 控制器:

$user = $this->getUser();

最后,虽然这不应该影响错误: 您根本不需要将 fosUerId 字段添加到表单中,因为您是在控制器中设置它的。

意思是:你可以去掉FormType中的隐藏字段。