重构 MySQL 中的 Rails 作用域方法 CASE-WHEN-THEN-ELSE-END

问题描述 投票:0回答:0

我正在使用 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 对记录进行排序?

mysql ruby-on-rails ruby refactoring sql-order-by
© www.soinside.com 2019 - 2024. All rights reserved.