2012-09-10 11 views
5

Doctrine2 dinleyicisine, herhangi bir onaylanmayan/taslak varlığı filtrelemenin bir aracı olarak işlev gören bir süzgeç uygulamam var. Bu, başvurulan varlık üzerinde iyi çalışıyor, ancak ilişkilerini nasıl kullanacağımı göremiyorum. .Bir ilişki temelinde bir Doctrine2 filtresini nasıl uygularım?

Şirket için Kategori denir, o Ürünle ilgili Ürünlerim var, o Ürünleri için findBy() yaptığımda, ilgili Kategoriyi onaylamadığını kontrol etmek için sorguya ihtiyacım var.

kalın bitleri and c.approved = true

left join category c on p.category_id = c.id
where p.id = 5 select * from products p

benim filtre veya eşdeğeri tarafından enjekte edilmesi gereken şeylerdir.

Bunu uygulamak hakkında nasıl gidebilirim?

Şimdiye kadar filtresinde yerde bir parçası olarak enjekte bir alt sorgu var, ama bu cehennemi görünüyor ve daha iyi bir yolu olmalı düşünüyorum:

class ApprovableFilter extends SQLFilter 
{ 
    protected $listener; 
    protected $entityManager; 

    public function addFilterConstraint(ClassMetadata $targetEntity, $targetTableAlias) 
    { 
     $config = $this->getListener()->getConfiguration($this->getEntityManager(), $targetEntity->name); 

     /* this bit works fine for the category */ 

     if (isset($config['approvable']) && $config['approvable']) { 
      $column = $targetEntity->columnNames[$config['fieldName']]; 

      return $targetTableAlias.'.'.$column.' = true'; 
     } 

     /* this bit works for products.. but seems like a pretty poor solution */ 

     if (isset($targetEntity->associationMappings['category'])) { 
      $config = $this->getListener()->getConfiguration(
       $this->getEntityManager(), 
       $targetEntity->associationMappings['category']['targetEntity'] 
      ); 

      return '(
       select d.id from dealership d 
       where d.id = '.$targetTableAlias.'.dealership_id 
       and d.'.$config['fieldName'].' = true 
      ) is not null'; 
     } 
    } 
+0

Yaptığınız şey en iyisi gibi görünüyor. İstek zaten JOIN içeriyorsa ne yapardınız? vb ... – AdrienBrault

+0

@AdrienBrault yeniden bir araya geldiği anda ve belki de, diğer takma adlar teorik olarak çatışabilir, eminim ki, bunu örneklemekte olduğumdan daha iyi bir yol olmalı. Bunu yapmaya nasıl devam edeceğine dair hiçbir fikriniz yok. – Steve

cevap

1

i düşünebildiğim en iyi , Ürünlerinizi Kategori nesnesi aracılığıyla almaktır.
Bu şekilde yalnızca category.approved alanına filtre uygulamanız yeterlidir. Örneğin

:

public function addFilterConstraint(ClassMetadata $targetEntity, $targetTableAlias) 
{ 
    $config = $this->getListener()->getConfiguration($this->getEntityManager(), $targetEntity->name); 

    /* this bit works fine for the category */ 

    if (isset($config['approvable']) && $config['approvable']) { 
     $column = $targetEntity->columnNames[$config['fieldName']]; 

     return $targetTableAlias.'.'.$column.' = true'; 
    } 
} 

Sonra Kategori varlık bir ürün koleksiyonuna sahip olmalıdır (bir çift yönlü ilişki olduğu varsayıldığında).

use Doctrine\Common\Collections\ArrayCollection; 

class Category { 
    /** 
    * @var ArrayCollection $products 
    * @ORM\OneToMany(targetEntity="Product", mappedBy="category") 
    */ 
    private $products; 

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

    public function getProducts() 
    { 
     return $this->products; 
    } 
} 

Bu şekilde öncelikle Kategori bu yardımcı olur

$category = $this->get('doctrine')->getRepository('SomeBundle:Category')->find(5); 
if($category) { 
    //Here you now the category is approved 
    $products = $category->getProducts(); 
} 

umut alabilirsiniz.

Düzenleme:

@lracicot soruya cevap vermek için ve tek yönlü ilişki için bir örnek vermek: Ben örneğin bir ProjectRepository yöntemi yaratacak:

... 
findByCategoryApproved($product_id, $approved = true) 
{ 
    $query = 
     'SELECT p 
     FROM AcmeBundle:Product 
     LEFT JOIN p.categories c 
     WHERE p.id = :id AND c.approved = :approved'; 

    return $this 
     ->getEntityManager() 
     ->createQuery($query) 
     ->setParameter('id', $product_id) 
     ->setParameter('approved', $approved) 
     ->getOneOrNullResult(); 
} 

...

$product = $doctrine 
    ->getRepository('AcmeBundle:Product') 
    ->findByCategoryApproved(5); 
+0

Benzer bir sorunum var ama benim durumumda, "Ürün" ten "Kategori" ye olan ilişki (ve) tek yönlüdür, bu yüzden "Ürünlerimi" "Kategori" den alamıyorum. Bu durumda ne önerirsiniz? – lracicot

+1

@lracicot cevabımı düzenle;) – Gintro

İlgili konular