CakePHP:afterFind与联想很奇怪

CakePHP:afterFind与联想很奇怪,cakephp,associations,Cakephp,Associations,因此,当我在相应的模型/控制器中时,afterFind工作得很好。但是,调用关联模型时,发送到afterFind回调的数据的格式不同。这会导致afterFind失败,因为它无法找到与在原始模型/控制器中工作时相同的数组索引 有人知道为什么,或者修复可能是什么吗?这是afterFind回调的第二个参数的作用 $primary告诉您查找是直接从此模型调用的(true),还是由关联模型调用的(false) 书中的注释: $primary参数指示当前模型是否为 查询所基于的模型,或者是否使用此模型 已作

因此,当我在相应的模型/控制器中时,afterFind工作得很好。但是,调用关联模型时,发送到afterFind回调的数据的格式不同。这会导致afterFind失败,因为它无法找到与在原始模型/控制器中工作时相同的数组索引


有人知道为什么,或者修复可能是什么吗?

这是
afterFind
回调的第二个参数的作用

$primary
告诉您查找是直接从此模型调用的(true),还是由关联模型调用的(false)

书中的注释:

$primary参数指示当前模型是否为 查询所基于的模型,或者是否使用此模型 已作为关联查询。如果模型被查询为 关联$结果的格式可能不同

期望$primary为true的代码可能会得到一个“cannotuse” 字符串偏移量作为数组“如果递归查找 使用


因此,根据
$primary

$primary
的值,您可能需要不同的处理逻辑,这可能不是很有帮助;我发现在第一个深度之外使用containableBehavior时总是
false

$this->Model->find('first', array(
  'contain' => array(
    'SecondaryModel' => array(
      'TertiaryModel',
    ),
  ),
));
如果要基于相关模型设置值,则可以检查其是否存在,以处理以下任一结构:

function afterFind($results, $primary) {
  if (isset($results['TertiaryModel'])) {
    $results['secondary_model_field'] = 'value';
  }
  else {
    foreach ($results as &$result) {
      if (is_array($result) && isset($result['TertiaryModel'])) {
        $result[$this->alias]['secondary_model_field'] = 'value';
      }
    } unset($result);
  }

  return $results;
}

或者,您可以只检查模型本身上字段的位置。如果该字段在顶层不存在,则需要对结果集进行迭代。

Cake 2.6似乎包括,以确保所有
$results
数组的格式一致。我对RC版本做了一些测试,它看起来确实有效,所有数组都以
{n}.ModelName.data
的格式传递

默认情况下会启用修复程序,但如果需要,也可以恢复到旧行为。只需将以下内容添加到模型(或AppModel)定义中:

public $useConsistentAfterFind = false;

此外,我还发现,
$primary==false
并不一定意味着数据的格式与数据为true时的格式不同。可能是,但这取决于发现。那么这个问题还没有解决吗?对我来说,有时afterFind$results返回多维数组,有时返回键值数组。正如这里所说,$primary标志始终为false,因为我使用的是containable。对此问题的任何更新都将不胜感激。我写了这个关于CakePHP1.3的答案,但我认为在2.0中没有任何变化。唯一的解决方案是检查是否存在已知密钥,以确定结果是单个结果还是一组结果,并对其进行适当的操作。提供了一种解决方案,似乎是防止代码片段所需的代码重复的好方法。我检查了主代码,在两种不同的情况下,我得到了主错误,结果结构不同。我认为我能解决这个问题的唯一方法就是像这里的人建议的那样检查结果的结构。