Rails 3使用数组搜索字符串

时间:2011-08-12 03:22:40

标签: sql ruby-on-rails ruby-on-rails-3 search

我试图在Rails 3中进行搜索。我有一个像这样的数据库对象,具有如下属性:

@food.fruit = "Apples, Pears, Plums"

我有一个使用复选框中的参数的搜索,如下所示:

params[:search] = ["Apples", "Oranges", "Bananas", "Grapefruit"]

由于上面的@food对象有“苹果”而搜索数组中有“苹果”,我希望此搜索成功。但是我无法正常工作。

我最初的想法是做类似

的事情
@results = Food.where("fruit LIKE ?", "%params[:search]%")

@results = Food.where("fruit IN ?", params[:search])

但是,如果params[:search]仅包含@food.fruit元素且没有其他元素,则第一个仅有效。第二个根本不起作用。

我的最后一个尝试是做

之类的事情
@results = Array.new
params[:search].each do |search|
  @results << Food.where("fruit LIKE ?", search)
end

但如果我不必这样做,我宁愿不这样做。有人有什么建议吗?

2 个答案:

答案 0 :(得分:2)

你正在寻找的是像这样的SQL:

WHERE LOWER(fruit) LIKE '%apples%'
   OR LOWER(fruit) LIKE '%oranges%'
   OR LOWER(fruit) LIKE '%bananas%'
   OR LOWER(fruit) LIKE '%grapefruit%'

请注意,LIKE不一定不区分大小写,因此将所有内容推送到小写(或大写)通常是个好主意。

这很简单,但当您需要x.where(...).where(...)...时,AND会将条件与OR联系起来。一种方法是将where的第一个参数构建为字符串,方法是将"LOWER(fruit) LIKE ?"字符串的正确数量粘贴在一起,以匹配params[:search]中的元素数量:

@results = Food.where(
    (["LOWER(fruit) LIKE ?"] * params[:search].length).join(' OR '),
    *(params[:search].map { |s| '%' + s.downcase + '%' })
)

答案 1 :(得分:1)

基本上你正在进行5次单独的搜索。虽然制作5个单独的SQL查询可能不是答案,但您可以始终加入数组,例如:

scope :search_fruit, lambda {|*fruits|
  where fruits.flatten.map {|fruit| arel_table[:fruit].matches("%#{fruit}%") }.inject(&:or)
}

Food.search_fruit(params[:fruit])