我有一种情况需要允许从表单手动构建SQL。我有这样的事情:
SomeModel.where("id in (#{custom_sql})")
其中custom_sql
是一个select语句,如下所示:
SELECT u.id FROM some_model u WHERE country_iso = 'AU'
我希望能够捕获where子句中存在无效SQL时抛出的StatementInvalid异常,但我无法弄清楚如何执行此操作。
begin
SomeModel.where("id in (#{custom_sql})")
rescue
puts "Error"
end
但它一直没有出错。但是在rails c
中,当我执行User.where("id in (#{custom_sql})")
时,它会正确错误。有什么想法吗?
答案 0 :(得分:2)
使用ActiveRecord::Base.connection.execute
检查SQL语句的有效性。如果您的陈述无效,则会抛出错误。
begin
ActiveRecord::Base.connection.execute custom_sql
User.where("id in (#{custom_sql})")
rescue
puts "Error"
end
答案 1 :(得分:1)
首先,您的示例不清楚或具有误导性(可能是因为您努力掩盖您的实际型号名称)
因为如果您真的想要运行您提出的方案,那么您的结果查询将是
select * from some_model where id in (select u.id from some_model u where country_iso = "AU"
(忽略你的country_iso
字段不明确的事实)你刚刚开始
SomeModel.where country_iso: "AU"
因此,您需要优化您的示例并正确说明您的问题,因为虽然@zeantsoi建议了一种方法来帮助您验证您的陈述,但我同意@phoet您可能错误地接近了这种情况。
答案 2 :(得分:0)
首先,这是sql注入最好的。你应该重新考虑你想要完成的任何事情。
其次,User.where
返回一个关系。关系是懒惰的。懒惰的语句尚未执行。所以,如果你正在做User.where(...).all
这应该有所帮助。