2012-12-12 2 views
2

나는 아래 엔티티를 가지고 있습니다. 생성하는 동안 몇 가지 기본값을 설정하려고합니다. __construct에서 볼 수 있듯이 $name (문자열)을 쉽게 설정할 수 있지만 어떻게 $group을 설정할 수 있습니까? 이 빈약 한 디자인입니다Doctrine ORM 연결의 기본값

/** 
* @ORM\Entity 
*/ 
class Person { 
    private $id; 

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

    /** 
    * @ORM\ManyToOne(targetEntity="Group", inversedBy="persons") 
    * @ORM\JoinColumn(referencedColumnName="id") 
    */ 
    private $group; 

    public function setGroup(Group $group) 
    { 
     $this->group = $group; 
     $group->addPerson($this); 
    } 

    // ... setters/getters 

    //construct default Person 
    public function __construct() 
    { 
     $this->setName("Mike"); 
     $this->setGroup($EXISTING_GROUP_FROM_MY_DB); // <<-------------- 
    } 
} 
+0

나쁜 디자인. 이 컨트롤러에. – moonwave99

답변

3

나는 moonwave99 동의 (예를 들어 나는 id=122와 데이터베이스의 그룹이 있다는 것을 알고). 여기에서는 컨테이너를 인식하지 못하는 곳 (즉, Doctrine에 대해 알지 않아도되고 그렇게해서는 안 됨)에서 데이터베이스 (Doctrine 서비스를 통해)에 액세스하려고합니다.

나는 비슷한 문제가 최근에 발생했다. 그러나 나는이 논리가 컨트롤러 내부에 있기를 원하지 않았다. 그래서 나는 사용자 생성을 돌보는 서비스를 썼다. 그리고 나는 그 서비스가 필요한 유일한 다른 서비스 인 교리에 대한 액세스 권한을 부여했습니다.

namespace MyBundle\Entity; 

class UserFactory 
{ 
    private $doctrine; 

    public function __construct($doctrine) 
    { 
     $this->doctrine = $doctrine; 
    } 

    public function generateNewUser($email, $password) 
    { 
     $user = new User(); 

     // Since you have access to the Doctrine service, you can use $this->doctrine 
     // to do anything you would normally do in your controller with $this->getDoctrine() 
     $roles = $this->doctrine->getEntityManager()->getRepository("MyBundle:Role")->findAll(); 

     foreach ($roles as $role) 
     { 
      $user->addRole($role); 
     } 

     return $user; 
    } 
} 

지금 그것을 교리 서비스를 전달하는 기억, config.yml 또는 services.yml에서 해당 서비스를 등록 :

services: 
    mybundle.factory.user: 
     class: MyBundle\Entity\UserFactory 
     arguments: ['@doctrine'] 

여기

는 사용자가 사용할 수있는 모든 역할이 만들어집니다 예를의 그리고는 ... 자, 컨트롤러, 당신은 수행하여 새로운 사용자를 생성 할 수있다 :

public function MyController() 
{ 
    $user = $this->get("mybundle.factory.user")->generateNewUser("[email protected]", "password123"); 
} 
+0

tomtheman5, 고마워요! 나는 당신의 해결책을 좋아한다! – jhard

2

또 다른 방법은 엔티티의 라이프 사이클 콜백 또는 이벤트 리스너를 사용하여보다 복잡한 기능을 수행하는 것입니다.

use Doctrine\ORM\Event\LifecycleEventArgs; 
use Doctrine\ORM\Mapping as ORM; 

/** 
* @ORM\Entity 
* @ORM\HasLifecycleCallbacks 
*/ 
class Person 
{ 
    const DEFAULT_GROUP = '122'; 

    /** @ORM\Column(type="string") */ 
    private $name = 'Mike'; 

    /** 
    * @ORM\ManyToOne(targetEntity="Group", inversedBy="persons") 
    * @ORM\JoinColumn(referencedColumnName="id") 
    */ 
    private $group = self::DEFAULT_GROUP; 

    //.... 

    public function setGroup(Group $group) 
    { 
     $this->group = $group; 
     $group->addPerson($this); 
    } 

    /** 
    * @param LifecycleEventArgs $event 
    * @ORM\PrePersist 
    */ 
    public function onPrePersist(LifecycleEventArgs $event) 
    { 
     if (!$this->group instanceof Group) { 
      /** set default group if not specified */ 
      $group = $event->getEntityManager()->find('MyBundle:Group', $this->group ?: self::DEFAULT_GROUP); 
      $this->setGroup($group); 
     } 
    } 

} 

이제 당신은 명시 적으로 컨트롤러에 설정되지 않은 경우는 그룹을 추가하는 사람의 실체를 계속 될 경우. 정신 들어

$person = new Person; 
echo $person->getName(); //outputs: Mike 
$person->setName('Foo Bar'); 
$em->persist($person); //persist or do nothing if already persisted 
$group = $person->getGroup(); 
$groupPerson = $group->getPerson(); 
echo $group->getId(); //outputs: 122 
echo $groupPerson->getName(); //outputs: Foo Bar 
$em->flush(); //save to database 

여기 교리 이벤트에 대한 문서에 대한 링크입니다 :