2017-06-29 3 views
2

Ich möchte in der Lage sein Entity Validator Einschränkungen zu verwenden, um zu überprüfen, ob der Fremdschlüssel book_id gültig ist, finden Sie unter:Symfony Einheit Validierung Fremdschlüssel überprüfen existiert

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; 
} 

Hier ist, wie ich zur Zeit das Darlehen Unternehmen am Validieren

$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(); 
    } 

Ich dachte, vielleicht kann ich einen benutzerdefinierten Validator wie dies für das Darlehen Unternehmen hinzufügen:

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

Aber ich mit der Folge Ausnahme am Ende:

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

übergeben zuerst den ersten Parameter von der Foreach zu einer Variablen zuweisen und dann in foreach verwenden, das ist nur böse. Zweitens, wenn Sie Ihr 'iBookLegal' anrufen, rufen Sie es ohne Parameter auf - deshalb erhalten Sie diese Nachricht. – Edwin

+0

Aber wie kann ich isBookLegal aufrufen, wenn es über validate ausgelöst wird? Mit anderen Worten, wie kann ich validieren, um den Parameter in diese Funktion zu übergeben? – Freid001

Antwort

2

Zunächst einmal sollten Sie nicht haben sowohl $book_id als auch $book in Ihrer Loan Einheit. Sie sollten $book_id entfernen, was für Ihre Entitätsbeziehung ausreicht.

Dann alles, was Sie tun müssen, ist fügen Sie ein @Assert\NotBlank() auf $book:

use Symfony\Component\Validator\Constraints as Assert; 

... 

/** 
    * @ORM\OneToOne(targetEntity="Book", inversedBy="loan") 
    * @ORM\JoinColumn(name="book_id", referencedColumnName="id") 
    * @Assert\NotBlank() 
    */ 
protected $book; 

Ich bin nicht sicher, welchen Code Sie verwenden alle Ihre Kredite zu bekommen, aber als Edwin Staaten das ist nicht wirklich gut bilden. Sie wollen wollen etwas mehr wie:

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

Die Assertionsfunktion Sie schrieb nicht funktionieren wird, weil man dort nicht in einem Wert Ihrer isBookLegal() Funktion übergeben kann, nicht können Sie immer die Datenbankverbindung/Repository verwenden aus Ihrer Entity-Klasse heraus.

Ich bin nicht wirklich sicher, was Sie ohne größeren Kontext hier erreichen möchten. Doctrine wird Ihr $book Mitglied aufgrund Ihrer @ORM\OneToOne Annotation in erster Linie bereits validieren. Sie müssen keine zusätzliche Validierung durchführen. Ich schätze, Sie versuchen, einen Wert direkt an $book_id zu übergeben, was falsch ist. Sie sollten nur bereits gültige $book Entitäten an Ihre Loan Klasse über $loan->setBook(Book $book);

+0

Danke für die Detailantwort, ich denke, ich verstehe nicht, wie Doktrin-Entity-Beziehungen funktionieren. Wenn ich book_id entferne, was sollte ich als Name in diesem setzen: @ORM \ JoinColumn (name = "book_id", referenzierteColumnName = "id") – Freid001

+0

Oh ich denke ich sehe jetzt. Daher muss ich book_id nicht implizit als Klasseneigenschaft festlegen, da doctrine herausfinden wird, dass sie diese Spalte wie angegeben hinzufügen muss. – Freid001

+0

Das ist richtig. Überprüfen Sie dies auch hier: http://symfony.com/doc/current/doctrine/reverse_engineering.html Sie können Doctrine automatisch alle Ihre Entitäten für Sie generieren lassen, wenn Ihre Datenbank bereits erstellt wurde. –

Verwandte Themen