2015-04-18 30 views
7

alanlarını içerir. Aşağıdaki DB tablolarım var: öğeler, kullanıcılar, gruplar, itemImages. (öğeler, gruplar) ve (kullanıcılar, gruplar) ve (öğeler, öğeler içindekiler) arasında bir çok arasında çok fazla ilişki vardır. Uygun tüm yabancı anahtarlar CakePHP'de dernekler olarak kuruldu.CakePHP 3,

Belirli bir kimliğe sahip bir kullanıcıya ana grup olarak atanmış bir gruptaki tüm öğeleri ve ana görüntülerini seçen içerme() ile bir sorguyu nasıl oluşturabilirim? Şimdilik var

SELECT items.id AS itemId, items.name, itemImages.url AS itemUrl 
FROM items 
INNER JOIN groups_items ON groups_items.item_id = items.id 
INNER JOIN groups ON groups_images.group_id = groups.id 
INNER JOIN groups_users ON groups_users.group_id = groups.id 
INNER JOIN users ON groups_users.user_id = users.id 
INNER JOIN itemImages ON itemImages.item_id = items.id 
WHERE groups_users.isMainGroup = 1 
    AND users.id = :userId 
    AND itemImages.isMainImage = 1 

CakePHP'nin kodu:

$items = $this->Items->find() 
      ->hydrate(false) 
      ->contain([ 
       'Groups.Users' => function($q) use ($userId){ 
        return $q->where(['isMainGroup' => 1, 'Users.id' => $userId]); 
       }, 
       'ItemImages' => function($q){ 
        return $q->where(['isMainImage' => 1]); 
       }, 
      ]); 
      //->select(['itemId' => 'Items.id', 'Items.name', 'itemUrl' => 'itemImages.url']); 

cevap

9

eşleştirme ile yardımcı olabilir() yöntem

burada, bu net hale getirmek için düz bir SQL sorgusu nasıl görüneceğini olduğunu Bu

$items = $this->Items->find() 
     ->hydrate(false) 
     ->select(['Items.id', 'Items.name', 'itemImages.url']) 
     ->distinct(['Items.id']) 
     ->matching('Groups.Users', function ($q) use ($userId) { 
      return $q->where(['Groups.isMainGroup' => 1, 'Users.id' => $userId]); 
     }) 
     ->matching('ItemImages', function ($q) { 
      return $q->where(['ItemImages.isMainImage' => 1]); 
     }) 
     ->contain([ 
      'ItemImages' => function ($q) { 
       return $q->autoFields(false) 
         ->select(['id','url']) 
         ->where(['ItemImages.isMainImage' => 1]); 
      } 
     ]); 

Bence bu durumda, son con tain ifadesi ommited olabilir, çünkü istenen sonuç zaten _matchingData özelliğindedir.

Not üzerinde distict() stament:

bir INNER JOIN yaratacak bu işlev olarak, senin koşullar eğer yinelenen satırları alabilirsiniz olarak bulmak sorgusunda farklı çağıran düşünebilirsiniz zaten bunları filtrelemeyin

http://book.cakephp.org/3.0/en/orm/retrieving-data-and-resultsets.html#filtering-by-associated-data

+0

Evet, son gerekli değildi içeren - tüm veriler alre edildi _matchingData içinde eşleşen() işlevlerinden ady. Benim en büyük sorum, sonucu doğru bir şekilde "düzleştirmek" idi. Bu şekilde() seçtiğimde, bana "_matchingData" anahtarının altında bir alt nesne olarak URL'yi verir ve diğer değerlerle aynı düzeyde olmasını isterim. Bir geçici çözüm olarak yaptığım şey json_encode -> all "_matchingData." dize aralıkları -> json_decode. – user1507558

+0

'distinct' ifadesine yapılan yorum çok faydalıdır. –