Проблема осмысления доктрины 2 - PullRequest
0 голосов
/ 18 июня 2011

Мне трудно понять, как правильно использовать Doctrine 2 с Zend Framework.Я читаю документы и основываюсь на том, что я уже сделал, и на zendcasts .Проблемы на самом деле начинаются, когда я пытаюсь делать реляционные вещи с моей базой данных, так как я не очень уверен, как использовать коллекции доктрин.В моем тестовом примере у меня есть сущность User:

class User 
{
/**
 * @var integer
 * @Column (name="id", type="integer", nullable=false)
 * @Id
 * @GenerateValue(strategy="IDENTIY")
 * 
 */
private $id;

/**
 * @Column(type="string",length=60,nullable=true)
 * @var string
 */
private $email;

/**
 * 
 * @param \Doctring\Common\Collections\Collection $property
 * @OneToMany(targetEntity="Countries",mappedBy="user", cascade={"persist", "remove"})
 */
private $countries;

public function __get($property) 
{
    return $this->$property;
}

public function __set($property, $value)
{
    $this->$property = $value;
}
}

, которая связана с сущностью стран:

class Countries {
/**
 * @var integer
 * @Column (name="id", type="integer", nullable=false)
 * @Id
 * @GenerateValue(strategy="IDENTIY")
 * 
 */
private $id;

/**
 *
 * @var string
 * @Column(type="string") 
 */
private $countryName;

/**
 *
 * @var User
 * @ManyToOne(targetEntity="User") 
 * @JoinColumns({
 *  @JoinColumn(name="user_id", referencedColumnName="id")
 * })
 */
private $user;


public function __get($property) 
{
    return $this->$property;
}

public function __set($property, $value)
{
    $this->$property = $value;
}
}

Теперь я могу присвоить странам из контроллера что-то вроде этого:

    $p1 = new \Federico\Entity\Countries();
    $p1->countryName = 'Argentina';
    $p2 = new \Federico\Entity\Countries();
    $p2->countryName = 'España';
    $u = new \Federico\Entity\User();
    $u->firstname = 'John';
    $u->lastname = 'Doe';
    $u->id = 1;

, который покажет мне этот объект:

object(Federico\Entity\User)[109]
  private 'id' => int 1
  private 'email' => null
  private 'countries' => 
array
  0 => 
    object(Federico\Entity\Countries)[107]
      private 'id' => null
      private 'countryName' => string 'Argentina' (length=9)
      private 'user' => null
  1 => 
    object(Federico\Entity\Countries)[108]
      private 'id' => null
      private 'countryName' => string 'España' (length=7)
      private 'user' => null
  public 'firstname' => string 'John' (length=4)
  public 'lastname' => string 'Doe' (length=3)

Если вы обратите на это внимание, вы увидите, что свойство user установлено в null в объектах страны.Я не понимаю, должно ли это происходить так или нет.Кроме того, поскольку пользователям будет разрешено выбирать страны из списка флажков, и они смогут выбирать более одной страны, ... не должны ли страны каким-либо образом храниться в БД?

Ответы [ 2 ]

0 голосов
/ 22 июня 2011

В доктрине 2 использование магических добытчиков и сеттеров не рекомендуется.Как вы можете видеть, они могут вызвать проблемы для управления ассоциациями.Ниже приведен пример того, как управлять ассоциацией, которая у вас есть в вашей пользовательской сущности.

namespace Whatever/Your/Namespace/Is;

use \Doctrine\Common\ArrayCollection;

class User
{
    /**
     * @Column (type="integer")
     * @Id
     * @var integer
     */
     private $id;

     /**
      * @OneToMany(targetEntity="Country", mappedBy="user", cascade={"persist", "remove"})
      * @var ArrayCollection
     private $countries;

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

     public function getCountries()
     {
         return $this->countries;
     }

     public function setCountry(Country $country)
     {
         $this->country[] = $country;
         $country->setUser($this);
         return $this;
     }

     public function removeCountry(Country $country)
     {
         return $this->country->removeElement($country);
     }
}

и для страны

class Country
{
    /**
     * @Id
     * @Column(type="integer")
     * @var integer
     */
    private $id;

    /**
     * @Column(length=100)
     * @var string
     */
    private $country_name;

    /**
     * @ManyToOne(targetEntity="User", inversedBy="countries")
     * @var User
     */
    private $user;

    public function setUser(User $user)
    {
        $this->user = $user;
        return $this;
    }

    public function getUser()
    {
        return $this->user;
    }

    // ...
}
0 голосов
/ 18 июня 2011

Я не вижу, где вы назначаете страну пользователю в вашем коде.В любом случае вам нужно сделать две вещи:

Инициализировать переменную $countries как новую Doctrine\Common\Collections\ArrayCollection в конструкторе User.

Вручную связать страну с пользователем:

public function addCountry(Country $c)
{
  if (!$this->countries->contains($c)) {
    $this->countries->add($c);
    $c->user = $user;
  }
}
...