以下内容之间有什么区别:
@user = User.find_by(["username = ?", params['username']])
User Load (0.5ms) SELECT "users".* FROM "users" WHERE (username = '2YY') LIMIT 1
和此:
@user = User.find_by(username: params['username'])
User Load (0.5ms) SELECT "users".* FROM "users" WHERE "users"."username" = '2YY' LIMIT 1
我看到的唯一区别是括号。这是如何摆脱糟糕的输入?我应该使用正则表达式来验证username
吗?例如。用户名只能包含文字或数字,我应该在转到数据库之前对此进行验证,还是@user = User.find_by(["username = ?", params['username']])
保护我?
而且,如果这两个查询具有相同的输出但第一个是安全的,那么第二个查询的重点是什么?
答案 0 :(得分:1)
存在差异,但正确引用params['username']
并非其中之一。在这两种情况下,ActiveRecord都会正确地转发用户名,因此您不必担心这一点。
一些差异:
find_by(['lower(username) = ?', x])
),布尔表达式(find_by('some_boolean_column and username = ?', x])
)等 - 那么第一个表单允许您使用它们,而第二种形式更有限。"users"
)并引用列名("username"
)。如果您有JOIN并且需要消除列名称的歧义,那么包括表名是很有用的。如果列名称区分大小写或包含特殊字符,则引用列名称很有用。使用像您一样的简单find_by
时,上述问题很少出现。第二种形式:
@user = User.find_by(username: params['username'])
通常是首选的,并且被认为是更多Railsy,因为它隐藏了数据库交互的细节,并允许您假装SQL不存在。
答案 1 :(得分:0)
在这种情况下,两种类型的语法在功能上都是等效的,并且两者都将使用Rails的内置SQL清理,因此用户无法做任何令人讨厌的事情。代表您无需进行额外的清理,只需确保您没有将param插入/连接到SQL片段中。