构建 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.all 或q.limit(11) 或任何您需要做的事情来获得最终结果。
这里有一个关于其工作原理的快速教程;您还应该查看Active Record Query Interface Guide 和Enumerable documentation。
如果您有两件事(a 和 b)要匹配,您可以这样做:
q = Model.where('p like ?', "%#{a}%").where('p like ?', "%#{b}%")
where 方法返回一个支持所有常用查询方法的对象,因此您可以根据需要将调用链接为M.where(...).where(...)...;其他查询方法(例如order、limit、...)返回相同类型的对象,因此您也可以将它们链接起来:
M.where(...).limit(11).where(...).order(...)
您有一系列要 LIKE 的东西,并且您想将 where 应用于模型类,然后将 where 应用于返回的内容,然后再一次,直到您用完您的数组。看起来像反馈循环的东西往往需要inject(又名reduce,来自“map-reduce”名声):
注入(初始){|备忘录,obj |块 } → obj
通过应用二元运算组合枚举的所有元素,该二元运算由命名方法或运算符的块或符号指定。
如果你指定了一个块,那么对于 enum 中的每个元素,块都会被传递一个累加器值(memo)并且元素 [...] 结果变为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)