2011-08-17 43 views
3

的Rails 2.3.5的Rails 2.3.5問題建設條件動態數組使用時(?)

我已經看了一些有關建築條件等問題,動態地一個ActiveRecord找到。

我知道有一些偉大的寶石,如搜索邏輯,這在Rails3中更好。然而,我正在使用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"]]] 

這給了我:

錯號碼綁定變量(4 2)

我要退後一步,在這一切的轉換爲命名範圍工作,但我真的很想知道如何得到這個工作這種方式。

+0

恕我直言,我認爲你的命名範圍的想法,甚至將它們分離成單一的方法比動態創建一個搜索字符串更好。命名範圍(或方法)使您的模型(和方法)調用更容易閱讀,同時嘗試混合查詢會導致很多痛苦並引入大量可能的問題。讓rails爲你查詢(除非你需要他們完全優化,我猜) – 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類。在config/initializers目錄中創建一個名爲monkey_patch.rb的文件。

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

你是我的Stack Overflow英雄。深深感謝這個提示。 – Nick

+0

我不能相信猴子的道路是唯一的邏輯方法來做到這一點。 –