如何告诉模型如何找到其相关模型?

时间:2010-12-22 18:12:23

标签: php cakephp cakephp-1.3 cakephp-appmodel

首先请注意,我是MVC框架的新手,所以不要假设该领域有任何知识。

我有一个Designer模型,当我从设计师模型中检索信息时,我想为每个设计师提取相关的产品

这种关联并不简单,所以蛋糕不会神奇地为我做,所以我需要自己定义。我一直在关注教程,我认为我很接近但不确定如何将它们组合在一起。

我有一个很长的查询,如果你在正确的位置插入designer_id,它将选择所有相关的产品。

我认为我应该将此查询放在Designer模型中的某个位置,以便它知道如何检索产品。

以下是查询,字符串中{$__cakeID__$}的部分需要替换为designer_id

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
)

此处还有设计师模特:

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';
}

我需要做些什么才能让Designer模型使用此查询自动查找其相关产品?

1 个答案:

答案 0 :(得分:0)

此查询应使用adhoc join和Containable行为:

// 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
    )
));

数据将围绕标签返回,但您将获得所需的信息。此外,您需要确保在所有三个模型DesignerProductTag中定义HABTM关系(标记应具有两个HABTM关联)。

此外,您需要将var $actsAs = array('Containable');添加到模型中。

修改

如果找不到CakePHP解决方案,并且最终需要使用原始查询,CakePHP可以使用模型query method来完成。了解您在使用此方法时放弃了某些功能。另请注意食谱中的建议:

  

如果您曾在应用程序中使用此方法,请务必查看CakePHP的Sanitize库,该库有助于清除注入和跨站点脚本攻击中的用户提供的数据。