2011-08-12 7 views
0

레일 3에서 검색을 시도하고 있습니다. 그래서 같은 속성 때문에 같은 데이터베이스 개체를 가지고 :레일 3 배열을 사용하여 문자열 검색

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

와 나는 같은, 체크 박스에서 PARAMS를 사용하는 검색이 :

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

@food 객체 위 가지고 있기 때문에 "사과 "검색 배열에는이 검색을 성공적으로 수행하고 싶은"사과 "가 있습니다. 그러나이 작업을 제대로 수행하는 데 문제가 있습니다.

내 초기 생각은 params[:search]@food.fruit 요소없이 다른 사람을 포함하는 경우

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

또는

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

하지만 처음에만 작동처럼 뭔가를했다. 두 번째는 전혀 작동하지 않습니다.

내 마지막 도랑 리조트는

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

같은 것을 할 것입니다하지만 난 오히려 내가가없는 경우 그렇게하지 않는 게 좋을. 누구든지 조언을하나요?

답변

2

을 당신이 찾고있는이 같은 일부 SQL은 다음과 같습니다

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

LIKE은 대소 문자를 구분하지 않아도되므로 모든 것을 소문자 (대문자)로 푸시하는 것이 일반적으로 좋습니다.

충분히 간단하지만 을 원할 때 AND과 조건을 연결하는 것은 x.where(...).where(...)...입니다. 한 가지 방법은 params[:search]의 요소의 수와 일치 함께 "LOWER(fruit) LIKE ?" 문자열의 오른쪽 숫자를 붙여 문자열로 where의 첫 번째 인수를 구축하는 것입니다 : 당신의 답변

@results = Food.where(
    (["LOWER(fruit) LIKE ?"] * params[:search].length).join(' OR '), 
    *(params[:search].map { |s| '%' + s.downcase + '%' }) 
) 
+0

감사합니다. 이것은 저에게 완전한 의미를 가지며, 완전히 작동해야합니다 ... params [: search]가 그것에 하나의 항목을 가지고있을 때, 그것은 작동합니다. 하지만 그 배열을 2 개 이상 만들면 배열에 얼마나 많은 항목이 있는지에 따라 3 개의 "바인드 변수의 잘못된 번호 (1에 3)"오류가 발생합니다. 이것은 실제로 이것이 일어나고있는 것에 관해서는 의미가 없습니다. – goddamnyouryan

+0

@ Ryan : 바인드 변수 배열의 배열을 해제하기 위해 splat을 추가 할 수 있습니다 (고정 답변과 동일). –

+0

아 완벽한 ... 감사합니다! 나는 당신처럼 내 SQL과 똑똑 할 수 있었으면 좋겠다. 더 자세한 정보는? – goddamnyouryan

1

기본적으로 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])