На данный момент вы, возможно, потребуется перейдите к чистому AREL и передайте их в качестве параметров для метода поиска. Что дает некоторые интересные дополнительные predicates и более расширяемой
вот и грязный, с верхней части моей головы, например, как вы могли сделать это с AREL. Его непроверенный код, хотя ... он не должен быть открытым до SQL injection, но я не помню, если AREL санирует совпадения запросов. Кроме того, подход AREL по совпадению предпочтительнее, чем необработанный SQL, поскольку он должен быть агностиком DB.
class Book
...
# search class method via AREL
def self.search(params = {})
if params.respond_to?(:has_key?)
# setup arel object for proper table
books = Arel::Table.new(:books)
if params.has_key?(:location)
location_match = books[:location].eq(params[:location])
end
if params.has_key?(:status)
status_match = books[:status].eq(params[:status])
end
# although if all you're doing is searching for a title
# maybe you can deprecate starts_with column and search
# the proper column say... title
if params.has_key?(:starts_with)
title_match = books[:starts_with].matches("%#{params[:starts_with}%")
end
# return AREL query. Note this *should* be safe from [SQL injection][4]
# via AREL sanitization but verify then trust.
# Choose one of the below
# match on Any
where(location_match.or(status_match).or(title_match))
# match on ALL
where(location_match.and(status_match).and(title_match))
end
end
...
end
Или более сложная настройка, но более простой подход заключается в использовании search kick камня и настраивают elasticsearch экземпляра.
Также быстрое примечание стороны. Проверка ключей Хэша с присутствием Hash #? это запах кода. Что произойдет, если проверяемый объект не реагирует на индексном метод ... Он будет дуть с
(dev)> a = nil
=> nil
(dev)> a[:dave].present?
NoMethodError: undefined method `[]' for nil:NilClass
IMO Вы должны более правильно проверить, что сам хэш существует, а затем использовать метод рубина has_key? (: some_key) ...
(dev)> a = nil
=> nil
(dev)> a.present? && a.has_key?(:dave)
=> false
(dev)>
Но тогда это только я, ваш пробег может отличаться. В принципе никогда не доверяйте типам ruby тем, что вы ожидаете от них.
Примечание. В этом методе мы устанавливаем хэш по умолчанию, если ни один не передан, поэтому мы можем перейти к has_key? проверьте, однако он все равно может исчезнуть, если мы передадим ему что-то еще, следовательно, response_to? проверьте параметры.
Теперь, когда вы вызываете его в контроллер (или модели, или там, где) вы можете назвать в качестве такого
@books = Book.search(params)
Check [этот ответ] (http://stackoverflow.com/a/4480139/2835243). Это должно делать то, что вы хотите сделать. – TheWanderingMind