2016-08-25 1 views
-3

Nach einigen Stunden versuchen zu verstehen, kann ich das Konzept nicht klar. Ich habe drei Einheiten definiert, wie gezeigt:Doktrin Entities Relations verwirrend

class Countries 
{ 
    /** 
    * @var int 
    * 
    * @ORM\Column(name="id", type="integer") 
    * @ORM\Id 
    * @ORM\GeneratedValue(strategy="AUTO") 
    */ 
    private $id; 

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

    /** 
    * @ORM\OneToMany(targetEntity="Regions", mappedBy="country_id") 
    */ 
    private $regions_in_country; 

    /** 
    * @ORM\OneToMany(targetEntity="Cities", mappedBy="country_id") 
    */ 
    private $cities_in_country; 

    public function __construct() { 
     $this->regions_in_country= new ArrayCollection(); 
     $this->cities_in_country= new ArrayCollection(); 
    } 
} 

class Regions 
{ 
    /** 
    * @var int 
    * 
    * @ORM\Column(name="id", type="integer") 
    * @ORM\Id 
    * @ORM\GeneratedValue(strategy="AUTO") 
    */ 
    private $id; 

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

    /** 
    * @var int 
    * 
    * @ORM\Column(name="country_id", type="integer") 
    * @ORM\ManyToOne(targetEntity="Countries", inversedBy="regions") 
    * @ORM\JoinColumn(name="country_id", referencedColumnName="id") 
    */ 
    private $countryId; 

    /** 
    * @ORM\OneToMany(targetEntity="Cities", mappedBy="region_id") 
    */ 
    private $cities_in_region; 

    public function __construct() { 
     $this->cities_in_region= new ArrayCollection(); 
    } 
} 

class Cities 
{ 
    /** 
    * @var int 
    * 
    * @ORM\Column(name="id", type="integer") 
    * @ORM\Id 
    * @ORM\GeneratedValue(strategy="AUTO") 
    */ 
    private $id; 

    /** 
    * @var int 
    * 
    * @ORM\Column(name="country_id", type="integer") 
    * @ORM\ManyToOne(targetEntity="Countries", inversedBy="cities_in_country") 
    * @ORM\JoinColumn(name="country_id", referencedColumnName="id") 
    */ 
    private $countryId; 

    /** 
    * @var int 
    * 
    * @ORM\Column(name="region_id", type="integer") 
    * @ORM\ManyToOne(targetEntity="Regions", inversedBy="cities_in_region") 
    * @ORM\JoinColumn(name="region_id", referencedColumnName="id") 
    */ 
    private $regionId; 

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

Das Problem ist, dass der Profiler sagt:

AppBundle\Entity\Regions  

The association AppBundle\Entity\Regions#cities_in_region refers to 
the owning side field AppBundle\Entity\Cities#region_id which does not exist. 

Aber das Feld region_id in AppBundle \ Entity \ Städte existieren !!

Irgendwelche Vorschläge?

EDITED: Dank Rafix und Alvin für die Konzepte. Ich bin neu in Doctrine/Symfony und manchmal ...

In der Tat, was ich tun möchte, ist in einem Formular eine Auswahl mit einem CountryType-Feld verwenden, die Sache ist, dass es code_2a als Werte verwendet.

In meinen Entitäten, wie user_profile, werde ich ein Feld Land mit dem 'Code_2a', OneToOne zu der Entität Land haben und dieses Feld dann in der Entität Region verwenden. Das bedeutet, dass die Country-Entität ein Feld "code_2a" OneToMany haben wird, das auf die Regions-Entity zeigt, die einen 'code_2a' ManyToOne hat, der auf Land umkehrt. Weil sie nicht "id" sind, frage ich mich, wie es geht. Es gibt keine Beispiele dafür, wie das geht.

Antwort

0

Die Klassen können wie mein Beispiel unten erstellt werden. Ich habe dies auf @rafix 's Antwort basiert, aber es gab einige Probleme.

Auch haben Sie nicht haben, um Ihre Klassen in der Einzahl wie @rafix angegeben, können Sie sie benennen, wie Sie wollen. Aber es ist viel praktischer, es so zu machen und Ihren Code viel einfacher zu lesen und zu unterstützen.

Zum Beispiel: Wenn Sie eine Klasse namens "Land" haben, dann wissen Sie, dass ein Land "Städte" hat und jede dieser "Städte" eine "Stadt" ist. Die Klasse bezieht sich also auf das einzelne Objekt. Hier

ist die Änderungen, die ich vorschlagen:

class Country 
{ 
    /** 
    * @ORM\Column(name="country_id", type="integer") 
    * @ORM\Id 
    * @ORM\GeneratedValue(strategy="AUTO") 
    */ 
    private $country_id; 

