我有这个查询:
@members = Member.where("EXTRACT(DOY FROM date_of_birth) >= ?", next_bdays).order('EXTRACT (DOY FROM date_of_birth) ASC').first(5)
出现错误:
DEPRECATION WARNING: Dangerous query method (method whose arguments are used as raw SQL) called with non-attribute argument(s): "EXTRACT (DOY FROM (Arel.sql \"DATE(date_of_birth)\")) ASC". 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. Known-safe values can be passed by wrapping them in Arel.sql().
该怎么办?如何将date_of_birth
包装在Arel中?
答案 0 :(得分:2)
根据DEPRECATION,您可以将其包装如下:
.order(Arel.sql('EXTRACT (DOY FROM date_of_birth) ASC'))
甚至
.order(Arel.sql('EXTRACT (DOY FROM date_of_birth)').asc)
但是我将更进一步,并遵循以下要求:
custom_clause = Arel::Nodes::NamedFunction.new('EXTRACT',
[Arel::Nodes::SqlLiteral.new("DOY FROM members.date_of_birth")]
)
这将产生所需的SQL,并且可以像where子句一样重复使用
@members = Member
.where(custom_clause.gteq(next_bdays))
.order(Arel.sql(custom_clause.to_sql).asc)
.first(5)
这将产生以下查询。 (假设next_bdays == 123
)
SELECT
members.*
FROM
members
WHERE
EXTRACT(DOY FROM members.date_of_birth) >= 123
ORDER BY
EXTRACT(DOY FROM members.date_of_birth) ASC
LIMIT 5
Some Raw SQL will be acceptable,只要它遵循标准的column_name或table.column_name语法Whitelist can be found here,并且一如既往,也将支持Arel对象Reference