Rails 6 SQL 方法的语法

Syntax for Rails 6 SQL method

某些控制器操作出现以下警告。

DEPRECATION WARNING: Dangerous query method (method whose arguments are used as raw SQL) called with non-attribute argument(s): 
"CASE id WHEN 343[...]". Non-attribute arguments will be disallowed in Rails 6.0. 
This method should not be called with user-provided values, 
such as request parameters or model attributes. 

但是这个方法没有被“用户提供的”值调用:

def find_ordered(ids)
  order_clause = "CASE id "
  ids.each_with_index do |id, index|
    order_clause << "WHEN #{id} THEN #{index} "
  end
  order_clause << "ELSE #{ids.length} END"
  where(id: ids).order(order_clause)
end

它确实调用了模型属性。那么这个初始化方法的语法如何才能被 Rails 6 接受?

严格来说'user-provided value'但是Rails无法知道一个字符串是来自用户还是硬编码在程序中。

解决这个问题的方法是使用Arel.sql

Wrap a known-safe SQL string for passing to query methods, e.g.

where(id: ids).order(Arel.sql(order_clause))