私はRailsを使用していますが、ここでの根本的な質問はもっと広く適用されます。私は自分のWebアプリケーション上で、フィルタリングしているものを指定し、それらのフィルタ(MongoDB)に基づいてデータベースを照会できるようにするためのレポートページを持っています。複数のオプションに基づいたクエリのクリーンアップ
データは、ホテルの周りに基づいており、ユーザが最初に(state_one
、state_two
、state_three
)ホテルの領域を選択する必要があり、その後、ホテルのその後の状態(planning
、under_construction
、operational
)、任意の基準、価格帯(200
,300
,400
)。ユーザーは、これらのオプションのそれぞれを複数選択できます。
私のやり方は空の配列を作成し、各領域を繰り返し、ユーザーがその領域を選択した場合は領域を配列にプッシュすることです。次に、その配列を繰り返して、その地域のホテルのステータスを評価します。ユーザーが選択したステータスのホテルがあれば、そのホテルを新しい空の配列に追加します。それから私は価格帯についても同じことをします。
これは動作しますが、コードが攻撃的乱雑で、ここでのコードの例です:
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_state」が「:one」の代わりに「hotel_is_in_state_one」を持っているのはなぜですか? – tadman
ActiveRecordの 'where'メソッドは、配列をSQLの' WHERE/IN'ステートメントに変換します。だから、 'Hotel.where(state:params [:options] [:region]、region:params [:options] [:region])'のようなことができるはずです。もちろん、攻撃から保護するために、permitted_paramsメカニズムを使用してパラメータをフィルタリングする必要があります。 – moveson
@tadman私はこのコードをこの例題のために書いています。実際のコードではありません。私がしたいことを説明すると思っただけですが、実際のアプリケーションは異なりますが、それはすべて私のものではありません。 – Justin