如何确保开发人员在 CakePHP 中按外键进行过滤



在一个遗留项目中,我们遇到了一些问题,如果开发人员忘记了查询条件中的project_id,将显示所有项目的行 - 而不是他们要查看的单个项目。例如,对于"注释":

comments [id, project_id, message ]

如果您忘记按project_id筛选,您将看到所有项目。 这是通过测试捕获的,有时不是,但我宁愿做一个预防 - 开发人员应该立即看到"错误/空"!

为了解决这个问题,产品经理坚持使用单独的表进行评论,如下所示:

project1_comments [id,message]
project2_comments [id,message]

在这里,如果您忘记了项目/表名称,如果某些内容仍然通过测试并被部署,您将一无所获或错误。

但是,困难在于相关表。 链接到"注释"的示例"文件":

files [ id, comment_id, path ]
3,     1,   files/foo/bar
project1_comments
id    |   message
1     |  Hello World
project2_comments
id    |   message
1     |  Bye World

然后,这变成了每个项目的数据库,这似乎有点矫枉过正。

另一种可能性,如何在注释模型上添加行为以确保任何查找/选择查询都包含外键,例如 - project_id?

提前非常感谢。

在一个遗留项目中,我们遇到了一些问题,如果开发人员忘记了查询条件中的project_id

CakePHP 根据您为表定义的关联生成连接条件。当你使用包含时,它们是自动的,开发人员不太可能在CakePHP上犯这样的错误。

为了解决这个问题,产品经理坚持使用单独的表进行评论,如下所示:

别这样。对我来说似乎是一个非常糟糕的主意。

另一种可能性,如何在注释模型上添加行为以确保任何查找/选择查询都包含外键,例如 - project_id?

最简单的解决方案是禁止对Comments表进行所有直接查询。

class Comments extends Table {
public function find($type = 'all', $options = [])
{
throw new CakeNetworkExceptionForbiddenException('Comments can not be used directly');
}
}

之后只允许通过关联读取Comments(关联始终具有有效的连接条件),但在执行此操作之前请三思而后行,因为我看不到这种限制有任何好处。

您不能轻松地将对Comments的直接查询限制为仅在where子句中包含product_id的查询。问题是子句是一个表达式树,你必须遍历树并检查所有不同类型的表达式。这是一种痛苦。

我要做的是限制Comments,以便product_id必须作为选项传递给查找器。

$records = $Comments->find('all', ['product_id'=>$product_id])->all();

上面所做的是将$product_id作为选项传递给表的默认findAll方法。我们可以覆盖该方法,并强制product_id作为所有直接评论查询的必需选项。

public function findAll(Query $query, array $options)
{
$product_id = Hash::get($options, 'product_id');
if (!$product_id) {
throw new ForbiddenException('product_id is required');
}
return $query->where(['product_id' => $product_id]);
}

我没有看到通过行为完成上述操作的简单方法,因为where子句在执行行为时仅包含表达式。

最新更新