首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何清理Arel SQL?

如何清理Arel SQL?
EN

Stack Overflow用户
提问于 2021-05-04 03:10:44
回答 2查看 705关注 0票数 0

我有以下Arel SQL:

代码语言:javascript
复制
Arel.sql("(users.last_donated_at IS NOT NULL AND users.last_donated_at < '#{User::ACTIVE_DONOR_WITHIN_DAYS.days.ago}')")

当我运行brakeman时,会收到SQL Injection警告。我尝试了以下几种方法:

代码语言:javascript
复制
Arel.sql("(users.last_donated_at IS NOT NULL AND users.last_donated_at < ?)", User::ACTIVE_DONOR_WITHIN_DAYS.days.ago)

但是,我得到以下错误:

代码语言:javascript
复制
ArgumentError:
       wrong number of arguments (given 2, expected 1)

如何使用Arel清理sql语句?

EN

回答 2

Stack Overflow用户

发布于 2021-05-04 06:19:30

我是在回答我自己的问题。我正在使用Arel遵循Github wiki的Ransack gem。我正在做与文档中提到的2.2点非常相似的事情:https://github.com/activerecord-hackery/ransack/wiki/Using-Ransackers。为了清理参数并避免brakeman sql injection警告,我最终执行了以下操作:

代码语言:javascript
复制
Arel.sql(sanitize_sql_array("(users.last_donated_at IS NOT NULL AND users.last_donated_at < '#{User::ACTIVE_DONOR_WITHIN_DAYS.days.ago}')"))
票数 2
EN

Stack Overflow用户

发布于 2021-05-04 03:39:32

使用Arel.sql通常不是处理查询的最佳方式。在我看来,你不需要清理这个查询,你需要重构它。

您可以为rails where子句(以及大多数其他查询方法orderselect等)构建条件。在Arel中,使用方便的方法ModelName.arel_attribute(:attribute_name),这将允许您构建超出rails原生where Hash所提供的高级支持的查询条件。

这与

代码语言:javascript
复制
table_name = ModelName.arel_table
table_name[:attribute_name]

因此,让我们将其应用于您的查询:

根据您的查询,IS NOT NULL条件没有任何意义,因为您还使用了小于,因此我们可以将条件更改为仅使用小于例如。

代码语言:javascript
复制
User.arel_attribute(:last_donated_at).lt(User::ACTIVE_DONOR_WITHIN_DAYS.days.ago)

这之所以有效,是因为NULL不小于(或大于,甚至等于)任何值,因此这些结果将不会以任何方式显示。

如果您坚持IS NOT NULL条件,我们仍然可以通过以下方式使用Arel属性生成所需的SQL:

代码语言:javascript
复制
User.arel_attribute(:last_donated_at).not_eq(nil).and(
  User.arel_attribute(:last_donated_at).lt(User::ACTIVE_DONOR_WITHIN_DAYS.days.ago)
)
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67374536

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档