在 cakephp 中,如何为与我正在分页的模型无关但与正在分页的模型相关联的模型设置条件?

发布于 2024-09-25 07:10:19 字数 366 浏览 0 评论 0原文

我正在“客户”模型上分页($this->Customer->paginate())。

客户模型与“Contact”模型关联,而“Contact”模型又与“ContactAddress”模型关联。

所以:

Customer hasMany Contact

Contact ownsTo ContactAddress

现在我想使用搜索查询对“Customers->index()”中的客户进行分页,假设“ContactAddress.city”LIKE“%New%”,

我该怎么做?当我在分页条件中执行此操作时,它逻辑上显示:“‘where 子句’中的未知列‘ContactAddress.city’”。

I am paginating ($this->Customer->paginate()) on the 'Customer' model.

The customer model is associated to the 'Contact' model which in turn is associated to the 'ContactAddress' model.

So:

Customer hasMany Contact

Contact belongsTo ContactAddress

Now I want to paginate customers in the 'Customers->index()' using a search query let's say 'ContactAddress.city' LIKE '%New%'

How do I do this? When I do it in the conditions for paginate it says: "Unknown column 'ContactAddress.city' in 'where clause'" logically.

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

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

发布评论

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

评论(2

烂柯人 2024-10-02 07:10:19

无论如何,无论是否成功,对两次删除的条件进行分页都是很困难的。您需要分步执行(首先找到 ContactAddresses 和关联的 Contact.customer_ids,然后在 Customer.id IN ($customer_ids) 上分页)或者你需要用子查询来做到这一点。请参阅有关如何正确执行子查询的手册(这不太好)。

哪个更好取决于您的编码技能、数据库大小和结果查询的复杂性。测试两者并决定哪种适合您。

Paginating on a condition twice removed is difficult in any case, Cake or not. You either need to do it in steps (find ContactAddresses and associated Contact.customer_ids first, then paginate on Customer.id IN ($customer_ids)) or you need to do it with subqueries. See the manual on how to do subqueries properly (it ain't pretty).

What's better depends on your coding skills, database size and complexity of the resulting query. Test both and decide what works for you.

孤蝉 2024-10-02 07:10:19

我找到了一个非常非常令人满意的解决方案。

我查看了分页功能的复杂代码,发现从逻辑上讲,分页设置条件并将这些条件传递给模型的查找函数(除非模型有自己的“分页”函数)。

我首先尝试重写分页函数,但这太复杂了。我最终找到的解决方案是将联接传递给分页选项,就像在模型上进行“查找”时传递它们一样:

    //Set the pagination options:   
    `$this->paginate = array(
        'limit' => 25,
        'order' => array(
        'Customer.lastname1' => 'asc'
        ),
        'joins' =>
        array(
                // OUTER JOIN because I wanted to also 
                // fetch record that do not have a 'contact'
        array(
            'table' => 'contacts',
            'alias' => 'Contact',
            'type' => 'LEFT OUTER',
            'conditions' => array(
                'Customer.id = Contact.customer_id',
                'Contact.class' => 'ContactAddress'
            )
            ),
        array(
            'table' => 'contact_addresses',
            'alias' => 'ContactAddress',
            'type' => 'LEFT OUTER',
            'conditions' => array(
                'Contact.index = ContactAddress.id',
            )
            ),
        ),
        // In your conditions you can now use any table that 
        // was joined as well as the original 'customer' table.
        'conditions' => $conditions,

    );

    $this->set('customers',$this->paginate('Customer'));

无论哪种方式,我希望这对某人有帮助!

I have found a solution that is very very satisfactory.

I looked through the complicated code of the pagination functionality and found, logically, that paginate sets conditions and passes these to a find function of the model (unless the model has it's own 'paginate' function).

I first tried overriding the paginate function, but this was too complicated. The solution I found in the end is to pass on joins to the paginate's options just like you would pass them when doing 'find' on a model:

    //Set the pagination options:   
    `$this->paginate = array(
        'limit' => 25,
        'order' => array(
        'Customer.lastname1' => 'asc'
        ),
        'joins' =>
        array(
                // OUTER JOIN because I wanted to also 
                // fetch record that do not have a 'contact'
        array(
            'table' => 'contacts',
            'alias' => 'Contact',
            'type' => 'LEFT OUTER',
            'conditions' => array(
                'Customer.id = Contact.customer_id',
                'Contact.class' => 'ContactAddress'
            )
            ),
        array(
            'table' => 'contact_addresses',
            'alias' => 'ContactAddress',
            'type' => 'LEFT OUTER',
            'conditions' => array(
                'Contact.index = ContactAddress.id',
            )
            ),
        ),
        // In your conditions you can now use any table that 
        // was joined as well as the original 'customer' table.
        'conditions' => $conditions,

    );

    $this->set('customers',$this->paginate('Customer'));

Either way I hope this helps someone!

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