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

发布于 2024-10-08 17:24:05 字数 1999 浏览 1 评论 0原文

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

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

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

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

First let me note that I am new to MVC frameworks so don't assume any knowledge in that area.

I have a Designer model, I want to pull associated products for each designer when I retrieve info from the designer model.

The association isn't simple so cake won't magically do it for me so I need to define this myself. I have been following tutorials and I think I am close but unsure how to tie it all together.

I have a very long query that if you plug in the designer_id in the right places it will select all the associated products.

I think I am supposed to put this query somewhere in the Designer model so that it knows how to retrieve the products.

Here is the query, the parts of the string that look like {$__cakeID__$} need to be replaced with the 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
)

Also here is the designer model:

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

What would I need to do to make the Designer model use this query to automatically find its associated products?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

残花月 2024-10-15 17:24:05

此查询应该使用即席连接和可包含行为来工作:

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

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

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

编辑

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

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

This query should work using an adhoc join and the Containable behavior:

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

The data will come back oriented around the tags, but you'll get what you need. Also, you'll need to make sure you define the HABTM relationships in all three models, Designer, Product, and Tag (tag should have two HABTM associations).

Also, you'll need to add var $actsAs = array('Containable'); to your models.

EDIT

If you cannot find a CakePHP solution, and end up needing to use a raw query, CakePHP can do it with the model query method. Understand that you are giving up some features when using this method. Also take note of this advice from the cookbook:

If you're ever using this method in your application, be sure to check out CakePHP's Sanitize library, which aids in cleaning up user-provided data from injection and cross-site scripting attacks.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文