ネストされた each/map Ruby のすべての要素を徹底的に比較する
概要
コレクションの Rails パラメータと、値をチェックする列を持つ既存のモデルの関連付けを取得するメソッドを書きました。これまで私が行ってきたことは、rails パラメータをクリーンアップし、その中に入れ子になったループ配列のマップを使用して要素を反復処理することです。このアプローチの問題は、どちらかの配列の値が失われる場合があることです。基本的に、両方の配列のすべての組み合わせを比較するわけではありません。両方の配列のすべての要素の組み合わせを比較するにはどうすればよいですか?
water_bottles = water_bottle_params.to_unsafe_h.map {|_w, v| v}
formatted_water_bottles = water_bottles.reject(&:blank?)
all_water_bottles = current_user.water_bottles
formatted_water_bottles.each do |w|
all_water_bottles.map |wb|
if wb.name == w['name']
raise "Water Bottle Exist!"
end
end
end
解決策
パラメータのウォーターボトル名のいずれかがデータベースにすでに存在する場合に例外を発生させたいようです。その場合、メソッド全体はおそらく次のようにはるかに単純に書くことができます。
bottle_names = water_bottle_params.values.compact_blank
raise 'Water Bottle Exist!' if current_user.water_bottles.exists?(name: bottle_names)
このバージョンでは FinderMethods#exists? を使用します。一致するボトル名が存在するかどうかをデータベース内で直接判断します。これは通常、すべてのレコードをメモリにロードし、配列メソッドを使用して両方の配列を比較するよりもはるかに高速です。さらに、この方法では必要なメモリが少なくなります。
コードを簡素化するために使用したその他のメソッド:map の代わりに value { |_k, v| v } と .reject(&:blank?) の代わりに Compact_blank を使用します。