web-dev-qa-db-ja.com

symfony2のエンティティのリポジトリメソッドにアクセスする方法は?

問題が発生しました。手伝ってください。これがシナリオです:

エンティティ「User」と対応するリポジトリ「UserRepository」があり、エンティティ内にはgetterメソッドとsetterメソッドしかありません。 UserRepositoryに書き込んだすべてのカスタムクエリ。今私は私のUserControllerの中で、私がそうすることができないリポジトリメソッドにアクセスしようとしています。例えばユーザーエンティティ:

class User
{
    ...

    public function getId()
    {
        return $this->id;
    }

    public function setId($id)
    {
        return $this->id=$id;
    }
    public function setProperty($property)
    {
        $this->property = $property;
    }


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

    ....

    }
  ?>

UserRepository:

class UserRepository extends EntityRepository
{


    public function findUsersListingById($id)
    {
        $queryBuilder = $this->getEntityManager()->createQueryBuilder();

       $query = $em->createQuery(
                    "SELECT U
                    FROM  UserEntityPathGoesHere
                    WHERE U.id IN (".implode(",", $id).")"
                );

        $users = $query->getResult();

        return $users;
    }

    public function sayHelloWorld(){

        echo ' Hello World';
    }

}
?>

UserController

class UserController
{
 ...


$users=$this->getDoctrine()
        ->getRepository('MyUserEntityPath')
        ->findUsersListingById($ids);

    //now I have multiple users I want to iterate through each user for associating additional data with each user

     foreach($users as $user)
     {
        $temp = array();

        //I am able to access getId method which is  defined in User entity
        $temp['id'] = $user->getId();

        //however I am not able to  access method from UserRepository, I tried something like below which gives me error  call to undefined function sayHelloWorld
        $temp['status'] = $user->sayHelloWorld();

       ....

     }


}

....

エンティティのリポジトリメソッドにアクセスするにはどうすればよいですか?出来ますか ?そうでない場合、ソリューションの代替手段は何ですか?

13
Rahul

すべてが可能ですただし懸念の分離のため、エンティティ自体からエンティティのリポジトリにアクセスしないでください。

これを参照してください 詳細についてはStackoverflowの回答

基本的に、全体の考え方は、アプリケーションを次のように編成することです。

要するに:

コントローラー>リポジトリ>エンティティ。

それは他の方向に行くべきではありません。そうでなければ混乱を引き起こします。

懸念事項の分離についてもう少し詳しく知りたい場合は、次のようにします。

コントローラ>サービス>リポジトリ >エンティティ

代替ソリューション:

  • サービス(リポジトリにアクセスする)またはリポジトリにアクセスする Twig拡張 を作成します。
  • リポジトリにメソッドを作成し、コントローラーでメソッドを呼び出し、データをIDにマップし(配列のキーはIDです)、配列をテンプレートに渡し、エンティティIDを使用して配列からデータをプルします
  • リポジトリにメソッドを作成し、コントローラーでメソッドを呼び出し、データをエンティティに挿入し、テンプレートのエンティティを介してデータにアクセスします。

おそらく他にもありますが、アプリケーションがどのように構成されているかがよくわかります。

21
Thomas Potaire

ユーザーエンティティのUserRepositoryEntityRepositoryとして宣言する必要があります。 Userエンティティに次の注釈を追加します。

/**
 * @ORM\Entity(repositoryClass="Acme\StoreBundle\Entity\UserRepository")
 */

詳細については the docs を参照してください。

1
ferdynator

バンドルがAcme/DemoBundleである場合、少なくとも1つは期待します

ユーザーエンティティ

namespace Acme/DemoBundle/Entity

use Doctrine\ORM\Mapping as ORM;


/**
 *
 * @ORM\Table(name="user")
 * @ORM\Entity(repositoryClass="Acme/DemoBundle/Entity/UserRepository")
 */
class User 
{
...
}

ユーザーリポジトリ

namespace Acme/DemoBundle/Entity

use Doctrine\ORM\Mapping as ORM;

class UserRepository extends EntityRepository
{
...
}   

また、IDの配列を使用して、コントローラーで次のことを行うこともできます。

...
$em = $this->getDoctrine()->getManager();
$users = $em->getRepository("AcmeDemoBundle:User")->findAllById($idArray);
...

コントローラーでユーザーを反復処理するには、次のようにforeachループを使用できます。

foreach ($users as $user) {
//each user is an array
...
$id = $user['id'];
...
}

またはテンプレートで:

{% for user in users %}
...
{{ user.firstName }}
...
{% endfor %}
1
geoB

doctrineからのpostLoadイベントを使用して、必要なものすべてをエンティティに注入できます。イベントリスナーは次のようになります:

    <?php
namespace AppBundle\EventListener;


use AppBundle\Entity\MyEntity;
use Doctrine\ORM\Event\LifecycleEventArgs;

/**
 * Class MyEntityListener
 */
class MyEntityListener
{

    public function postLoad(LifecycleEventArgs $eventArgs)
    {
        /** @var MyEntity $document */
        $document = $eventArgs->getEntity();
        if(!($document instanceof MyEntity)){
            return;
        }
        $document->setEntityManager($eventArgs->getEntityManager());

    }
}

そしてservice.yml:

services:
app.myentity.listener:
  class: AppBundle\EventListener\MyEntityListener
  tags:
    - { name: doctrine.event_listener, event: postLoad }

当然のことながら、エンティティにはsetEntityManagerメソッドが必要であり、準備ができています。

0
Rawburner