简体   繁体   English

CakePHP HABTM关联规则

[英]CakePHP HABTM association rules

If I want to create a category and be able to link products to it by tags I can like so: 如果我想创建一个类别并能够通过标签将产品链接到该类别,我可以这样:

  • Create the category and product tables. 创建类别和产品表。
  • Create a tags table with tags like: Ruby, Earrings, White-Gold 创建一个带有以下标签的标签表:Ruby,Earrings,White-Gold
  • Create a category_tags and product_tags table to map them 创建一个category_tagsproduct_tags表以映射它们
  • Set category and product to hasAndBelongsToMany tags 将类别和产品设置为hasAndBelongsToMany标签
  • Set tags to hasAndBelongsToMany products and hasAndBelongsToMany categories 将标签设置为hasAndBelongsToMany产品和hasAndBelongsToMany类别

Now say I have 2 products one with tags: Ruby and Earrings and another with tags: Ruby and Bracelet 现在说我有2个产品,其中一个带有标签: RubyEarrings ,另一个带有标签: RubyBracelet

Say I want to create a Ruby Earrings category. 假设我要创建“ Ruby耳环”类别。

I could add the Ruby and Earrings tags to the category. 我可以将RubyEarrings标签添加到类别中。 But under normal HABTM Model associations both products will be returned because even though only 1 has an earrings tag they both have a ruby tag. 但是在正常的HABTM模型关联下,两种产品都将被退回,因为即使只有1个具有earrings标签,它们都具有ruby标签。

How can I make it only match products that have ALL of the same tags as the category (products can have more tags but must have all the tags the corresponding category has) in order be returned? 如何才能使其仅与具有与类别相同标签的所有产品匹配(产品可以具有更多标签,但必须具有对应类别具有的所有标签)才能返回?

Also, taking that even further, how could I add -tags to a category that the products must NOT have these tags to be returned? 此外,进一步讲,如何将-tags添加到产品必须没有这些标签才能返回的类别中?

The script below solved my issue by generating a query like so: 下面的脚本通过生成如下查询来解决我的问题:

PHP 的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 的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

However I feel like this is not the way CakePHP is inteded to be treated, I think maybe this is something that should be handled in the model not in the controller. 但是我觉得这不是CakePHP真正要被对待的方式,我认为这也许应该在模型中而不是在控制器中处理。 But I am not sure how to do that. 但是我不确定该怎么做。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM