Rails ActiveRecord:如何在jsonb上使用带双引号的绑定变量
我有一个postgres jsonb查询如下:
Blog.where("upload_data @> '[ { \"name\": \"#{name}\" }]'")
哪个有效,但打破了构建,因为优秀的制动员指出了可能的SQL注入风险。 如果我使用绑定变量:
Blog.where("upload_data @> '[ { \"name\": ? }]'", name)
它创建一个SQL查询,如:
WHERE upload_data @> '[ { "name": 'name' }]'
请注意单引号 – 这是一个无效的查询
如果我使用单引号,我得到:
WHERE upload_data @> "[ { 'name': 'name' }]"
这是无效的
我尝试了一些其他的东西,但我想要的是绑定变量计算为双引号的字符串:
WHERE upload_data @> '[ { "name": "name" }]'
或者一个不同的解决方案 – 除了让刹车手跳过文件。
您不能将参数占位符放在带引号的字符串中。
Rails允许您执行此操作并在单引号字符串中替换单引号字符串这一事实表明Rails(通常)无法理解SQL规则。
但是您可以将参数占位符放在表达式中,并使用其他字符串。 我不是常规的PostgreSQL用户,但我假设您可以将字符串连接在一起以形成完整的JSON文字:
Blog.where("upload_data @> '[ { \"name\": \"' || ? || '\"}]'", name)
如果参数化整个JSON值,您可能会发现它使代码更加清晰。 使用%Q()
来避免需要反斜杠文字双引号。
Blog.where("upload_data @> ?", %Q([ { "name": "#{name}" } ]))
或者为了确保生成有效的JSON,我将表达式放在Ruby语法中,然后转换为JSON:
Blog.where("upload_data @> ?", JSON.generate( [{name: name}] ))