2017-12-04 17 views
0

私は自分のプロジェクトで初めてdoctrineに取り組んでいます。私は、教義の1対多の関係から返されたコレクションから正しいオブジェクトを見つけることに問題があります。Doctrineのコレクションから特定のアイテムを取得する適切な方法

私はエンティティPageに多くのSectionサブエンティティを持っているとしましょう。

/** 
* @ORM\Entity 
* @ORM\Table(name="Pages") 
*/ 
class Page 
{ 
    // bunch of properties 

    /** 
    * @ORM\OneToMany(targetEntity="Section", mappedBy="page") 
    * @var Collection 
    */ 
    protected $sections; 

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

    /** 
    * @return Collection 
    */ 
    public function getSections(): Collection 
    { 
     return $this->sections; 
    } 

} 

は今、私が達成したいものを(私はおそらくnameSectionエンティティのプロパティであることを言及する必要があります)、それの名前でSectionを取得できるようにすることです。

だから最後に、私は次のように何かを達成することができるようにしたい:

class SomeController 
{ 

    public function HomePageAction() 
    { 
     $page = $this->getEntityManager() 
        ->getRepository('App:Entity:Page') 
        ->findOneBy(array('name' => 'homepage')); 

     $section = $page->findSectionByName('header'); 

     // rendering etc. 
    } 

} 

私はでき、もちろん、すべてのセクションと私が探している名前と一致するものを返してループ(もし例外がなければ例外をスローする)、そうする簡単な方法がないのだろうか?また、何らかのカスタムリポジトリクラスで行うべきことは何ですか、あるいはのメソッドをEntityクラスの中に残しても構いませんか?前もって感謝します。

だから、私がこれまで試したどのような...

// class App\Entity\Page 
public function getSectionByName(string $name) 
{ 
    foreach ($this->getSections() as $section) { 
     if ($section->getName() === $name) 
      return $section; 
    } 
    return null; 
} 

答えて

1

ベストプラクティスは、あなたのコレクションにマッチング(基準$基準)機能を使用することです。だから、

:あなたが見つからない例外をスローする場合

use Doctrine\Common\Collections\Criteria; 

public function getSectionByName(string $name) 
{ 
    $criteria = Criteria::create() 
     ->where(Criteria::expr()->eq('name', $name)) 
     ->setFirstResult(0) 
     ->setMaxResults(1); 

    return $this->getSections()->matching($criteria)->first(); 
} 

、ベストプラクティスは、あなたの行動でそれを行うには、次のようになります。

フィルタリング教義のコレクションに関する
public function HomePageAction() 
{ 
    $page = $this->getEntityManager() 
       ->getRepository('App:Entity:Page') 
       ->findOneBy(array('name' => 'homepage')); 

    $section = $page->findSectionByName('header'); 

    if($section === false) { 
     //here throw your exception. 
    } 
    // rendering etc. 
} 

詳細を見つけることができますin Doctrine - Working with Associations

+0

をチェックしてください。私は、「基準」の原則については知らなかった。実際には、他のユーザーにとってより便利なので、基準に関連する文書を回答に追加することを検討することができます。もう一度ありがとう! –

1

Pageエンティティでカスタムリポジトリを生成することもできます

でその後
/** 
* @ORM\Entity(repositoryClass="App\Repository\PageRepository") 
*/ 
class Page 
{ 
    .... 
} 

210あなたApp\Repository\PageRepositoryあなたはこの機能を簡単に は何度も繰り返し、自分のコントローラ内の関数を呼び出すことができますその後、ページとセクション名

// App\Repository\PageRepository 
    public function getSectionByPageAndName($pageName, $sectionName) 
    { 
     return $this->getEntityManager() 
      ->createQueryBuilder() 
      ->select('s') 
      ->from(Page::class, 'p') 
      ->join(Section::class, 's') 
      ->where('p.name = :pageName') 
      ->andWhere('s.name = :sectionName') 
      ->setParameter('pageName', $pageName) 
      ->setParameter('sectionName', $sectionName) 
      ->getQuery() 
      ->getResult(); 
    } 

でセクションを得ることになる関数を定義あなたの関係の原因リポジトリ

class SomeController 
{ 

    public function HomePageAction() 
    { 
     $sections = $this->getEntityManager() 
      ->getRepository('App:Entity:Page') 
      ->getSectionByPageAndName($pageName, $sectionName); 

     //etc 
    } 

} 

@OneToManyあるとsectionNameが一意でない場合$sectionsは空ARRAになりますyまたは配列Sectionのオブジェクトの場合、1つの結果のみに限定したい場合は、docs

+0

ありがとうございました。私はここでのアプローチを理解していますが、既存のPageエンティティ内のセクションを見つける必要があります(すべてのセクションとページエンティティ自体を使用するため)。あなたのソリューションは私にセクションを取得する素晴らしい方法を提供しますが、私の場合は、実際にページを取得し、それを使って作業し、そのセクションを簡単にナビゲートすることです(冗長に - 名前で探すことを選ぶ理由です)。私は必要な場所で正確にページの情報を抽出することができます。それ以外の場合は、お手伝いをして試してみてください。 +1 –

関連する問題