    /** 
    * @ORM\Column(name="flag", type="string", length=100, nullable=true) 
    */ 
    private $flag; 

    /** 
    * @ORM\OneToMany(targetEntity="Region", mappedBy="country") 
    */ 
    private $regions = null; 

    public function __construct() { 
     $this->regions = new ArrayCollection(); 

    } 
} 

class Region 
{ 
    /** 
    * @ORM\Column(name="region_id", type="integer") 
    * @ORM\Id 
    * @ORM\GeneratedValue(strategy="AUTO") 
    */ 
    private $region_id; 

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

    /** 
    * @ORM\ManyToOne(targetEntity="Country", inversedBy="regions") 
    * @ORM\JoinColumn(name="region_country_id", referencedColumnName="country_id") 
    */ 
    private $country; 

    /** 
    * @ORM\OneToMany(targetEntity="City", mappedBy="region") 
    */ 
    private $cities = null; 

    public function __construct() { 
     $this->cities = new ArrayCollection(); 
    } 
} 

class City 
{ 
    /** 
    * @ORM\Column(name="city_id", type="integer") 
    * @ORM\Id 
    * @ORM\GeneratedValue(strategy="AUTO") 
    */ 
    private $city_id; 

    /** 
    * @ORM\ManyToOne(targetEntity="Region", inversedBy="cities") 
    * @ORM\JoinColumn(name="region_id", referencedColumnName="region_id") 
    */ 
    private $region; 

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

Hinweis, ich jedes der "id" s in jeder der Klassen umbenannt, damit Sie wissen würde dass es die ID für diese bestimmte Entität ist. Zum Beispiel: Die Country-Klasse hat eine "country_id".

Da zum Beispiel die Country-Klasse "Regionen" hat, müssen Sie das Array als "null" deklarieren. Stellen Sie sicher, dass Sie über die richtigen addRegion verfügen, um Regionen zu dem Array hinzuzufügen, wenn Sie Ihren Code abschließen.

1

Sie können das Id-Suffix in den Entitätsfeldern vermeiden, und Sie müssen die Entitätsklassen im Singular benennen.

class Country 
{ 
    /** 
    * @var int 
    * 
    * @ORM\Column(name="id", type="integer") 
    * @ORM\Id 
    * @ORM\GeneratedValue(strategy="AUTO") 
    */ 
    private $id; 

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

    /** 
    * @ORM\OneToMany(targetEntity="Region", mappedBy="country") 
    */ 
    private $regions; 

    public function __construct() { 
     $this->regions = new ArrayCollection(); 

    } 
} 
class Region 
{ 
    /** 
    * @var int 
    * 
    * @ORM\Column(name="id", type="integer") 
    * @ORM\Id 
    * @ORM\GeneratedValue(strategy="AUTO") 
    */ 
    private $id; 

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

    /** 
    * @var int 
    * 
    * @ORM\ManyToOne(targetEntity="Country", inversedBy="regions") 
    * @ORM\JoinColumn(name="country_id", referencedColumnName="id") 
    */ 
    private $country; 

    /** 
    * @ORM\OneToMany(targetEntity="City", mappedBy="region") 
    */ 
    private $cities; 

    public function __construct() { 
     $this->cities = new ArrayCollection(); 
    } 
} 
class City 
{ 
    /** 
    * @var int 
    * 
    * @ORM\Column(name="id", type="integer") 
    * @ORM\Id 
    * @ORM\GeneratedValue(strategy="AUTO") 
    */ 
    private $id; 

    /** 
    * @var int 
    * 
    * @ORM\ManyToOne(targetEntity="Region", inversedBy="cities") 
    * @ORM\JoinColumn(name="region_id", referencedColumnName="id") 
    */ 
    private $region; 

    /** 
    * @var string 
    * 
    * @ORM\Column(name="name", type="string", length=100) 
    */ 
    private $name; 
} 
+0

Ist es möglich, dass das Attribut $ region in der City-Entity in Ihrem Code keine Spaltendefinition hat? Das gleiche gilt für $ country in Region. Ist es ein Tippfehler? Mit den Definitionen von Spalte bekomme ich: Die Assoziation AppBundle \ Entity \ Region # Städte bezieht sich auf die besitzende Seite AppBundle \ Entity \ City # Region, die nicht als Assoziation, sondern als Feld definiert ist. Die Assoziation AppBundle \ Entity \ Region # cities verweist auf das besitzende Seitenfeld AppBundle \ Entity \ City # region, das nicht existiert. – Carlos

+0

Jetzt sehe ich meinen Fehler, Danke rafix. Nein, Sie haben keinen Tippfehler begangen. Die M-t-O-Spalten müssen JoinColumn sein, das ist der Schlüssel. Hoffe das hilft. – Carlos