CakePHP:ContainableBehavior查询结构/连接

时间:2012-05-09 20:56:52

标签: cakephp join model containable

我的应用程序的数据模型

  • 群组拥有多个用户
  • 用户所属组
  • 用户有多次打卡
  • Punch belongsTo User
  • Punch belongsTo PayPeriod
  • PayPeriod hasMany Punch

查找电话

$groups = $this->Group->find('all', array( 'contain' => array(
    'User' => array(
        'Punch' => array(
            'conditions' => array(
                'Punch.payperiod_id' => null
            )
        )
    )

)));

查询调试

SELECT `Group`.`id`, `Group`.`name` 
FROM `pclock`.`groups` AS `Group` 
WHERE 1 = 1 ORDER BY `name` ASC

SELECT `User`.`id`, `User`.`name`, `User`.`group_id` 
FROM `pclock`.`users` AS `User` 
WHERE `User`.`group_id` IN (4, 3, 5, 2, 1)

SELECT `Punch`.`id`, `Punch`.`user_id`, `Punch`.`time_in`, `Punch`.`time_out`, `Punch`.`payperiod_id` 
FROM `pclock`.`punches` AS `Punch` 
WHERE `Punch`.`payperiod_id` IS NULL AND `Punch`.`user_id` IN (1, 2, 3, 4, 5)

一旦我的应用程序扩展到数百个拥有数千个打孔器的用户,这些查询就会变得非常低效。我希望Containable可以执行以下查询:

查询我更喜欢

SELECT 
    Group.id, Group.name, 
    User.id, User.name, User.group_id, 
    Punch.id, Punch.user_id, Punch.time_in, Punch.time_out, Punch.payperiod_id 
FROM groups AS Group
LEFT JOIN users AS User 
    ON (Group.id = User.group_id)
LEFT JOIN punches AS Punch 
    ON (User.id = Punch.user_id)
WHERE Punch.payperiod_id IS NULL

有没有办法优化这个? options数组中的join属性似乎被忽略,并且手动连接而没有Containable返回非分层结果。

2 个答案:

答案 0 :(得分:2)

这是可以容纳的作品。您可以在查找中使用join params或查找为您执行连接的可链接行为。

https://github.com/rafaelbandeira3/linkable

答案 1 :(得分:2)

您可以手动加入:

$groups = $this->Group->find('all', array(
    'fields'=>array(
        'Group.id', 'Group.name', 'User.id', 'User.name', 'User.group_id', 
        'Punch.id', 'Punch.user_id', 'Punch.time_in', 'Punch.time_out',
        'Punch.payperiod_id'
    ),
    'conditions'=>array(
        'Punch.payperiod_id IS NULL'
    ),
    'joins'=>array
        array(
           'table'=>'users',
           'alias'=>'User',
           'conditions'=>array(
               'Group.id = User.group_id'
           )
        ),
        array(
            'table'=>'punches',
            'alias'=>'Punch',
            'conditions'=>array(
                'User.id = Punch.user_id'
            )
        )
    )
));