清理基于多个选项查询的混乱代码

时间:2017-04-10 22:55:54

标签: ruby-on-rails arrays ruby mongodb

我使用的是Rails,但这里的基本问题更广泛地适用。我的网络应用程序上有一个报告页面,允许用户指定他们过滤的内容,并根据这些过滤器(MongoDB)查询数据库。

数据基于酒店,用户必须先选择酒店的区域(postMessagestate_onestate_two),然后选择酒店的状态({{1 }},state_threeplanning),然后是可选标准,价格范围(under_constructionoperational200)。用户可以选择每个选项的多个。

我目前的做法是创建一个空数组,遍历每个区域,并在用户选择该区域时将区域推入数组。然后,我正在迭代THAT数组,并评估这些地区的酒店状态,如果有任何酒店具有用户选择的状态,那么我将该酒店添加到新的空数组中。然后我为价格范围做同样的事情。

这样可行,但代码非常混乱,这是代码的一个例子:

300

有哪些更好的方法可以实现这一目标?

2 个答案:

答案 0 :(得分:1)

这个怎么样:

STATES   = [:one, :two, :three]
STATUSES = [:planning, :under_construction, :operational]
PRICES   = [200, 300, 400]

def find_hotel
  region = params[:options][:region]

  first_array  = set_array(region, find_all_hotels, STATES, :state)
  second_array = set_array(region, first_array, STATUSES, :status)
  third_array  = set_array(region, second_array, PRICES, :price_range)
end

def set_array(region, array, options, attribute)
  array.each_with_object([]) do |element, result|
    options.each do |option|
      result << element if region.include?(option) && element[attribute] == option
    end
  end
end

<强>更新

attribute添加了set_array参数,以使代码与您更新的示例一起使用。

答案 1 :(得分:0)

由于second_array为空,无论你通过它迭代得到什么(也许是third_array)也都是空的。

def find_hotel
  hotels = find_all_hotels

  first_array = hotels
  .select{|hotel| params[:options][:region].include?("state_#{hotel.state}")}

  first_array += first_array
  .select{|hotel| params[:options][:region].include?(hotel.status.to_s)}

  second_array = third_array = []

  ...
end