2

我在我的模型中定义了这些关系:

Lead hasMany Job
Job Job HABTM 员工
Job HABTM Truck

我正在尝试find('all')从我的卡车模型中做一个,并将结果限制为:

  1. 所有卡车,
  2. 与具有特定取货日期的卡车相关的所有工作,
  3. 分配到这些工作的员工,
  4. 以及与该工作相关的潜在客户。

这是我的查找操作:

// app/models/truck.php
$this->find('all', array(
    'contain' => array(
        'Job' => array(
            'Employee',
            'Lead',
            'conditions' => array(
                'Job.pickup_date' => $date
            )
        )
    )
));

出于某种原因,Cake 执行查询以查找员工 TWICE。这导致所有员工在每项工作中代表两次。这是 SQL 转储:

  1. SELECT `Truck`.`id`, `Truck`.`truck_number`
    FROM   `trucks` AS `Truck`
    WHERE  1 = 1;
  2. SELECT `Job`.`id`, `Job`.`lead_id`, `Job`.`city`,
           `JobsTruck`.`id`, `JobsTruck`.`job_id`, `JobsTruck`.`truck_id`
    FROM   `jobs` AS `Job`
    JOIN   `jobs_trucks` AS `JobsTruck` ON (`JobsTruck`.`truck_id` IN (2, 3)
    AND    `JobsTruck`.`job_id` = `Job`.`id`)
    WHERE  `Job`.`pickup_date` = '2010-10-06'
  3. SELECT `Lead`.`id`, `Lead`.`name`, `Lead`.`created` FROM `leads` AS `Lead`
    WHERE  `Lead`.`id` = 4
  4. SELECT `Employee`.`id`, `Employee`.`name`, `Employee`.`created`,
           `EmployeesJob`.`id`, `EmployeesJob`.`employee_id`,
           `EmployeesJob`.`job_id`
    FROM   `employees` AS `Employee`
    JOIN   `employees_jobs` AS `EmployeesJob`
           ON (
               `EmployeesJob`.`job_id` = 1 AND
               `EmployeesJob`.`employee_id` = `Employee`.`id`
           )
  5. SELECT `Lead`.`id`, `Lead`.`name`, `Lead`.`created` FROM `leads` AS `Lead`
    WHERE  `Lead`.`id` = 4
  6. SELECT `Employee`.`id`, `Employee`.`name`, `Employee`.`created`,
           `EmployeesJob`.`id`, `EmployeesJob`.`employee_id`,
           `EmployeesJob`.`job_id`
    FROM   `employees` AS `Employee`
    JOIN   `employees_jobs` AS `EmployeesJob`
           ON (
               `EmployeesJob`.`job_id` = 1 AND
               `EmployeesJob`.`employee_id` = `Employee`.`id`
           )

请注意,最后两个查询是重复的。我做错了什么我错过了吗?

更新
似乎 Cake 为每辆卡车发送了一个重复的查询。现在我在卡车表中有 15 条记录,对leads和的查询employees每个重复 15 次。

4

3 回答 3

3

我不知道为什么有两个重复的查询,但也许这种行为会有所帮助:

https://github.com/Terr/linkable

更新

这种问题是众所周知的:

于 2010-11-20T21:19:44.460 回答
1

没有什么可以加入Job/s到特定的Truck.

(我希望我的解释不会太难理解,但 CakePHP 有时可能是这样的!恕我直言)

Jobs几乎以任意方式归因于(我对 Cake的Trucks记忆是这可能发生);HABTM 调用的性质将 附加Job/s到 15 中的每一个Trucks。从我的角度来看,这似乎是当前的过程;

  • 获得所有卡车。
  • 获取日期为x的卡车的所有工作。
  • [问题 1] 将找到的附加Jobs到每个Truck(即您的 15 辆卡车)上,但附加到每个Truck.
  • [问题 2]再次获取与该工作相关的所有潜在客户/员工Truck

问题1:问题的根源。您可以在第二个查询 (SELECT Job...) 中看到,它在 ON 语句中使用了正确truck_id的 's,但 Cake 无法将这些“加入”Jobs回 right Truck,因为它是一个不同的查询!因此,它将找到的工作加入到每个Truck.

问题 2:这是“真正的”问题,因为 Cake 不构造长的 JOIN 语句,所以没有办法只为你想要的那些找到Employees/ 。这就是为什么它会为每辆卡车找到它们,这是因为你正在做一个on 。LeadsTrucksFindAllTruck

我希望这是有道理的。您需要在 上进行查找Jobs,因为那是查询的“中心”(pickup_date)。

$this->loadModel('Job');
$whatev = $this->Job->find('all', array(
    'contain' => array(
        'Job' => array(
            'Truck',
            'Employee',
            'Lead',
            'conditions' => array(
                'Job.pickup_date' => $date
            )
        )
    )
));

CakePHP 查询实际上只有在您找到某个模型的一个/全部时才起作用,如果您有双重 HABTM 关系,最好从中间开始并在任一侧工作。如果您希望按卡车“排序”,那么您可能必须编写自己的查询(模型方法)来自己完成任务。在原始 SQL 中,这个查询可能很容易,在抽象的 PHP 超级蛋糕中,这对于 CakePHP 来说是难以允许的。

正如他们所说,快乐烘焙!

于 2010-11-24T15:28:10.007 回答
-3

您想要 LEFT JOIN 而不是 JOIN。

不要问我如何在 cakephp 中做到这一点,我很高兴我的代码目前可以正常工作。^^

于 2010-11-22T20:11:58.913 回答