2011-08-17 6 views
3

레일.레일 2.3.5 문제 건축 조건 배열을 동적으로 사용하는 경우 (?) 나는 동적으로 액티브 찾기 위해 건물 조건 관련 질문의 수를 살펴 보았다 2.3.5</p> <p>

검색 로직과 같은 멋진 보석이 있으며 Rails3에서 더 뛰어나다는 점을 알고 있습니다. 그러나 geospitial 검색을 위해 geokit을 사용하고 있습니다. 다른 조건의 필터를 결합 할 수있는 표준 조건 세트 만 만들려고합니다.

고급 검색을 위해 동적으로 결합하려고하는 12 가지 필터가 있습니다. (?)와 IS NULL 조건에서 동등성,보다 큼,보다 작음을 섞을 수 있어야합니다. 여기

내가 작업을 얻기 위해 노력하고있어의 예 :

conditions = [] 
conditions << ["sites.site_type in (?)", params[:site_categories]] if params[:site_categories] 
conditions << [<< ["sites.operational_status = ?", 'operational'] if params[:oponly] == 1 
condition_set = [conditions.map{|c| c[0] }.join(" AND "), *conditions.map{|c| c[1..-1] }.flatten] 


@sites = Site.find :all, 
        :origin => [lat,lng], 
        :units => distance_unit, 
        :limit => limit, 
        :within => range, 
        :include => [:chargers, :site_reports, :networks], 
        :conditions => condition_set, 
        :order => 'distance asc' 

내가 얻을 수있을 것 같다이 조건 표현 만 하나의 변수가있을 때 잘 작동하지만 난 뭔가를 때 (?)이며 값 배열에 잘못된 바인드 조건 수에 대한 오류가 발생합니다. 내가 합류하고 조건을 평평하게하는 (대답을 기반으로 Combine arrays of conditions in Rails) 제대로 배열을 처리하지 않는 것 같아요. 그리고 문제를 추적 할 수있는 평탄화 논리를 이해하지 못합니다. 그래서

의 내가 PARAMS 3 개 값이 있다고 가정 해 보자는 [: site_categories] 나는 위의 코드는 다음 날 잎 있습니다 :

조건이

[["sites.operational_status = ?", "operational"], ["sites.site_type in (?)", ["shopping", "food", "lodging"]]] 

평탄화 시도는 다음과 같습니다

저를 제공
["sites.operational_status = ? AND sites.site_type in (?)", ["operational"], [["shopping", "food", "lodging"]]] 

:

바인드 변수 개수가 잘못되었습니다 (2에 대해 4)

나는이 모든 것을 명명 된 범위로 변환하는 작업을 진행할 예정이지만이 방법으로 작업하는 방법을 이해하고 싶습니다.

+0

IMHO, 내가 명명 된 범위 아이디어 나 심지어는 하나의 방법으로 그들을 분리한다는 것은 동적 검색 문자열을 만드는 것보다 낫다 생각하십니까. 명명 된 범위 (또는 메서드)를 사용하면 모델 (및 메서드) 호출을 훨씬 쉽게 읽을 수 있으며 쿼리를 매시업하면 많은 어려움이 발생할 수 있으며 많은 문제가 발생할 수 있습니다.레일즈가 당신을 위해 쿼리를 해보겠습니다. (내가 완전히 추측 할 필요가 없다면) – corroded

+0

@corroded - 10-15 개의 명명 된 스코프를 동적으로 결합하고 단일 쿼리를 생성하는 방법을 이해하지 못합니다. 데이터베이스를 한번에 여러 번 치는 것을 피하기를 원하며 주어진 검색에서 얼마나 많은 조건이 지정 될지 모른다. – Nick

답변

3

레일 4

users = User.all 
users = User.where(id: params[id]) if params[id].present? 
users = User.where(state: states) if states.present? 
users.each do |u| 
    puts u.name 
end 

올드 대답

원숭이는 Array 클래스를 패치. 파일명 : monkey_patch.rbconfig/initializers 디렉토리에 만듭니다.

class Array 
    def where(*args) 
    sql = args.first  
    unless (sql.is_a?(String) and sql.present?) 
     return self 
    end  
    self[0] = self.first.present? ? " #{self.first} AND #{sql} " : sql 
    self.concat(args[1..-1])  
    end 
end 

이제 당신은이 작업을 수행 할 수 있습니다

cond = [] 
cond.where("id = ?", params[id]) if params[id].present? 
cond.where("state IN (?)", states) unless states.empty? 
User.all(:conditions => cond) 
+0

당신은 내 스택 오버플로 영웅입니다. 이 팁에 깊이 감사드립니다. – Nick

+0

원숭이 경로가 이것을 수행하는 유일한 논리 방법이라고 나는 믿을 수 없다. –