建立你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(...)
你有東西像對數組,你想申請where
添加到模型類中,然後將where
應用於返回的內容,然後再次使用,直到用完陣列。事情看起來像一個反饋迴路趨向於(從「映射簡化」成名AKA reduce
)呼籲inject
:
注入(初始){|備忘錄,obj | block}→obj
通過應用二進制操作(由命名方法或運算符的塊或符號指定)來組合enum的所有元素。
如果指定的塊,然後在枚舉每個元素的塊被傳遞的累加器值(備忘錄)和元素[...]的結果變成用於備忘錄新值。在迭代結束時,備忘錄的最終值是該方法的返回值。
所以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)
哇!這樣可行!我剛剛接觸rails(和ruby),你介意給我一個關於這裏發生了什麼的簡短解釋嗎? – MGA
@Mattieu:這有幫助嗎?解釋你一直使用的功能性東西可能很難,通常是「aha!」你得到它的那一刻,它在那之前就是魔術。 –
@Mattieu,如果你不害怕添加寶石,請看一下squeel https://github.com/ernie/squeel。它有很棒的功能'like_all' /'like_any':'queries =%w [ruby rails] .map {| s |「%#{s}%」}; Product.where {title.like_all queries}'。 – jdoe