2011-12-18 79 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