2011-12-18 80 views
0

我想寫快速範圍來過濾我的餐館。過濾器的最佳範圍

我做這樣的事情

@restaurants = Restaurant.all 
@restaurants = filter(@restaurants) 

def filter(restaurants) 
    restaurants = restaurants.filter('types', params[:type].split(','))   unless params[:type].nil? 
    restaurants = restaurants.filter('cuisines', params[:cuisine].split(',')) unless params[:cuisine].nil? 
    restaurants = restaurants.filter('facilities', params[:facility].split(',')) unless params[:facility].nil? 
    restaurants = restaurants.filter('services', params[:service].split(',')) unless params[:service].nil? 
    restaurants = restaurants.filter('prices', params[:price].split(','))  unless params[:price].nil? 
    return restaurants 
end 

,其中過濾器是:

scope :filter, lambda{|type_name, type_id| includes(type_name.to_sym).where(["#{type_name}.id in (?)", type_id]) } 

所以......當我得到網址:

.../search?service=1,2,3 

我得到的服務1或飯店2或3,但我想要獲得服務1和2和3的餐館。 我該如何做到這一點噸,因爲它可能是?

回答

1

IN in SQL is always將成爲OR的操作。你需要首先分解參數,然後做多個過濾器。此外,all避開了AREL的延遲加載,因此您首先加載所有內容,然後從那裏進行過濾。壞的魔咒。 :)

你有沒有考慮過這樣做的路線?

# restaurant.rb 
scope :filter, lambda{|type_name, type_id| includes(type_name.to_sym).where("#{type_name}_id" => type_id) } 

# routes.rb 
match 'restaurants/search/*query', "restaurants_controller#search" 

# restaurants_controller.rb 
def search 
    query = params[:query] 
    query.delete_at(-1) if query.length % 2 > 0 #Otherwise we'll get an exception for providing an odd number of elements. 
    search_hash = Hash[*query].symbolize_keys 
    @restaurants = Restaurant.scoped 
search_hash.each do |key, value| 
    value.split(",").each do |v| 
     @restaurants.filter(key, v) 
    end 
    end 
end 

那麼您的搜索網址成爲了類似:

/search/service/1,2,3/type/3,4,5 

你需要做一些健全檢查就像確保keyRestaurant模型的屬性,但這應該工作。另外,爲了確保我沒有錯過任何東西,我已經校驗了幾次,但這是未經測試的代碼,可能存在錯誤或錯別字。買者自負。 :)

+0

有delete_at(沒有操作delete_at爲字符串/服務/ 1,2,3)的問題等:( – 2011-12-19 18:43:30

+0

D'oh!在Rails 2中,我認爲它作爲一個數組通過嘗試分裂獲得一個數組的路徑組件。 – jxpx777 2011-12-20 14:31:37