非常简单的问题 - 我如何进行搜索以查找名称以ActiveRecord中的某个字符串开头的所有记录.我已经在互联网上看到了各种各样的比特,其中使用了逐字的LIKE SQL子句 - 但是从我所听到的那些不是'正确'的方式.
有没有'正确'的Rails方式?
如果您希望在数据库中进行搜索,那么您将需要使用SQL.
当然,你需要在数据库中进行搜索,否则你需要将所有对象加载到Ruby中(这不是一件好事).
所以,你需要类似的东西
MyModel.find(:all, :conditions => ["field LIKE ?", "#{prefix}%"])
where prefix
是一个带有你正在寻找的字符串的变量.
在Rails 3.0+中,这变为:
MyModel.where("field LIKE :prefix", prefix: "#{prefix}%")
我强烈推荐Searchlogic插件.
然后它就像:
@search = Model.new_search(params[:search]) @search.condition.field_starts_with = "prefix" @models = @search.all
Searchlogic足够聪明,就像ActiveRecord一样,可以在starts_with
条件中获取字段名称.它还将处理所有分页.
此方法将有助于防止SQL注入,并且还将与数据库无关.Searchlogic最终会根据您使用的数据库适配器以不同方式处理搜索.您也不必编写任何SQL!
Searchlogic有很好的文档,并且易于使用(我自己是Ruby和Rails的新手).当我遇到困难时,该插件的作者甚至在几个小时内回复了一封直接电子邮件,帮助我解决了我的问题.我不能推荐Searchlogic ......正如你所知道的那样.
免责声明:我是Ruby和Rails的新手,我仍然在努力学习Ruby方法来做事,但我已经编写了超过一半的生命,并且专业地编写了十年.DRY是我非常熟悉的概念.这是我实现它的方式.这与narsk的答案非常相似,我认为这也很好.
# name_searchable.rb # mix this into your class using # extend NameSearchable module NameSearchable def search_by_prefix (prefix) self.where("lower(name) LIKE '#{prefix.downcase}%'") end end
然后在你的模型中:
class User < ActiveRecord::Base extend NameSearchable ... end
然后当你想要使用它时:
User.search_by_prefix('John') #or User.search_by_prefix("#{name_str}")
要喊出一件事:
传统的关系数据库并不能很好地满足这些类型的查询.如果您正在寻找一种不会在负载下杀死数据库的高响应性实现,那么您应该使用针对此目的而定制的解决方案.流行的例子包括Solr或Sphinx,还有很多其他的例子.有了这个实现,既然你干了,你可以在一个地方用一个单独的索引器替换实现,你就可以摇滚了.
每次我想查看特定列是否带有前缀时,我都不想写一个作用域.
# initializers/active_record_initializers.rb class ActiveRecord::Base # do not accept a column_name from the outside without sanitizing it # as this can be prone to sql injection def self.starts_with(column_name, prefix) where("lower(#{column_name}) like ?", "#{prefix.downcase}%") end end
像这样称呼它:
User.starts_with('name', 'ab').limit(1)