在Rails 3 / ActiveRecord中构建LIKE查询时,转义%%的正确方法



我想将url字段与url前缀(可能包含百分号)匹配,例如.where("url LIKE ?", "#{some_url}%")。最适合Rails的方式是什么?

来自Rails版本4.2。x有一个活动记录方法称为sanitize_sql_like。因此,您可以在模型中执行如下搜索范围:

scope :search, -> search { where('"accounts"."name" LIKE ?', "#{sanitize_sql_like(search)}%") }

和像

这样调用作用域
Account.search('Test_%')

结果转义的sql字符串是:

SELECT "accounts".* FROM "accounts" WHERE ("accounts"."name" LIKE 'Test_%%')

阅读更多:http://edgeapi.rubyonrails.org/classes/ActiveRecord/Sanitization/ClassMethods.html

如果我理解正确,您担心"%"出现在some_url中,这是正确的;你也应该担心嵌入的下划线("_"),它们是正则表达式中"。"的LIKE版本。我不认为有任何rails特定的方式来做到这一点,所以你只剩下gsub:

.where('url like ?', some_url.gsub('%', '\\%').gsub('_', '\\_') + '%')

这里也不需要字符串插值。您需要双反斜杠来从数据库的字符串解析器转义它们的含义,以便LIKE解析器将看到简单的"%"并知道忽略转义的百分号。

你应该检查你的日志,以确保两个反斜杠通过。我从检查irb中的东西得到令人困惑的结果,使用五(!)得到正确的输出,但我看不出其中的意义;如果有人真的看到了其中五个的意义,请给予解释性的评论。

UPDATE: Jason King为转义转义字符的噩梦提供了一个简化。这允许您指定一个临时转义字符,以便您可以执行以下操作:

.where("url LIKE ? ESCAPE '!'", some_url.gsub(/[!%_]/) { |x| '!' + x })

我也切换到gsub的块形式,使它不那么讨厌。

这是标准的SQL92语法,因此可以在任何支持它的数据库中工作,包括PostgreSQL, MySQL和SQLite。

将一种语言嵌入到另一种语言中总是有点像噩梦般的拼凑,而且你对此无能为力。生活中总会有一些丑陋的小细节,你只能勉强忍受。

https://gist.github.com/3656283

在这个代码中,

Item.where(Item.arel_table[:name].matches("%sample!%code%"))

正确转义"sample"one_answers"code"之间的%,并匹配"AAAsample%codeBBB",但不为"AAAsampleBBBcodeCCC"在MySQL, PostgreSQL和SQLite3至少。

Post.where('url like ?', "%#{some_url + '%'}%)

相关内容

  • 没有找到相关文章

最新更新