2012-04-26 7 views
31

回答が見つからないため、回答が見つかりません。 私のアプリケーションにデータベースロールモデルがあります。ユーザーは役割を持つことができますが、この役割はデータベースに格納する必要があります。エンティティの中でsymfony 2.0サービスを取得しています

しかし、ユーザーはデータベースからデフォルトロールを追加する必要があります。だから私は、サービスを作成しました:

alef.role_service: 
    class: Alef\UserBundle\Service\RoleService 
    arguments: [%doctrine.orm.entity_manager%] 

そして今、私は2つの場所でそれを使用したい:

<?php 

namespace Alef\UserBundle\Service; 

use Alef\UserBundle\Entity\Role; 

/** 
* Description of RoleService 
* 
* @author oracle 
*/ 
class RoleService { 

    const ENTITY_NAME = 'AlefUserBundle:Role'; 

    private $em; 

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

    public function findAll() 
    { 
     return $this->em->getRepository(self::ENTITY_NAME)->findAll(); 
    } 

    public function create(User $user) 
    { 
     // possibly validation here 

     $this->em->persist($user); 
     $this->em->flush($user); 
    } 

    public function addRole($name, $role) { 
     if (($newrole = findRoleByRole($role)) != null) 
      return $newrole; 
     if (($newrole = findRoleByName($name)) != null) 
      return $newrole; 

     //there is no existing role 
     $newrole = new Role(); 
     $newrole->setName($name); 
     $newrole->setRole($role); 

     $em->persist($newrole); 
     $em->flush(); 

     return $newrole; 
    } 

    public function getRoleByName($name) { 
     return $this->em->getRepository(self::ENTITY_NAME)->findBy(array('name' => $name)); 
    } 

    public function getRoleByRole($role) { 
     return $this->em->getRepository(self::ENTITY_NAME)->findBy(array('role' => $role)); 
    } 

} 

services.ymlはあり UserControllerUserエンティティ。どのようにしてそれらをエンティティの中に入れられますか?

$this->get('alef.role_service'); 

しかし、どのようにエンティティ内のサービスを受けるために:私はちょうどに必要だと思うコントローラ用として ?

答えて

41

あなたはしていません。これは非常によくある質問です。エンティティは、他のエンティティについてのみ知っているべきであり、エンティティマネージャまたは他の高レベルサービスについては知っていないはずです。このような開発方法への移行は少し難題かもしれませんが、通常はそれに値するでしょう。

あなたがしたいのは、ユーザーを読み込むときに役割を読み込むことです。通常、この種のことをするUserProviderで終了します。あなたはセキュリティのセクションを読んだことがありますか?それはあなたの出発点でなければなりません:それはエンティティへのサービスを得ることは非常に落胆だが

http://symfony.com/doc/current/book/security.html

13

は、グローバルなカーネルをいじって関与していない、それを行うための良い方法があります。

Doctrineエンティティには、イベントリスナーをフックできるlifeCycleイベントがあります(http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/events.html#lifecycle-eventsを参照してください)。例のために、私はエンティティが作成された直後にトリガするpostLoadを使用します。

イベントリスナーは、他のサービスを注入するサービスとして作成することができます。

追加するアプリ/設定/ config.yml:

services: 
    example.listener: 
      class: Alef\UserBundle\EventListener\ExampleListener 
    arguments: 
      - '@alef.role_service' 
    tags: 
      - { name: doctrine.event_listener, event: postLoad } 

はあなたのエンティティに追加します。

use Alef\UserBundle\Service\RoleService; 

private $roleService; 

public function setRoleService(RoleService $roleService) { 
     $this->roleService = $roleService; 
} 

また、新しいイベントリスナーを追加します

namespace Alef\UserBundle\EventListener; 

use Doctrine\ORM\Event\LifecycleEventArgs; 
use Alef\UserBundle\Service\RoleService; 

class ExampleListener 
{ 
    private $roleService; 

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

    public function postLoad(LifecycleEventArgs $args) 
    { 
     $entity = $args->getEntity(); 
     if(method_exists($entity, 'setRoleService')) { 
      $entity->setRoleService($this->roleService); 
     } 
    } 
} 
+4

最善の解決策だと質問に対する最も正確な答え。私は "あなたができない"、 "それは間違ったデザインパターン"、または "それはすべてを破滅させる、あなたは馬鹿だ"のような答えは嫌いです。誰も何も指導者によって書かれていない。 「悪い(時には)良い」;)もう一度ありがとう。 –

+3

悲しいことに、「間違ったデザインパターン」、「MCVモデル」、「セパレートビジネスレイヤー」など。 @Kaiのお返事ありがとうございます、私が探していたものです。 –