Dangerous query method called with non-attribute argument(s)
踩坑 query method。
问题描述
现有model issue,需要对issues进行排序,根据指定的ID集合来决定记录的位置,比如id包含在(4, 6, 9)中的纪录就排在前面,剩下的排在后面。
使用scope进行处理:
class Issue < ApplicationRecord
.........
IDLIST = [4, 6, 9]
scope :order_by_custom_id, -> {
order_by = ['CASE']
order_by << "WHEN id in (#{IDLIST.join(', ')}) THEN 0"
order_by << 'ELSE 1 END'
order(order_by.join(' '))
}
end
在controller中调用了该scope。刷新页面后,发现服务器报出warning message:
DEPRECATION WARNING: Dangerous query method (method whose arguments are used as raw SQL) called with non-attribute argument(s): "CASE WHEN id in (4,6,9) THEN 0 ELSE 1 END". 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().
解决方法
其实,报错信息里面已经告诉我解决方法了,但是当时一看懵逼,Dangerous query method?!直接Google了一堆,后面在slack上跟同事求助了下,搞定!
很简单,就是使用warning message里面提到的Arel.sql()方法,将CASE WHEN id in (4,6,9) THEN 0 ELSE 1 END 用Arel.sql() 包起来即可。
修改scope:
class Issue < ApplicationRecord
.........
IDLIST = [4, 6, 9]
scope :order_by_custom_id, -> {
order_by = ['CA 大专栏 Dangerous query method called with non-attribute argument(s)SE']
order_by << "WHEN id in (#{IDLIST.join(', ')}) THEN 0"
order_by << 'ELSE 1 END'
order(Arel.sql(order_by.join(' ')))
}
end
OK!
但是,这个Arel.sql(raw_sql)是什么?
先看看Arel是什么。
官方文档的解释:
Arel is a SQL AST manager for Ruby. It
- Simplifies the generation of complex SQL queries
- Adapts to various RDBMSes
文档里面还列出了很多例子,从简单的select * from users 到复杂点的joins table,我猜是因为我接触Rails的时间不长,反正是从来没用过这东西。
Arel.sql(raw_sql) 这个类方法的源代码如下:
def self.sql raw_sql
Arel::Nodes::SqlLiteral.new raw_sql
end
也就是新建了一个Arel::Nodes::SqlLiteral实例,而Arel::Nodes::SqlLiteral为什么是安全的呢?用Arel::Nodes::SqlLiteral 把raw_sql包起来的用意是什么?估计也能猜到,防攻击啥的。果然,Google了下,发现说是可以防止SQL注入的情况。
有些复杂了,脑子暂时消化不了。
此外,文档中有关sanitize_limit 部分也有提到SQL injection的问题。
参考
A “strict Arel” mode for ActiveRecord to prevent SQL injection vulnerabilities
Dangerous query method called with non-attribute argument(s)的更多相关文章
- C#编译问题'System.Collections.Generic.IEnumerable' does not contain a definition for 'Where' and no extension method 'Where' accepting a first argument
'System.Collections.Generic.IEnumerable<string>' does not contain a definiti ...
- 【spring data jpa】repository中使用@Query注解使用hql查询,使用@Param引用参数,报错:For queries with named parameters you need to use provide names for method parameters. Use @Param for query method parameters, or when on
在spring boot中, repository中使用@Query注解使用hql查询,使用@Param引用参数 如题报错: For queries with named parameters you ...
- 编译问题:'<invalid-global-code>' does not contain a definition for 'Store' and no extension method 'XXX' accepting a first argument of type '<invalid-global-code>' could be found
这是VS2015上的bug. 我碰到的时候,是VS在合并两个分支的代码时,多加了一个}.导致编译语法报错.. 解决办法就是在错误的附近,找找有没有多余的大括号,删掉即可. 这个问题在vs2017上面没 ...
- 深入浅出Attribute(三)
约定: 1.”attribute”和”attributes”均不翻译 2.”property”译为“属性” 3.msdn中的原句不翻译 4.”program entity”译为”语言元素” Attri ...
- Using dojo/query(翻译)
In this tutorial, we will learn about DOM querying and how the dojo/query module allows you to easil ...
- Segment Tree Query I & II
Segment Tree Query I For an integer array (index from 0 to n-1, where n is the size of this array), ...
- Lintcode: Segment Tree Query II
For an array, we can build a SegmentTree for it, each node stores an extra attribute count to denote ...
- Lintcode: Segment Tree Query
For an integer array (index from 0 to n-1, where n is the size of this array), in the corresponding ...
- Attribute的理解和认识
1什么是Attribute? 在网上看到这样一段定义 MADN的定义为:公共语言运行时允许添加类似关键字的描述声明,叫做attributes, 它对程序中的元素进行标注,如类型.字段.方法和属性等.A ...
随机推荐
- centos7 安装gdb (调试nginx)
首先卸载原有的gdb,sudo yum remove gdb 从gnu官网下载最新的gdb源文件,wget http://mirrors.ustc.edu.cn/gnu/gdb/gdb-7.9.1.t ...
- maven打包springboot项目的插件配置概览
jar包的术语背景: normal jar: 普通的jar,用于项目依赖引入,不能通过java -jar xx.jar执行,一般不包含其它依赖的jar包. fat jar: 也叫做uber jar,是 ...
- 深度学习数据集MNIST ImageNet COCO PASCAL VOC介绍
参考文档 深度学习数据集汇总介绍 1. MNIST 深度学习领域的“Hello World!”,入门必备!MNIST是一个手写数字数据库,它有60000个训练样本集和10000个测试样本集,每个样本 ...
- input标签添加上disable属性在移动端(ios)字体颜色及边框颜色不兼容的解决办法。
手机一些兼容性问题: 1.苹果手机输入框input:disabled显示模糊问题 input:disabled, input[disabled]{ color: #5c5c5c; -webkit-te ...
- 34)static 静态成员和静态成员函数
1) static修饰的方法,只能在这个文件中使用,比如你是多文件编程,别的文件即使引入了我的 .h文件 但那时我的static方法也是不能用 2)C++的static的成员变量 比如 sta ...
- 13)PHP,文件加载(include和require)
有四种文件加载的语法形式(注意,不是函数): include, include_once, require, require_once; 他们的本质是一样的,都是用于加载/引入/包含/载入一个外部 ...
- ServletUtils
package com.ruoyi.common.utils; import java.io.IOException; import javax.servlet.http.HttpServletReq ...
- RPC,基于消息,远程访问方式比较
远程访问 1.RPC方式 客户端调用远程方法和客户端调用本地方法形式是一样的,当然了底层需要封装通讯协议及数据转换的过程,这个一般由框架完成,可以简化开发, 这种方式本质也是通过通讯协议发消息给对方的 ...
- oBike退出新加坡、ofo取消免押金服务,全球共享单车都怎么了?
浪潮退去后,才知道谁在裸泳.这句已经被说烂的"至理名言",往往被用在一波接一波的互联网热潮中.团购.O2O.共享单车.共享打车.无人货柜--几乎每一波热潮在退去后会暴露出存在的问题 ...
- 爬虫笔记(十一)——认识cookie
什么是cookie? 在爬虫的使用中,如果涉及登录等操作时,经常会使用到cookie.简单的来说,我们访问每一个互联网页面,都是通过HTTP协议进行的,而HTTP协议是一个无状态协议,所谓的无状态协议 ...