2017-04-01 3 views
0

Ich habe einen User-Entity bekam definiert (Abbildung in yml)Doctrine2: persistierende Muttergesellschaft gegeben Kind Klasse

namespace My\CoreBundle\Entity; 

use Doctrine\ORM\Mapping as ORM; 

class User 
{ 

...

Und ich ein Kind Klasse geschaffen, die von diesem Unternehmen erbt, so dass ich einige benutzerdefinierte Validierungsmethoden und ein paar Felder hinzufügen können, die ich brauche, aber (zB ConfirmPassword, Confirmemail Felder)

namespace My\SecondBundle\EditModels; 

use My\CoreBundle\Entity\User; 

class UserModel extends User 
{ 

Wenn der Benutzer ein Anmeldeformular einreichen, nicht beibehalten werden muss ich map th Die Anfrage an eine UserModel-Entität, und wenn sie gültig ist, versuche ich, den Benutzer zu persistieren.

Der folgende Code löst eine Ausnahme

$entityManager->persist($userModel); 

//=>The class 'My\SecondBundle\EditModels\UserModel' was not found in the chain configured namespaces My\CoreBundle\Entity 

Frage: Wie kann ich anhalten $ userModel (Instanz UserModel) als User-Entity-Klasse? Mögliche Optionen:

  • Sie nicht eine vererbte Klasse verwenden und benutzerdefinierte Felder und Validierungsmethode für den Benutzer Entität selbst
  • Kopieren Sie die Felder aus der UserModel an die Benutzereinheit und bleiben die Benutzereinheit
hinzufügen

Ich glaube nicht, dass ich den Vererbungsmechanismus von Doctrine verwenden sollte, da ich die zusätzlichen Felder nicht speichern möchte.

Danke

Antwort

0

Ich denke, Ihr Problem hier ist, dass Sie nur My\CoreBundle\Entity Namespace in Doctrine2 konfiguriert haben, aber das Unternehmen Sie wollen tatsächlich in My\SecondBundle\EditModels befindet bestehen bleiben.

Wenn Klassen erben, die als @ORM\Entity() markiert sind, muss die Klasse, von der Sie sich erstrecken, normalerweise die Klassenanmerkung @ORM\MappedSuperclass() haben. Aber normalerweise verwenden Sie dies für einzelne Tabelle inhertiance, z. B. nicht für Ihren Anwendungsfall.

Meiner Meinung nach ist der Ansatz, um Datenbank bezogene Attribute von den anderen zu trennen, nicht erschwinglich. Ich würde validierungsbezogene Daten im Modell selbst aufbewahren - Sie benötigen sie in Ihrer Erstellungs-/Aktualisierungsaktion.

Ich bin nicht vertraut mit der XML-Konfiguration, aber wenn Sie Anmerkungen verwenden, müssen Sie jede Eigenschaft, die mit der Datenbank zugeordnet werden soll (mit @ORM\Column()) markieren. Doctrine ignoriert also alle anderen Attribute und Methoden vollständig.

Also hier ich meine vor kurzem entwickelte AbstractModel für Sie teilen, um zu sehen, wie ich die Validierung implementiert haben (mit respect/validation):

<?php 
namespace Vendor\Package\Model; 

use Doctrine\ORM\Mapping as ORM; 

/** 
* Abstract Model 
* 
* @ORM\MappedSuperclass() 
*/ 
abstract class AbstractModel 
{ 
    /** 
    * @var \Respect\Validation\Validator 
    */ 
    protected $validator; 

    /** 
    * AbstractModel constructor 
    */ 
    public function __construct() 
    { 
     $this->validator = static::validation(); 
    } 

    /** 
    * Defines validation for this model 
    * 
    * @return \Respect\Validation\Validator 
    */ 
    public static function validation() : \Respect\Validation\Validator 
    { 
     return \Respect\Validation\Validator::create(); 
    } 

    /** 
    * Executes validations, defined in validation method. 
    * 
    * @return bool 
    */ 
    public function isValid() : bool 
    { 
     if (is_null($this->validator)) { 
      $this->validator = new \Respect\Validation\Validator(); 
      $this->validation(); 
     } 
     return $this->validator->validate($this); 
    } 
} 

Ein Modell, das von der AbstractModel erstreckt muss eine statische Validate-Methode implementieren, Klasse Validierung zu definieren:

<?php 
namespace Vendor\Package\Model; 

use Doctrine\ORM\Mapping as ORM; 

/** 
* @ORM\Entity() 
* @ORM\Table(name="my_model") 
*/ 
class MyModel extends AbstractModel 
{ 
    /** 
    * @var string 
    * @ORM\Column(type="string") 
    */ 
    private $name; 

    /** 
    * Defines validation for this model 
    * 
    * @return \Respect\Validation\Validator 
    */ 
    public static function validation() : \Respect\Validation\Validator 
    { 
     return \Respect\Validation\Validator::create() 
      ->attribute('name', \Respect\Validation\Validator::notEmpty()->stringType()->length(null, 32)) 
      ; 
    } 
    // getter, setter, ... 
} 

Jede Einheit, beharrte auf Datenbank, haben das $validator Eigentum und all diese Methoden, sondern weil ich Anmerkungen hier links (und ziemlich sicher, dass dies funktioniert auch mit xml/yaml) Lehre ignoriert es.

Und auf diese Weise halten Sie auch Validierungsfragen aus der Modellklasse selbst heraus, was gut für die Lesbarkeit ist. Die Validierung selbst sollte im Modell selbst definiert werden, imho. Aber dieser Respekt/Validierungsrahmen ist ein guter Weg dies zu erreichen. Hoffe, das hilft :)

Verwandte Themen