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

|| 我想将网址字段与网址前缀(可能包含百分号)进行匹配,例如
.where(\"url LIKE ?\", \"#{some_url}%\")
。 最Rails的方式是什么?
已邀请:
如果我理解正确,您担心\“%\”出现在
some_url
内,这是正确的;您还应该担心嵌入式下划线(\“ _ \”),它们是正则表达式中\“。\”的类似版本。我不认为有任何特定于Rails的方式可以这样做,所以您只剩下
gsub
.where(\'url like ?\', some_url.gsub(\'%\', \'\\\\\\\\\\%\').gsub(\'_\', \'\\\\\\\\\\_\') + \'%\')
这里也不需要字符串插值。您需要将反斜杠加倍以从数据库的字符串解析器中转义其含义,以便LIKE解析器将看到简单的“ \\%\”并知道忽略转义的百分号。 您应该检查日志,以确保两个反斜杠都可以通过。通过检查
irb
中的内容,我得到令人困惑的结果,使用五个(!)可以得到正确的输出,但是我看不到它的含义。如果有人在其中五个中确实看到了这种感觉,那么将不胜感激。 更新:杰森·金(Jason King)简化了逃生逃生角色的噩梦。这使您可以指定一个临时转义符,以便可以执行以下操作:
.where(\"url LIKE ? ESCAPE \'!\'\", some_url.gsub(/[!%_]/) { |x| \'!\' + x })
我还改用了
gsub
的块形式,以减少麻烦。 这是标准的SQL92语法,因此可以在任何支持该语法的数据库中使用,包括PostgreSQL,MySQL和SQLite。 将一种语言嵌入另一种语言总是有点恶梦般的纠结,对此您无能为力。总是会有丑陋的一点,您只需要咧着嘴笑。
从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
https://gist.github.com/3656283 有了这段代码,
Item.where(Item.arel_table[:name].matches(\"%sample!%code%\"))
正确地在\“ sample \”和\“ code \”之间转义
%
,并且匹配\“ AAAsample%codeBBB \”,但至少在MySQL,PostgreSQL和SQLite3上不匹配\“ AAAsampleBBBcodeCCC \”。
Post.where(\'url like ?\', \"%#{some_url + \'%\'}%)

要回复问题请先登录注册