【问题标题】:Rails 3 Searching through a string using an arrayRails 3使用数组搜索字符串
【发布时间】:2011-10-25 12:04:35
【问题描述】:

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

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

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

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

由于我上面的@food 对象具有“Apples”并且搜索数组具有“Apples”,因此我希望此搜索能够成功。但是我无法正常工作。

我最初的想法是做类似的事情

@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

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

【问题讨论】:

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


    【解决方案1】:

    您正在寻找的是这样的 SQL:

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

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

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

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

    【讨论】:

    • 感谢您的回答。这对我来说完全有意义,并且完全应该工作......当 params[:search] 中有一个项目时,它确实有效。但是当我将该数组设为 2 或更多时,它会抛出“错误数量的绑定变量(1 对 3)”错误,其中 3 是数组中有多少项。这对于为什么会发生这种情况真的没有意义。
    • @Ryan:您可以尝试添加一个 splat 来取消绑定变量数组的排列(如我的固定答案中所示)。
    • 啊完美...谢谢!我希望我的 SQL 能像你一样出色!有什么提示可以了解更多信息吗?
    • @Ryan:练习,犯错误,并向他们学习。并熟悉任何可用的文档。回答关于 SO 的问题也有帮助 :) 这里有很多人比我更擅长这些事情。
    【解决方案2】:

    基本上,您正在执行 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])
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-23
      • 2014-10-06
      • 2012-01-13
      相关资源
      最近更新 更多