CakePHP HABTM关联规则

时间:2010-12-20 17:37:46

标签: php cakephp cakephp-1.3 has-and-belongs-to-many

如果我想创建一个类别,并且能够通过标签链接产品,我可以这样:

  • 创建类别和产品 表。
  • 使用以下标签创建标签表: 红宝石,耳环,白金
  • 创建category_tagsproduct_tags表来映射它们
  • 将类别和产品设置为 hasAndBelongsToMany标签
  • 将标签设置为 hasAndBelongsToMany产品和hasBelongsToMany类别

现在说我有两个带有标签的产品: Ruby 耳环,另一个带有标签: Ruby Bracelet

我想要创建一个 Ruby Earrings 类别。

我可以将 Ruby Earrings 标签添加到该类别中。但是在正常的HABTM模型关联下,两个产品都将被返回,因为即使只有1个标签有earrings标签,它们都有一个ruby标签。

如何使其仅匹配具有与类别相同的所有标签的产品(产品可以包含更多标签但必须具有相应类别的所有标签)才能返回?

另外,更进一步,我如何将-tags添加到产品不得返回这些标签的类别中?

1 个答案:

答案 0 :(得分:0)

下面的脚本通过生成如下查询解决了我的问题:

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

但是我觉得这不是CakePHP打算对待的方式,我想也许这应该是在模型中处理而不是在控制器中处理的。但我不知道该怎么做。