Самый простой способ построить ваши LIKE шаблоны струнный интерполяции:
where('property like ?', "%#{str}%")
и если у вас есть все ваши строки в массиве, то вы можете использовать цепочки запросов и inject
ActiveRecord, чтобы построить свой окончательный запрос:
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
к тому, что возвращается, затем снова, пока вы не исчерпали свой массив. Вещь, которая выглядит как петля обратной связи, как правило, требует inject
(AKA reduce
от "Map-Reduce" славы):
нагнетающих (начальное) {| memo, obj | Блок} → OBJ
сочетает в себе все элементы перечисления путем применения бинарную операцию, указанную в блоке или символ, что имена метода или оператора.
Если указать блок, то для каждого элемента в перечисления блок передается значение аккумулятора (памятки) и элемент [...] результат становится новым значением для памятки. В конце итерации конечное значение 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)
Woah! Это работает! Я новичок в рельсах (и рубине), не возражаете ли вы дать мне короткое объяснение того, что здесь происходит? – MGA
@Mattieu: Это помогает? Трудно объяснить функциональные вещи, которые вы используете все время, обычно есть «ага!». момент, когда вы его получите, и до этого все волшебство. –
@Mattieu, Если вы не боитесь добавлять драгоценные камни, взгляните на squeel https://github.com/ernie/squeel. У этого есть удивительная функция 'like_all' /' like_any': 'queries =% w [ruby rails] .map {| s |"% # {s}% "}; Product.where {title.like_all query} '. – jdoe