我使用的是Rails,但这里的基本问题更广泛地适用。我在我的web应用上有一个报告页面,允许用户指定他们过滤的内容,并根据这些过滤器(MongoDB)查询数据库。清理凌乱的代码,基于多个选项的查询
的数据是基于围绕旅馆,用户必须首先选择的酒店(state_one
,state_two
,state_three
),则的酒店(planning
,under_construction
,operational
),状态然后任选的标准的区域,价格范围(200
,300
,400
)。用户可以选择多个这些选项。
我现在这样做的方法是创建一个空数组,迭代每个区域,并在用户选择该区域时将该区域推入数组。然后,我遍历THAT数组,并评估这些区域中的酒店的状态,如果任何酒店具有用户选择的状态,那么我将该酒店添加到新的空白数组中。然后我为价格范围做同样的事情。
这工作,但代码是进攻凌乱,这里的代码示例:
def find_hotel
hotels = find_all_hotels
first_array = []
hotels.each do |hotel|
if params[:options][:region].include? 'state_one' and hotel.state == :one
first_array.push(hotel)
elsif params[:options][:region].include? 'state_two' and hotel.state == :two
first_array.push(hotel)
elsif params[:options][:region].include? 'state_three' and hotel.state == :three
first_array.push(hotel)
end
end
second_array = []
first_array.each do |hotel|
if params[:options][:region].include? 'planning' and hotel.status == :planning
first_array.push(hotel)
elsif params[:options][:region].include? 'under_construction' and hotel.status == :under_construction
first_array.push(hotel)
elsif params[:options][:region].include? 'operational' and hotel.status == :operational
first_array.push(hotel)
end
end
third_array = []
second_array.each do |hotel|
# More of the same here, this could go on forever
end
end
有哪些更好的实现这一目标的方法吗?
为什么你有'hotel_is_in_state_one'而不是像'hotel_state'这样的东西是':one'? – tadman
ActiveRecord的'where'方法将数组转换为SQL'WHERE/IN'语句。所以你应该可以做一些像'Hotel.where(state:params [:options] [:region],region:params [:options] [:region])''。当然,你会想通过一个allowed_params机制来过滤你的params来防止攻击。 – moveson
@tadman我为这个例子编写了代码,它不是我的实际代码,只是我认为会说明我想要它做什么,我的实际应用程序是不同的,但我不能在这里使用它,因为它并不全是我的。 – Justin