douyi1966 2010-12-20 17:37
浏览 28

CakePHP HABTM关联规则

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
  • Create a category_tags and product_tags table to map them
  • Set category and product to hasAndBelongsToMany tags
  • Set tags to hasAndBelongsToMany products and hasAndBelongsToMany categories

Now say I have 2 products one with tags: Ruby and Earrings and another with tags: Ruby and Bracelet

Say I want to create a Ruby Earrings category.

I could add the Ruby and Earrings tags to the category. 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.

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?

  • 写回答

1条回答 默认 最新

  • dqpd4268 2010-12-21 19:53
    关注

    The script below solved my issue by generating a query like so:

    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
    

    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. But I am not sure how to do that.

    评论

报告相同问题?

悬赏问题

  • ¥20 @microsoft/fetch-event-source 流式响应问题
  • ¥15 ogg dd trandata 报错
  • ¥15 高缺失率数据如何选择填充方式
  • ¥50 potsgresql15备份问题
  • ¥15 Mac系统vs code使用phpstudy如何配置debug来调试php
  • ¥15 目前主流的音乐软件,像网易云音乐,QQ音乐他们的前端和后台部分是用的什么技术实现的?求解!
  • ¥60 pb数据库修改与连接
  • ¥15 spss统计中二分类变量和有序变量的相关性分析可以用kendall相关分析吗?
  • ¥15 拟通过pc下指令到安卓系统,如果追求响应速度,尽可能无延迟,是不是用安卓模拟器会优于实体的安卓手机?如果是,可以快多少毫秒?
  • ¥20 神经网络Sequential name=sequential, built=False