Symfony实体validationvalidation外键是否存在

我希望能够使用实体validation器约束来validation外键book_id是否有效,请参阅下面的内容:

book.php中

/** * Book * * @ORM\Table("book") * @ORM\Entity * @ORM\Entity(repositoryClass="AppBundle\Repository\BookRepository") */ class Book { /** * @var integer * @ORM\Column(name="id", type="integer") * @ORM\Id * @ORM\GeneratedValue(strategy="AUTO") */ private $id; /** * @var string * @ORM\Column(name="name", type="string") * @Assert\Length( * max = 250, * maxMessage = "Name cannot be longer than {{ limit }} characters", * groups={"create","update"} * ) */ private $name; /** * @ORM\OneToOne(targetEntity="Loan", mappedBy="book", fetch="LAZY") */ protected $loan; } 

Loan.php

 /** * Loan * * @ORM\Table("loan") * @ORM\Entity * @ORM\Entity(repositoryClass="AppBundle\Repository\LoanRepository") */ class Loan { /** * @var integer * @ORM\Column(name="id", type="integer") * @ORM\Id * @ORM\GeneratedValue(strategy="AUTO") */ private $id; /** * @var integer * @ORM\Column(name="book_id", type="integer") */ protected $book_id; /** * @var string * @ORM\Column(name="name", type="string") * @Assert\Length( * max = 500, * maxMessage = "Person cannot be longer than {{ limit }} characters", * groups={"create","update"} * ) */ private $person; /** * @ORM\OneToOne(targetEntity="Book", inversedBy="loan") * @ORM\JoinColumn(name="book_id", referencedColumnName="id") */ protected $book; } 

这是我目前如何validation贷款实体

  $loan = new Loan(); $loan->setPerson($person); $loan->setBookId($id); /** @var ConstraintViolation $error */ foreach ($this->get('validator')->validate($loan,null,['create'])->getIterator() as $index => $error) { $errorMessages[] = $error->getMessage(); } 

我想也许我可以添加一个像这样的自定义validation器到贷款实体:

 /** * @Assert\IsTrue(message = "The book does not exist") * @return bool */ public function isBookLegal(BookRepository $bookRepository) { return !$bookRepository->fetchById($this->book_id); } 

但是我最终得出的例外是:

 Type error: Too few arguments to function AppBundle\Entity\Loan::isBookLegal(), 0 passed and exactly 1 expected 

首先,你的Loan实体中不应该有$book_id$book 。 你应该删除$book_id ,这对于你的实体关系是足够的。

然后,所有你需要做的是在$book上添加一个@Assert\NotBlank()

 use Symfony\Component\Validator\Constraints as Assert; ... /** * @ORM\OneToOne(targetEntity="Book", inversedBy="loan") * @ORM\JoinColumn(name="book_id", referencedColumnName="id") * @Assert\NotBlank() */ protected $book; 

我不确定你用什么代码来获得所有的贷款,但埃德温说,这不是一个好的forms。 你想要的东西更像是:

 foreach ($loans as $loan) { $errors = $this->get('validator')->validate($loan); // do something here if there is an error } 

你写的断言函数是不行的,因为你不能在你的isBookLegal()函数中传递一个值,你isBookLegal()在你的Entity类中使用数据库连接/存储库。

如果没有更多的背景,我不确定你想要完成什么。 Doctrine已经开始validation你的$book成员了,因为你的@ORM\OneToOne注解在第一位。 您不必执行任何额外的validation。 我猜你正在尝试直接将值传递给$book_id ,这是不正确的。 您只应通过$loan->setBook(Book $book);将已经有效的$book实体传递给您的Loan$loan->setBook(Book $book);