【问题标题】:CakePHP 3 find() with beforeFind() callback SQL issueCakePHP 3 find() 和 beforeFind() 回调 SQL 问题
【发布时间】:2016-05-10 04:57:48
【问题描述】:

当我在控制器中使用 find() 和行为回调中的 beforeFind() 时,我遇到了数据完整性问题。 WHERE Submissions.site_id 没有像应有的那样添加到 WHERE 子句中。根据设置 WHERE 子句的位置,我得到不同的结果集。

在我的 SubmissionsController 中:

public function index()
{

    $query = $this->Submissions->find('all')
                ->where(['user_id' => $this->Auth->user('id')])
                ->contain(['Users', 'Categories']);

    $this->set('submissions', $this->paginate($query));

}

在我的 beforeFind() 模型回调中(作为 'TenantBehavior' 附加到

$query->where([$this->_table->alias().'.'.'site_id' => 3]);

问题在于,通过上述方式,生成的 SQL 将“WHERE”子句作为 AND 放在 JOIN 条件上,就像这样,而不是实际 WHERE:

...
FROM 
submissions Submissions 
INNER JOIN users Users ON (
Users.id = (Submissions.user_id) 
AND Users.site_id = 3
) 
INNER JOIN categories Categories ON (
Categories.id = (Submissions.category_id) 
AND Categories.site_id = 3
) 
WHERE 
user_id = 315 

如果我删除 beforeFind() ->where 并将其放置在控制器上 ->我得到预期的 SQL 和结果集,如下所示:

...
FROM 
submissions Submissions 
INNER JOIN users Users ON (
Users.id = (Submissions.user_id) 
AND Users.site_id = 3
) 
INNER JOIN categories Categories ON (
Categories.id = (Submissions.category_id) 
AND Categories.site_id = 3
) 
WHERE 
(
user_id = 315 
AND Submissions.site_id = 3
) 

想法?有什么建议吗?

编辑 根据@ndm 的建议,我开始更新并提供更多上下文。在这样做的过程中,我发现(像个白痴一样)我在“SubmissionsTable”模型上缺少$this->addBehavior('Tenant');。添加这个当然解决了这个问题。

【问题讨论】:

  • 之前的 find 回调到底在哪里(在哪个类中)?看起来像是一种行为?如果是这样,那么它是在哪里以及如何加载的?回调中的其余代码是什么样的?请始终包含足够的代码和信息,以便人们能够重现该问题!另外,请始终提及您的 准确 CakePHP 版本并相应地标记您的问题!
  • 哇。谢谢。我开始更新更多信息(我是新来的),正如你提到的那样,当我开始表明确实在模型的行为中添加了 beforFind() 代码时,我发现我实际上并没有将 '$this->addBehavior('Tenant')' 行添加到我的 SubmissionsTable。您要求更多信息帮助我意识到我的菜鸟错误。非常感谢,吸取教训!

标签: cakephp cakephp-3.x


【解决方案1】:
$query = $this->Submissions->find('all', [
            'conditions' => [
                 'user_id' => $this->Auth->user('id')
             ],
             'contain' => [
                  'Users',
                  'Categories',
             ]
         ]);

将条件作为内联数组传递将解决您的问题,并将 beforeFind() 附加到条件正确的位置。

【讨论】:

  • 当它有效地创建与流体界面构建的查询相同的查询时,它将如何解决问题?在发布代码示例时,请始终添加至少一个简短的解释!
  • @diomedes,我试过了,但还是遇到同样的问题?
猜你喜欢
  • 1970-01-01
  • 2016-06-19
  • 2015-03-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多