【问题标题】:CakePHP 3-level-deep model associationsCakePHP 3 级深度模型关联
【发布时间】:2010-06-03 13:01:25
【问题描述】:

我对 CakePHP 比较陌生,我在文档方面做得很好,但是几周来我一直试图找到解决这个问题的方法,但我似乎没有找到解决方案,我确信它是简单,甚至可能自动完成,但我就是不知道如何找到它(也许我不知道这类事情的行话)

我的模型结构是这样的:

<?php
    class Trip extends AppModel {
          var $belongsTo = array(
            'User' => array(
                'className' => 'User',
                'foreignKey' => 'user_id'
            ),
            'Start' => array(
                'className' => 'Place',
                'foreignKey' => 'start_id'
            ),
            'End' => array(
                'className' => 'Place',
                'foreignKey' => 'end_id'
            ),
            'Transport' => array(
                'className' => 'Transport',
                'foreignKey' => 'transport_id'
            )
        );

     }
?>

<?php
class Place extends AppModel {

    var $belongsTo = array(
        'User' => array(
            'className' => 'User',
            'foreignKey' => 'user_id'
        ),
        'Country' => array(
            'className' => 'Country',
            'foreignKey' => 'country_id'
        ),
        'State' => array(
            'className' => 'State',
            'foreignKey' => 'state_id'
        ),
        'City' => array(
            'className' => 'City',
            'foreignKey' => 'city_id'
        )
    );
    var $hasMany = array(
        'PlaceStart' => array(
            'className' => 'trip',
            'foreignKey' => 'start_id',
            'dependent' => false
        ),
        'PlaceEnd' => array(
            'className' => 'trip',
            'foreignKey' => 'end_id',
            'dependent' => false
        )
    );

}
?>

<?php
class State extends AppModel {

    var $belongsTo = array(
        'Country' => array(
            'className' => 'Country',
            'foreignKey' => 'country_id',
            'conditions' => '',
            'fields' => '',
            'order' => ''
        )
    );

    var $hasMany = array(
        'City' => array(
            'className' => 'City',
            'foreignKey' => 'city_id',
            'dependent' => false
        )
    );

}
?>

... 用户、城市、国家和交通模型等等。

我想要实现的是在搜索Trip 时获取整棵树的所有信息。

<?php
class TripController extends AppController {
    function index() {
        debug($this->Trip->find('first'));
    }
}

输出

Array
(
    [Trip] => Array
        (
            [id] => 6
            [created] => 2010-05-04 00:23:59
            [user_id] => 4
            [start_id] => 2
            [end_id] => 1
            [title] => My trip
            [transport_id] => 1
        )

    [User] => Array
        (
            [id] => 4
            [name] => John Doe
            [email] => john.doe@mailinator.com
        )

    [Start] => Array
        (
            [id] => 2
            [user_id] => 4
            [country_id] => 1
            [state_id] => 1
            [city_id] => 1
            [direccion] => Lincoln Street
        )

    [End] => Array
        (
            [id] => 1
            [user_id] => 4
            [country_id] => 1
            [state_id] => 1
            [city_id] => 4
            [address] => Fifth Avenue
        )

    [Transport] => Array
        (
            [id] => 1
            [name] => car
        )
)

这是一个问题: 如何在一次查询中获取树下的所有信息?

我想要类似的东西

Array
(
    [Trip] => Array
        (
            [id] => 6
            [created] => 2010-05-04 00:23:59
            [User] => Array
                (
                    [id] => 4
                    [name] => John Doe
                    [email] => john.doe@mailinator.com
                )
            [Start] => Array
                (
                    [id] => 2
                    [user_id] => 4
                    [Country] => Array
                        (
                            [id] => 1
                            [name] = Spain
                        )
                    [State] => Array
                        (
                            [id] => 1
                            [name] = Barcelona
                        )
                    [City] => Array
                        (
                            [id] => 1
                            [name] = La Floresta
                        )
                    [address] => Lincoln Street
                )
            [End] => (same as Start)
            [title] => My trip
            [Transport] => Array
                (
                    [id] => 1
                    [name] => car
                )
        )
)

CakePHP 可以创建这种数据吗? 不仅适用于$this-&gt;Model-&gt;find(),还适用于$this-&gt;paginate(),例如:

    // filter by start
    if(isset($this->passedArgs['start'])) {
        //debug('isset '.$this->passedArgs['start']);
        $start = $this->passedArgs['start'];
        $this->paginate['conditions'][] = array(
            'OR' => array(
                'Start.address LIKE' => "%$start%",
                'Start.State.name LIKE' => "%$start%",
                'Start.City.name LIKE' => "%$start%",
                'Start.Country.name LIKE' => "%$start%"
            )
        );
        $this->data['Search']['start'] = $start;
    }

这似乎是一个粗略的问题,但我确信这已被广泛完成并记录在案,我非常感谢任何帮助。

【问题讨论】:

    标签: php cakephp join children pagination


    【解决方案1】:

    您似乎一切都设置好了。您所要做的就是将递归设置为 2,这应该为您的数据提供一个额外的级别(假设您已正确设置所有关系)

    var $recursive =2;
    

    【讨论】:

    • $this-&gt;Trip-&gt;find('first', array('recursive' =&gt; 2));
    • 简直太美了。感谢百万保尔和班瑟!
    • 这似乎很棒,但是 - 有很多关联,我不能使用递归 2 而不会出现内存错误 - 即使我将它限制为一个结果(比如“第一个”) .有什么想法吗?
    • 您可以在运行时动态绑定您需要的关联,而不是让它们在模型中永久设置。 (您甚至可以在模型中设置函数来为您设置绑定,以便将所有内容集中在一个地方)
    • 如果有人使用 CakePHP 3.0 遇到这个答案,我刚刚得知 recursive 已被放弃,因此您应该改用 contain()。更多信息在这里:link
    【解决方案2】:

    Containable Behavior 是一个替代的、更具外科手术性的解决方案,如果您需要深入 2 个级别或如果您有很多不需要解决此特定问题的 2 级关联,则该解决方案特别有用。这是 1.2.x 文档。如果你使用的是 v1.3.x,你会发现它here

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-01-05
      • 1970-01-01
      • 2023-04-03
      • 1970-01-01
      • 2016-03-16
      • 1970-01-01
      • 2017-08-14
      相关资源
      最近更新 更多