【问题标题】:How to tell a model how to find its associated models?如何告诉模型如何找到其关联模型?
【发布时间】:2010-12-22 18:12:22
【问题描述】:

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

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

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

我有一个很长的查询,如果您在正确的位置插入 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 模型使用此查询来自动查找其关联产品?

【问题讨论】:

  • 这是一个很好的查询。您确定 Cake 不能为您处理关联吗?您能否描述关联,和/或准确描述您希望从数据库返回的内容?
  • @Stephen,设计师 HABTM 标签,产品 HABTM 标签。包含所有标签为设计者的产品。此外,designers_tags 表还有一个名为 include 的布尔字段,如果为 false,则不应包含任何带有这些标签的产品。这样我就可以创建一个类别并选择产品必须或不能包含哪些标签才能包含在该类别中。有意义吗?
  • 差不多明白了:您只需要那些标签与设计师完全相同的产品吗?或者您是否希望所有产品都具有设计师也拥有的 any 标签?
  • @Stephen,产品可以包含更多,但必须包含所有的设计师。

标签: php cakephp cakephp-1.3 cakephp-model


【解决方案1】:

这个查询应该使用临时连接和 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 库,它有助于清除用户提供的数据以防止注入和跨站点脚本攻击。

【讨论】:

  • 您的最后一条评论使我的回答无效...但是您也许可以以此为基础。
  • 感谢您的回答,我可以尝试使用您的解决方案,看看我能从中得到什么,但有一件事。我如何告诉它不要包含具有任何 include=0 标签的产品?我会在条件数组中添加类似'FilterDesignersTag.include !=' => 0 的东西吗?谢谢!
  • 我告诉它只包含FilterDesignersTag.include = 1 的那些。看看最终条件。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-14
  • 2021-10-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多