1

我正在尝试尽可能将其作为 MVC / CakePHP 2 来做,所以如果我的方法不正确,我很想知道(仍在学习)。我觉得我正在做的事情应该发生在模型中,而不是控制器中(遵循胖模型瘦控制器原则)。

我在两个表之间有一个 hasMany 关系:

trainings hasMany days.

如果我想整天都在训练中,这个设置可以按预期工作。

但我想要(在每一次训练中)训练的第一天。我的想法是在Training模型中设置一个 hasOne 关系,如下所示:

public $hasOne = array(
    ...
    'FirstDay' => array(
      'className' => 'Day',
      'foreignKey' => 'training_id',
      'fields' => 'FirstDay.training_date',
      'order' => array('FirstDay.training_date ASC'),
    )
);

本质训练有一天作为FirstDay

我假设通过这种设置,如果我调用一个Training对象,我将获得关联的FirstDay.

相反,我得到了多个条目Training——一个给定培训的每个天数实例。得到输出的SQL如下:

SELECT `Training`.`id`, `Training`.`course_id`, `Course`.`name`, ...  `FirstDay`.`training_date`
  FROM `tst`.`trainings` AS `Training`
  LEFT JOIN `tst`.`courses` AS `Course` ON (`Training`.`course_id` = `Course`.`id`)
  ...
  shortened for your benefit
  ...
  LEFT JOIN `tst`.`days` AS `FirstDay` ON (`FirstDay`.`training_id` = `Training`.`id`)
  WHERE 1 = 1 ORDER BY `FirstDay`.`training_date` ASC LIMIT 20

我假设 hasOne 会在上述条款中设置限制 1 而不是 20。由于没有,我尝试添加 a'limit' => 1但这不起作用,并且文档没有提到它作为 hasOne 关系中的一个选项。我也不明白为什么WHERE 1 = 1会这样,但我认为这并不重要,因为它是一个不限制任何东西的真实陈述——似乎是不必要的提升。

4

1 回答 1

0

关系类型hasOne是用 a 实现的LEFT JOIN,因此不能LIMIT作为选项支持,因为它会影响整个查询(不仅限制,Day而且Training也限制)。

有几种方法可以解决您的问题。最简单的是将您的关联定义为hasMany,但设置'limit'=>1

public $hasMany = array(
    'FirstDay' => array(
        'className' => 'Day',
        'foreignKey' => 'training_id',
        'fields' => 'FirstDay.training_date',
        'order' => array('FirstDay.training_date ASC'),
        'limit' => 1
    )
);

[0](可选)然后,您可以通过Hash::map()在 之后使用来摆脱额外的数字索引find()

$this->Training->contain('FirstDay');
$trainings=$this->Training->find('all');

$trainings = Hash::map($trainings, "{n}", function($arr){
        $arr['FirstDay']=$arr['FirstDay'][0];
        return $arr;
    });

有关其他可能的选项,请参阅:

于 2015-12-20T13:28:47.047 回答