从数组中创建rails中的where查询

时间:2012-05-25 04:39:22

标签: ruby-on-rails activerecord rails-activerecord

我需要从数组中创建一个where查询,其中数组的每个成员都是一个“赞”操作,即ANDed。例如:

SELECT ... WHERE property like '%something%' AND property like '%somethingelse%' AND ...

使用ActiveRecord where函数很容易,但我不确定如何首先清理它。我显然不能只创建一个字符串并将其填充到where函数中,但似乎没有办法使用?

由于

3 个答案:

答案 0 :(得分:6)

构建LIKE模式的最简单方法是字符串插值:

where('property like ?', "%#{str}%")

如果你有一个数组中的所有字符串,那么你可以使用ActiveRecord的查询链和inject来构建你的最终查询:

a = %w[your strings go here]
q = a.inject(YourModel) { |q, str| q.where('property like ?', "%#{str}%") }

然后您可以q.allq.limit(11)或您需要做的任何事情来获得最终结果。


这是一个关于它是如何工作的快速教程;您还应该查看Active Record Query Interface GuideEnumerable documentation

如果你要匹配两件事(ab),你可以这样做:

q = Model.where('p like ?', "%#{a}%").where('p like ?', "%#{b}%")

where方法返回一个支持所有常用查询方法的对象,因此您可以根据需要将调用链接为M.where(...).where(...)...;其他查询方法(例如orderlimit,...)返回相同类型的对象,因此您也可以将它们链接起来:

M.where(...).limit(11).where(...).order(...)

你有一系列要反对的东西,你想将where应用于模型类,然后将where应用于返回的内容,然后再次使用,直到你用尽了你的数组。看起来像反馈循环的东西往往需要inject(来自“map-reduce”成名的AKA reduce):

  

注入(初始){|备忘录,obj |阻止}→obj

     

通过应用由块或命名方法或运算符的符号指定的二进制操作来组合 enum 的所有元素。

     

如果指定一个块,那么对于 enum 中的每个元素,该块将传递一个累加器值( memo ),并且元素[...]结果变为备忘录的新值。在迭代结束时, memo 的最终值是该方法的返回值。

因此inject获取块的输出(在我们的例子中是where的返回值)并将其作为输入提供给下一次执行块。如果你有一个数组并且你inject

a = [1, 2, 3]
r = a.inject(init) { |memo, n| memo.m(n) }

然后就是这样:

r = init.m(1).m(2).m(3)

或者,在伪代码中:

r = init
for n in a
    r = r.m(n)

答案 1 :(得分:0)

如果您正在使用AR,请执行Model.where(property: your_array)Model.where("property in (?)", your_array)之类的操作,这样,所有内容都会被清理

答案 2 :(得分:0)

让我们说你的数组是model_array,尝试数组选择:

model_array.select{|a|a.property=~/something/ and a.property=~/somethingelse/}

当然你可以随意使用任何正则表达式。