我使用的是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