我正在开发一个基本的 Rails 4.0 应用程序以了解它是如何工作的,但我遇到了一些我似乎无法弄清楚的事情。我一直在通过 ActiveRecord 对默认的 Sqlite DB 进行查询,对于大多数查询,根据调试输出,它似乎会生成参数化查询,如下所示:
2.0.0-p247 :070 > file.save
(0.2ms) begin transaction
SQL (0.6ms) UPDATE "rep_files" SET "report_id" = ?, "file_name" = ?, "updated_at" = ?
WHERE "rep_files"."id" = 275 [["report_id", 3], ["file_name", "hello.jpg"],
["updated_at", Mon, 09 Sep 2013 04:30:19 UTC +00:00]]
(28.8ms) commit transaction
但是,每当我使用 find_by 进行查询时,似乎只是将提供的参数粘贴到生成的 SQL 中:
2.0.0-p247 :063 > file = RepFile.find_by(report_id: "29", file_name: "1.png")
RepFile Load (6.2ms) SELECT "rep_files".* FROM "rep_files" WHERE
"rep_files"."report_id" = 29 AND "rep_files"."file_name" = '1.png' LIMIT 1
它似乎确实正确地转义了参数以防止 SQL 注入:
2.0.0-p247 :066 > file = RepFile.find_by(report_id: "29", file_name: "';")
RepFile Load (0.3ms) SELECT "rep_files".* FROM "rep_files" WHERE
"rep_files"."report_id" = 29 AND "rep_files"."file_name" = ''';' LIMIT 1
但是,据我了解,将参数化查询发送到数据库被认为是比尝试转义查询字符串更好的选择,因为参数化选项将导致查询数据完全绕过数据库的解析引擎。
那么这里发生了什么?这是 Sqlite 适配器中的一些奇怪之处还是生成调试输出的方式?如果 ActiveRecord 确实是这样工作的,有什么原因吗?我在任何地方都找不到有关此的任何信息。我已经开始查看 ActiveRecord 代码,但还没有弄清楚任何事情。