我正在使用 MySQL 并将我的应用程序升级到 Rails 7。这样做时,我必须在我的范围方法中重构一些与订单相关的查询。
在 Rails 7 之前,我使用以下范围方法(称之为“原始范围方法”):
scope.order(sanitize_sql_array(["CASE articles.author_id WHEN ? THEN 1 ELSE 2 END", author.id]))
在 Rails 7 中,上述语句引发错误:
ActiveRecord::UnknownAttributeReference(危险的查询方法 (其参数用作原始 SQL 的方法)使用非属性调用 argument(s): "CASE articles.author_id WHEN '3784' THEN 1 ELSE 2 END”。不应使用用户提供的值调用此方法,例如 作为请求参数或模型属性。已知安全值可以是 通过将它们包装在 Arel.sql() 中来传递。):
在这些情况下,Rails 7 中可能会派上用场的是新添加的方法
in_order_of
。所以,原来的范围方法可能变成:
scope.in_order_of(:author_id, [author.id])
然而,这个
in_order_of
方法向SQL查询添加了一个(unwanted)WHERE子句,即以下查询中的“AND'articles'.'author_id'”部分:
SELECT `articles`.* FROM `articles`
WHERE (articles.some_other_column >= 10) AND `articles`.`author_id` IN (3784)
ORDER BY FIELD(`articles`.`author_id`, 3784) DESC
附加 WHERE 子句的(unwanted)效果是从查询结果中删除我在 Rails 7 之前使用原始范围方法时存在的所有记录,即在上面的示例中,作者 ID 不是 3784被忽略但应该出现在查询结果中。
我如何在 Rails 7 中构建/重构与我之前在 Rails 7 中使用的原始“CASE-WHEN-THEN-ELSE-END”等效的范围方法,以便按给定的作者 ID 对记录进行排序?