2010-12-08 4 views
1

레일즈 3 응용 프로그램을 작성 중이며 Users 테이블이 있습니다. 사용자는 first_name 및 last_name 열을가집니다. 사용자를 나열하는 내 페이지에서 사용자가 목록을 필터링 할 수있는 단일 텍스트 검색 상자가 필요합니다. 검색 상자에 다음 중 하나를 입력 할 수 있어야합니다. - 사용자의 이름 - 사용자의 성도 - 사용자의 전체 이름 (예 : "Smith, John")"Where"절이 레일스 3에 연결된 필드가 있습니다.

이러한 결과를 반환하는 where 절을 작성하는 방법을 모르겠습니다. 내가 얻은 가장 가까운 것이 아래에 있지만, 연결된 필드 부분이 작동하지 않습니다.

where('(first_name LIKE :search) or (last_name LIKE :search) or ("#{last_name}, #{first_name}" LIKE :search)', :search => "%#{search}%") 

또한이 절이 매우 까다로워 지므로 내 OR 문을 처리하는 더 좋은 방법이 있는지 알고 싶습니다.

도움 주셔서 감사합니다.

답변

2

다른 사람에게 도움이 될 경우이 솔루션을 사용해 보겠습니다.

def self.search(query) 
    if query.blank? 
     scoped 
    else 
     sql = query.split.map do |word| 
     %w[first_name last_name].map do |column| 
     sanitize_sql ["#{column} LIKE ?", "%#{word}%"] 
     end.join(" or ") 
     end.join(") and (") 
     where("(#{sql})") 
    end 
    end 

이 솔루션에 대한 Railscasts의 Ryan Bates에게 감사드립니다.

+0

Railscasts에서이 솔루션을 찾았습니까? 미리 감사드립니다. –

+0

그것은 railscast에서 아니었다. –

+0

감사합니다! 나는 그것이 매우 유용하다는 것을 알았다 :) –

2

where이 SQL로 바뀌고 연결 열과 검색 문자열을 비교하려면 데이터베이스/sql 수준에서이 작업을 수행해야한다는 것을 기억해야합니다.

이제 SQL에서의 연결이 데이터베이스에 따라 다르기 때문에 이것이 까다로워집니다. 당신과 같이 작성합니다 PostgreSQL을, 오라클에서

: MySQL과,

where("(first_name LIKE :search) or (last_name LIKE :search) or (last_name || ',' || first_name LIKE :search)", :search => "%#{search}%" 

불행하게도, MySQL은 표준 연결 연산자 ||를 지원하지 않습니다 대신 concat를 사용해야합니다 :

where("(first_name LIKE :search) or (last_name LIKE :search) or (concat(last_name, ',', first_name) LIKE :search)", :search => "%#{search}%" 
+1

where 절보다 더 나은 방법이 있습니까? 가능하다면 데이터베이스에 특정한 것을 추가하지 않을 것입니다. –

+0

다른 옵션은 나중에 메모리에서 수행하지만, 이에 대해 강력하게 조언합니다. 나는 여기서'where'를 사용하는 것이 최선의 선택이라고 생각합니다 : 당신의 데이터베이스는이 작업을 수행하기에 가장 잘 갖추어져 있습니다. 이러한 경우에는 일부 데이터베이스 관련 코드를 추가하지 않아도 될까봐 걱정됩니다. – nathanvda

관련 문제