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

MGA*_*MGA 1 activerecord ruby-on-rails rails-activerecord

我需要从一个数组中进行where查询,其中数组的每个成员都是一个"相似"的AND运算.例:

SELECT ... WHERE property like '%something%' AND property like '%somethingelse%' AND ...
Run Code Online (Sandbox Code Playgroud)

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

谢谢

mu *_*ort 6

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

where('property like ?', "%#{str}%")
Run Code Online (Sandbox Code Playgroud)

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

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

然后你可以q.all或者q.limit(11)你需要做什么来获得你的最终结果.


这是一个关于它是如何工作的快速教程; 您还应该查看" Active Record查询接口指南"Enumerable文档.

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

q = Model.where('p like ?', "%#{a}%").where('p like ?', "%#{b}%")
Run Code Online (Sandbox Code Playgroud)

where方法返回一个支持所有常用查询方法的对象,因此您可以M.where(...).where(...)...根据需要链接调用; 其他查询方式(如order,limit...)返回相同类型的对象,所以你可以链的还有:

M.where(...).limit(11).where(...).order(...)
Run Code Online (Sandbox Code Playgroud)

你有一系列喜欢的东西,你想要应用于where模型类,然后应用于where返回的内容,然后再次使用,直到你用完你的数组.看起来像反馈循环的东西倾向于要求inject(AKA reduce来自"map-reduce"的名声):

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

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

如果指定一个块,那么对于枚举中的每个元素,块将传递一个累加器值(memo),而元素[...]结果将成为memo的新值.在迭代结束时,memo的最终值是方法的返回值.

因此inject获取块的输出(where在我们的例子中是返回值)并将其作为输入提供给下一次执行块.如果你有一个阵列,你inject就可以了:

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

然后就是这样:

r = init.m(1).m(2).m(3)
Run Code Online (Sandbox Code Playgroud)

或者,在伪代码中:

r = init
for n in a
    r = r.m(n)
Run Code Online (Sandbox Code Playgroud)