2017-10-10 2 views
1

Symfony Securityの章に従って読み込まれたデータベースに自分のユーザとロールがあります。ユーザーはAdvancedUserInterface、\ Serializable、 を実装します。ロールはRoleInterfaceを実装します。 私の役割エンティティ:Symfonyがロールをロードするために使用するロールレポジトリのメソッド

マイRolesPrivilegesエンティティは、役割と権限との関係と同じ種類で1つのリレーションに多くと接続されている
AppBundle\Entity\Roles: 
    type:  entity 
    table:  Roles 
    repositoryClass: AppBundle\Repository\Roles 
[...] 
    oneToMany: 
      users: 
       targetEntity:  Users 
       mappedBy:   role 
       cascade:   [persist] 
      privs: 
       targetEntity:  RolesPrivileges 
       mappedBy:   role 
       cascade:   [persist] 

AppBundle\Entity\RolesPrivileges: 
    type:  entity 
    table:  RolesPrivileges 
    repositoryClass: AppBundle\Repository\RolesPrivileges 
id: 
    role: 
      associationKey: true 
      type:  integer 
    privilege: 
      type:  integer 
      associationKey: true 
fields: 
    related: 
      type:  boolean 
      nullable: FALSE 
      options: 
        default: 0 
manyToOne: 
     role: 
      targetEntity:  Roles 
      inversedBy:  privs 
      joinColumn: 
       name:  role_id 
       referencedColumnName:  id 
     privilege: 
      targetEntity:  Privileges 
      joinColumn: 
       name:  privilege_id 
       referencedColumnName:  id 

そして最後に特権エンティティ:

AppBundle\Entity\Privileges: 
    type:  entity 
     table:  Privileges 
     id: 
[...] 

     fields: 
      short: 
       type:  string 
       length: 50 
       nullable: FALSE 

コントローラの各アクションに(ログインしたユーザーの)詳細なアクセス権を確認できるように書いてあります。ユーザーに割り当てられている役割に関連する権限を繰り返し実行します。

問題は、SymfonyがPrivilegesテーブルのエントリごとにdbに対して別々のクエリを実行していることです。コントローラ内で、クエリを使用してすべてをフェッチし、保護された変数に格納することで修正しました。

しかし、(ロールエンティティで定義されたメソッドを使用して)twigテンプレートから権限を反復するときに発生する同じ問題を解決する方法がわかりません。私はRolesRepositoryのメソッドの1つを再定義して、すべての権限を1つのクエリで取得できると考えていました。どうやってやるの?

+0

私の心に来る唯一の解決策は、(それは醜いです)、以前にDBから移入(1つのクエリをコントローラのrender()メソッドを再定義し、さまざまな権限を渡すことです)をつけてそれを繰り返します。しかし、私はより良い修正を探しています。 –

答えて

2

Doctrineではリレーションがデフォルトで遅延ロードされます。ロールが取得されたときにロールとともに権限をロードする場合は、関係の負荷タイプをEAGERとして構成します。

あなたが永続的な関連を持っていると これらの団体は、EAGERとしてマッピングされたエンティティを照会するたびに、彼らは自動的に は、エンティティが照会されていると一緒にロードされるとすぐにそのため、あなたのアプリケーションに利用できる されます。

http://doctrine-orm.readthedocs.org/en/latest/reference/working-with-objects.html#by-eager-loading

AppBundle\Entity\Roles: 
    oneToMany: 
     [...] 
     privs: 
      [...] 
      fetch: EAGER 

AppBundle\Entity\RolesPrivileges: 
    [...] 
    manyToOne: 
     privilege: 
      [...] 
      fetch: EAGER 
+0

@Stefanoありがとうございました。 RolesPrivilegesエンティティスニペットでわかるように、私は追加のフィールドを持っているので、別のエンティティを持つ必要があります。 また、フェッチしません:EAGERは関連するエンティティをただちにロードしますが、依然として別のクエリでロードしますか?私はちょうどクエリの数を減らしたいと思っていた... –

+0

私はあなたが中間のエンティティにある追加のフィールドに気付かなかった、それについて残念。ところで、デフォルトでDoctrineはコレクションの各レコードを取得するためのクエリを実行します。 EXTRA_LAZYは、コレクションのアイテム数を数えたい場合など、すべてのレコードの読み込みをスキップします。最後に、EAGERの読み込みでは、すべての行を1つのクエリで読み込んでエンティティを取得します。 – Stefano

+0

EAGERの読み込みをテストしましたが、残念ながらそれはすべて1つずつ読み込まれます(なぜ100%この)。おそらく、私はdoctrineクエリdbをそのようにするデータ(反復)を使用する方法です。それが使う方法はfindOneByだと思いますか?私は私のリポジトリクラスでそれを再定義したいと思います。 –

関連する問題