2010-12-22 7 views
0

Zunächst möchte ich bemerken, dass ich neu in MVC-Frameworks bin, also keine Kenntnisse in diesem Bereich annehmen.Wie kann ich einem Modell sagen, wie es die zugehörigen Modelle findet?

Ich habe ein Designer-Modell, ich möchte verknüpfte Produkte für jeden Designer ziehen, wenn ich Informationen aus dem Designer-Modell abrufen.

Der Verein ist nicht einfach so Kuchen wird nicht magisch es für mich tun, also muss ich das selbst definieren. Ich habe Tutorials verfolgt und denke, dass ich in der Nähe bin, aber nicht sicher bin, wie ich alles zusammenbinden kann.

Ich habe eine sehr lange Abfrage, dass wenn Sie die Designer_ID an den richtigen Stellen anschließen, wird es alle zugehörigen Produkte auswählen.

Ich denke, ich soll diese Abfrage irgendwo im Designer-Modell platzieren, damit sie weiß, wie man die Produkte abruft.

Hier ist die Abfrage, die Teile der Zeichenfolge, die wie {$__cakeID__$} aussehen müssen mit den designer_id ersetzt werden:

SELECT *, COUNT(DISTINCT tags.name) AS uniques 
FROM products, products_tags, tags, designers, designers_tags 
WHERE products.id = products_tags.product_id 
AND tags.id = products_tags.tag_id 
AND tags.id IN (
    SELECT t.id 
    FROM tags t 
    LEFT JOIN designers_tags dt ON dt.tag_id = t.id 
    LEFT JOIN designers d ON d.id = dt.designer_id 
    WHERE d.id ={$__cakeID__$} 
    AND dt.include =1 
) 
AND products.id NOT IN ( 
    SELECT products.id 
    FROM products, products_tags, tags 
    WHERE products.id = products_tags.product_id 
    AND tags.id = products_tags.tag_id 
    AND tags.id IN (
     SELECT t.id 
     FROM tags t 
     LEFT JOIN designers_tags dt ON dt.tag_id = t.id 
     LEFT JOIN designers d ON d.id = dt.designer_id 
     WHERE d.id ={$__cakeID__$} 
     AND dt.include =0 
    ) 
) 
AND designers.id = designers_tags.designer_id 
AND designers_tags.tag_id = tags.id 
GROUP BY products.id 
HAVING uniques = (
    SELECT COUNT(d.id) AS tag_count 
    FROM tags t 
    LEFT JOIN designers_tags dt 
     ON dt.tag_id = t.id 
    LEFT JOIN designers d 
     ON d.id = dt.designer_id 
    WHERE d.id = {$__cakeID__$} 
    AND dt.include =1 
    GROUP BY d.id 
) 

Auch hier ist das Designer-Modell:

class Designer extends AppModel 
{  
    var $name = 'Designer'; 

    var $actsAs = array('Sluggable' => array('separator' => '-', 'overwrite' => false, 'label' => 'name')); 

    var $hasAndBelongsToMany = 'Tag'; 

    var $hasOne = 'AlternateName'; 

    var $hasMany = 'Vote'; 
} 

Was würde Ich muss tun, damit das Designer-Modell diese Abfrage verwendet, um die zugehörigen Produkte automatisch zu finden?

+0

Das ist eine höllische Abfrage. Bist du sicher, dass Cake die Verbindung nicht für dich übernehmen kann? Können Sie die Assoziation beschreiben und/oder genau beschreiben, was Sie von der Datenbank erhalten möchten? – Stephen

+0

@Stephen, Designer HABTM-Tags, Produkt HABTM-Tags. Die Produkte, die alle Tags als Designer enthalten, sind enthalten. Auch die Tabelle designers_tags enthält ein boolesches Feld mit dem Namen 'include', falls false, und alle Produkte mit diesen Tags sollten NICHT enthalten sein. Auf diese Weise kann ich eine Kategorie erstellen und auswählen, welche Produkte Produkte haben oder nicht haben dürfen, um in die Kategorie aufgenommen zu werden. Sinn ergeben? –

+0

Fast schon verstanden: Benötigen Sie nur die Produkte, die genau die gleichen Tags haben wie der Designer?Oder wollen Sie alle Produkte, die ein * an * Tag haben, das ein Designer auch hat? – Stephen

Antwort

0

Diese Abfrage sollte eine Ad-hoc-beitreten und das Contain Verhalten arbeiten mit:

// this assumes you are in the DesignersController 
$this->Designer->Tag->find('all', array(
    'joins' => array(
     array(
      'table' => 'designers_tags', 
      'alias' => 'FilterDesignersTag', 
      'type' => 'INNER', 
      'conditions' => array(
       'FilterDesignersTag.tag_id = Tag.id' 
      ) 
     ) 
    ), 
    'contain' => array('Designer', 'Product'), 
    'conditions' => array(
     'FilterDesignersTag.designer_id' => $designer_id, 
     'FilterDesignersTag.include' => 1 
    ) 
)); 

Die Daten kommen wieder die Tags orientiert sich um, aber Sie bekommen, was Sie brauchen. Außerdem müssen Sie sicherstellen, dass Sie die HABTM-Beziehungen in allen drei Modellen Designer, Product und Tag definieren (das Tag sollte zwei HABTM-Verknüpfungen haben).

Außerdem müssen Sie var $actsAs = array('Containable'); zu Ihren Modellen hinzufügen.

EDIT

Wenn Sie nicht benötigen eine CakePHP Lösung, und am Ende finden eine rohe Abfrage zu verwenden, kann CakePHP es tun mit dem Modell query method. Verstehen Sie, dass Sie einige Funktionen aufgeben, wenn Sie diese Methode verwenden. Beachten Sie auch diese Ratschläge aus dem Kochbuch:

Wenn Sie jemals diese Methode in Ihrer Anwendung verwenden, müssen Sie die CakePHP Sanitize Bibliothek zu überprüfen, die bei der Säuberung vom Benutzer bereitgestellte Daten von Injektionshilfen und Quer -Site-Scripting-Angriffe.

+0

Ihr letzter Kommentar macht meine Antwort ungültig ... Aber Sie können vielleicht darauf aufbauen. – Stephen

+0

danke für deine antwort, ich kann versuchen, mit deiner lösung zu spielen und zu sehen, was ich daraus machen kann. Wie würde ich sagen, dass keine Produkte enthalten sind, die eines der include = 0 Tags haben? Würde ich etwas wie "FilterDesignersTag.include! = '=> 0" in das Array "conditions" einfügen? Vielen Dank! –

+0

Ich sage es, nur die mit 'FilterDesignersTag.include = 1' einzuschließen. Sehen Sie sich die endgültigen Bedingungen an. – Stephen