gab*_*lal 17 sqlite postgresql search ruby-on-rails pattern-matching
我使用SQLite3进行开发,使用PostgreSQL进行部署.但是,我面临以下问题:
我的简单搜索使用SQLite3
:
def self.search(search)
if search
find(:all, :conditions => ["style LIKE ? OR construction LIKE ?", "%#{search}%", "%#{search}%"])
else
find(:all)
end
end
Run Code Online (Sandbox Code Playgroud)
但是,它不起作用PostgreSQL
,我需要替换LIKE
for ILIKE
来解决问题:
def self.search(search)
if search
find(:all, :conditions => ["style ILIKE ? OR construction ILIKE ?", "%#{search}%", "%#{search}%"])
else
find(:all)
end
end
Run Code Online (Sandbox Code Playgroud)
是否有"Ruby方式"在任何数据库中进行这些搜索?
编辑 - 基于您的答案我不相信我会找到一个通用的Ruby解决方案.
我也跟着Ruby on Rails的教程:学习的榜样导轨-由迈克尔·哈特尔,在最终的Gemfile显示这两个数据库...嗯,令人失望...
Erw*_*ter 46
问题的根源在于:
我使用SQLite3进行开发,使用PostgreSQL进行部署.
这是一个坏主意™.你将继续遇到不兼容问题 - 或者更糟糕的是:在完成损害之前没有意识到这一点.
使用相同的RDBMS(PostgreSQL)进行开发和生产,为您节省无意义的麻烦.
当你遇到不幸的设置时,有一个简单的解决方法:
lower(style) LIKE lower(?)
Run Code Online (Sandbox Code Playgroud)
适用于两个平台.
lower()
如果您提供小写搜索模式,则可以放弃右手.
在标准SQLite中,lower(X)
只折叠ASCII字母.有关更多信息,请引用SQLite手册中的核心函数一章:
lower(X)函数返回字符串X的副本,所有ASCII字符都转换为小写.默认的内置lower()函数仅适用于ASCII字符.要对非ASCII字符进行大小写转换,请加载ICU扩展名.
强调我的.
PostgreSQLlower(X)
开箱即用UTF-8.
作为一个受欢迎的副作用,您可以使用表达式上的索引加速 PostgreSQL中的查询,这将比使用和基本索引更快. lower(style)
ILIKE
style
此外,由于PostgreSQL 9.1你可以使用带pg_trgm
扩展名的GIN或GIST索引来加速任何 LIKE
和ILIKE
查询 - 三元组不区分大小写.此相关答案中的详细说明和链接:
我认为Arel是解决这个问题的最佳方法.它被Rails用于活动记录并且与数据库无关.您的代码在sqlite3或postgres中的工作方式相同,这似乎适合您的情况.使用匹配方法将自动切换到postgres环境中的ilike.例:
users=User.arel_table
User.where(users[:style].matches("%#{search}%").or(users[:construction].matches("%#{search}%")))
Run Code Online (Sandbox Code Playgroud)
您可以从github获取更多信息:https://github.com/rails/arel/
不,搜索数据库没有"ruby方式" - Ruby on Rails(特别是ActiveRecord)包含帮助方法,用于在ActiveRecord支持的RDB上执行CRUD操作,但是没有更好的方法可以使用LIKE进行搜索然后示例你提供.
与此讨论相关的Rails文档部分将是ActiveRecord :: FinderMethods.
作为旁注,而不是做find(:all)
你可以做所有.
Rails文档使用与用于执行LIKE语句相同的语法,即:
Person.exists?(['name LIKE ?', "%#{query}%"])
Run Code Online (Sandbox Code Playgroud)
使用上述方法是非常安全的.
下面这样的语句不安全的原因是因为where
字符串直接传递到您的数据库查询而没有任何清理,这使您的数据库开放利用(即一个简单的撇号params[:first_name]
可能会弄乱您的整个查询并使您的数据库易受攻击 - - 特别是SQL注入).在上面的示例中,ActiveRecord可以清理您传递给查询的参数.
Client.where("first_name LIKE '%#{params[:first_name]}%'")
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
7398 次 |
最近记录: |