2010-12-20 4 views
0

Si je veux créer une catégorie et être en mesure de lier des produits à par des tags Je peux comme ceci:association CakePHP HABTM Règles

  • Créer la catégorie et produit tables.
  • Créer une table de balises avec des balises comme: Ruby, boucles d'oreilles, en or blanc
  • Créer une table category_tags et product_tags pour les associer
  • Set catégorie et produit étiquettes hasAndBelongsToMany
  • Définir des balises à produits hasAndBelongsToMany et catégories hasAndBelongsToMany

dire maintenant, j'ai 2 produits avec un tags: Ruby et Boucles d'oreilles et un autre avec les étiquettes: Ruby et Bracelet

que je veux créer une catégorie Ruby Boucles d'oreilles.

Je pourrais ajouter le Ruby et Boucles d'oreilles étiquettes à la catégorie. Mais dans les associations normales du modèle HABTM, les deux produits seront retournés parce que même si seulement 1 a une étiquette earrings, ils ont tous les deux une étiquette ruby.

Comment puis-je faire correspondre uniquement les produits qui ont TOUS les mêmes tags que la catégorie (les produits peuvent avoir plus de tags mais doivent avoir tous les tags de la catégorie correspondante) pour être retournés?

En outre, en prenant cela encore plus loin, comment pourrais-je ajouter -tags à une catégorie que les produits ne doivent PAS avoir ces balises à retourner?

Répondre

0

Le script ci-dessous résolu mon problème en générant une requête comme ceci:

PHP

$data = $this->Designer->find(
    'first', 
    array(
     'conditions' => array(
      'Designer.slug' => $name, 
      'Designer.available' => 1 
     ) 
    ) 
); 

$inc_tag_ids = array(); 
$exc_tag_ids = array(); 
foreach($data["Tag"] as $tag) 
{ 
    if($tag['DesignersTag']['include']) 
    { 
     $inc_tag_ids[] = $tag['id']; 
    } 
    else 
    { 
     $exc_tag_ids[] = $tag['id']; 
    } 
} 

$ins = ' '; 

if(count($inc_tag_ids)) 
{ 
    $inc_tag_id_str = '"' . implode('","',$inc_tag_ids) . '"'; 
    $ins .= 'AND tags.id IN ('.$inc_tag_id_str.')'; 
} 

if(count($exc_tag_ids)) 
{ 
    $exc_tag_id_str = '"' . implode('","',$exc_tag_ids) . '"'; 
    $ins .= '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 ('.$exc_tag_id_str.') 
    )'; 
} 

$prod_qry = ' 
    SELECT *, COUNT(DISTINCT tags.name) AS uniques 
    FROM products, products_tags, tags 
    WHERE products.id = products_tags.product_id 
    AND tags.id = products_tags.tag_id 
    '.$ins.' 
    GROUP BY products.id 
    HAVING uniques = '.count($inc_tag_ids).' 
'; 

echo $prod_qry; 

$data["matching_products"] = $this->Designer->Tag->query($prod_qry); 

SQL

SELECT * , COUNT(DISTINCT tags.name) AS uniques 
FROM products, products_tags, tags 
WHERE products.id = products_tags.product_id 
AND tags.id = products_tags.tag_id 
AND tags.id 
IN (
"8" 
) 
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 (
"7" 
) 
) 
GROUP BY products.id 
HAVING uniques =1 

Cependant, je pense que ce n'est pas la façon dont CakePHP est BUT à être traité, je pense que c'est quelque chose qui devrait être traité dans le modèle pas dans le contrôleur. Mais je ne suis pas sûr de savoir comment faire cela.