2009-10-29 2 views
2

사용자가 특정 name 문자열로 시작하는 이름을 가진 사람들을 검색 할 수있는 양식이 있다고 가정 해 봅시다. 예를 들어 "Mi"는 "Mike"와 "Miguel"을 찾습니다. 아마 그래서 같이 찾기 문을 만들 것입니다 : 바인딩 변수 및 선택적 매개 변수가있는 조건

find(:all, :conditions => ['name LIKE ?', "#{name}%"]) 

가의 양식도이 개 선택적 필드, hair_color 추가 결과를 필터링 할 수 있습니다 eye_color을 가지고 있다고 가정 해 봅시다. 쿼리의 이름 부분을 무시하고, 선택적 매개 변수의 임의의 수에 걸릴 수있는 사람들을위한 찾기 문은 다음과 같습니다

find(:all, :conditions => { params[:person] })

내 두 개의 선택적 매개 변수에 대한 어떤이의 동등 행동 것 : 나는 알아낼 수 없습니다 무엇

find(:all, :conditions => { :hair_color => hair_color, :eye_color => eye_color })

은 필수 "이름은"위 "와 같은"조건에 적용되는 쿼리의 두 종류와 옵션 hair_coloreye_color을 병합하는 방법입니다 매개 변수 ers (그리고 아마도 다른 것들)는 결과를 더 필터링하기 위해 추가 될 수 있습니다.

필자는이 작업을 위해 쿼리 문자열을 작성할 수 있지만 필연적으로 "레일 방식"이 더 우아해야합니다. 필수 바인딩 매개 변수를 선택적 매개 변수와 병합하려면 어떻게합니까?

답변

4

이것은 명명 된 범위의 완벽한 사용법입니다.

모델에서 명명 된 범위를 만들 :

named_scope :with_name_like, lambda {|name| 
    {:conditions => ['name LIKE ?', "#{name}%"]} 
} 

을이 시점에서 당신은 당신을 위해 쿼리를 병합합니다

Model.with_name_like("Mi").find(:all, :conditions => params[:person]) 

그리고 레일을 호출 할 수 있습니다.

편집 : Waseem에 대한 코드 :

unless name.blank? 
    Model.with_name_like("Mi").find(:all, :conditions => params[:person]) 
else 
    Model.find(:all, :conditions => params[:person]) 
end 

또는 당신이로 명명 된 범위를 다시 정의 할 수 있습니다 :

이름은 당신이 만약 조건이있는 방법 체인에서 명명 된 범위를 생략 할 수 중 하나를 선택 사항 인 경우 똑같은 일을하십시오.

scope :with_name_like, lambda {|name| 
    if not name.blank? 
    where('name LIKE ?', "#{name}%") 
    end 
} 
+0

그냥 호기심에 도움이되기를 바랍니다. 이름 문자열을 지정하는 것이 선택 적이라면 어떻게 확장하겠습니까? – Waseem

+0

나는 그것을 할 수있는 좋은 깨끗한 방법이 있어야한다는 것을 알고있었습니다. 항상 레일이 있습니다 :-) 감사합니다! – SingleShot

+1

@waseem, 나는 귀하의 질문에 답하기 위해 해결책을 수정했습니다. – EmFi

0

은 Waseem 요구와도 부합하지만, 허용 전무 대신 빈하려면 : 여기

named_scope :with_name_like, lambda {|name| 
    if name.blank? 
    {} 
    else 
    {:conditions => ['name LIKE ?', "#{name}%"]} 
    end 
} 

업데이트

은 레일 마지막 코드의 3 버전? (경우에 udeful 인 사용하려는 "[: 이름] @things = Thing.named_like (PARAMS)"을 직접)

named_scope :named_like, lambda do |*args| 
    if (name=args.first) 
    {:conditions => ["name like ?",name]} 
    else 
    {} 
    end 
end 

# or oneliner version: 

named_scope :named_like, lambda{|*args| (name=args.first ? {:conditions => ["name like ?",name]} : {}) } } 

나는 그것이

관련 문제