2015-04-21 5 views
8

Der Kodex

Sagen, ich habe zwei Modelle, genannt Product und Image, die von Product hasMany Image und Image belongsTo Product verbunden ist.Mit limit() auf enthaltenes Modell

Nun sagen, ich möchte alle Produkte mit dem ersten Bild jeweils abrufen. Ich würde diesen Code verwenden:

$this->Products->find('all') 
    ->contain([ 
     'Images' => function($q) { 
      return $q 
       ->order('created ASC') 
       ->limit(1); 
     } 
    ]); 

Sieht nach rechts, oder? Außer jetzt nur ein der Produkte enthält ein Bild, obwohl jedes Produkt tatsächlich mindestens ein Bild enthält (wenn ohne das Limit abgefragt).

Die resultierende Abfrage

Das Problem mit der Grenze zu sein scheint, da dies die folgenden zwei Abfragen (zum Beispiel) erzeugt:

bei der
SELECT 
    Products.id AS `Products__id`, 
FROM 
    products Products 

und

SELECT 
    Images.id AS `Images__id`, 
    Images.product_id AS `Images__product_id`, 
    Images.created AS `Images__created` 
FROM 
    images Images 
WHERE 
    Images.product_id in (1,2,3,4,5) 
ORDER BY 
    created ASC 
LIMIT 1 

Suche zweite Frage, es ist ziemlich offensichtlich, wie dies immer nur ein Bild ergeben wird.

Das Problem

Allerdings würde ich den Kuchen ORM haben erwartet die Bilder auf 1 pro Produkt zu begrenzen, wenn ich limit(1) genannt.

Meine Frage: Ist das ein Fehler bei der Verwendung des ORM? Wenn ja, wie sollte ich die Anzahl der Bilder auf eins pro Bild begrenzen?

+0

Für die Zukunft: Ich habe einfach das Weglassen endete 'limit()' und verwende einfach das erste Bild im Array. Alle Antworten während der Arbeit scheinen eine Umgehungslösung zu sein. Das Cake-ORM ** immer ** verwendet eine einzige Abfrage für contains, auch wenn dies unerwünscht ist (etwa wenn der Abfrage ein Limit hinzugefügt wird). –

Antwort

14

Der sauberste Weg, dies durch Schaffung einer anderen Verein tun kann: es

$this->hasOne('FirstImage', [ 
    'className' => 'Images', 
    'foreignKey' => 'image_id', 
    'strategy' => 'select', 
    'sort' => ['FirstImage.created' => 'DESC'], 
    'conditions' => function ($e, $query) { 
     $query->limit(1); 
     return []; 
    } 
]) 
+1

aber ich bekomme nicht die letzte Reihe, ich bekomme die erste. Kannst du mehr vorschlagen? – sradha

+0

Vielen Dank, ich habe es. Es funktioniert wirklich. Ich möchte Sie auf den neuesten Stand bringen. – sradha

+0

@sradha - wie hast du das gelöst? Ich kann das primäre hasOne-Array nicht sortieren, und die Reihenfolge funktioniert auch nicht in der Bedingungsabfrage. Ich kann nur scheinen, erstes Ergebnis zu bekommen. – MiDri

0

Wenn Sie das Bild auf ein Bild beschränken, sollten Sie ein Standardbild haben. Sie betrachten könnte ein default Feld in der Bildtabelle hinzufügen und einen Alias ​​wie dies zu tun:

var $hasOne = array(
    'CoverImage' => array(
     'className' => 'Image', 
     'conditions' => array('CoverImage.default' => true), 
    ), 

Es sieht aus wie Sie Kuchen v3 verwenden, so dass Sie nur die entsprechende Zuordnung als die oben hinzufügen kann, ist eine 2.x Probe .

2

Überprüfen Sie, dieses ist mein Code

$this->Orders->hasOne('Collections', [ 
        'className' => 'Collections', 
        'foreignKey' => 'order_id', 
        'strategy' => 'select', 
        'conditions' => function (\Cake\Database\Expression\QueryExpression $exp, \Cake\ORM\Query $query) { 
        $query->order(['Collections.id' => 'ASC']); 
        return []; 
                                 } 
        ]); 


        $Lists = $this->Orders->find('all')->where($condition)->contain(['Collections'])->order(['Orders.due_date DESC']); 
        $this->set(compact('Lists'));