Rails 3 Поиск по строке с использованием массива - PullRequest
0 голосов
/ 12 августа 2011

Я пытаюсь выполнить поиск в Rails 3 следующим образом. У меня есть объект базы данных, например, с таким атрибутом:

@food.fruit = "Apples, Pears, Plums"

и у меня есть поиск, который использует параметры из флажка, например:

params[:search] = ["Apples", "Oranges", "Bananas", "Grapefruit"]

Поскольку у моего объекта @food выше есть «Яблоки», а в массиве поиска - «Яблоки», я бы хотел, чтобы этот поиск был успешным. Однако у меня возникают проблемы с правильной работой.

Моей первоначальной мыслью было сделать что-то вроде

@results = Food.where("fruit LIKE ?", "%params[:search]%")

или

@results = Food.where("fruit IN ?", params[:search])

Но первый работает, только если params[:search] содержит ТОЛЬКО элементы @food.fruit и никаких других. Второй вообще не работает.

Мой последний вариант - это сделать что-то вроде

@results = Array.new
params[:search].each do |search|
  @results << Food.where("fruit LIKE ?", search)
end

но я бы предпочел этого не делать, если мне не нужно. У кого-нибудь есть совет?

Ответы [ 2 ]

2 голосов
/ 12 августа 2011

Что вам нужно, так это какой-то SQL-код:

WHERE LOWER(fruit) LIKE '%apples%'
   OR LOWER(fruit) LIKE '%oranges%'
   OR LOWER(fruit) LIKE '%bananas%'
   OR LOWER(fruit) LIKE '%grapefruit%'

Обратите внимание, что LIKE не обязательно не чувствителен к регистру, поэтому обычно рекомендуется переносить все в нижний регистр (или верхний регистр).

Это достаточно просто, но сказать, что x.where(...).where(...)... связывает условия с AND, когда вы хотите OR.Один из способов - создать первый аргумент для where в виде строки, вставив правильное количество строк "LOWER(fruit) LIKE ?", соответствующих количеству элементов в params[:search]:

@results = Food.where(
    (["LOWER(fruit) LIKE ?"] * params[:search].length).join(' OR '),
    *(params[:search].map { |s| '%' + s.downcase + '%' })
)
1 голос
/ 12 августа 2011

По сути, вы делаете 5 отдельных поисков. Хотя выполнение 5 отдельных запросов SQL может не быть решением, вы всегда можете присоединиться к массиву, например:

scope :search_fruit, lambda {|*fruits|
  where fruits.flatten.map {|fruit| arel_table[:fruit].matches("%#{fruit}%") }.inject(&:or)
}

и

Food.search_fruit(params[:fruit])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...