気づけばeachばかり… Rails開発でよくある落とし穴と解決法

ruby on rails

Railsでの開発中に、繰り返し処理でよく使う`each`メソッド。便利ですが、気づけばほぼすべての処理で`each`を使ってしまっていませんか?
本記事では、 Rails開発でよくある落とし穴と解決法 の一つとして`each`だけでなく`map`や`select`、`reject`などのEnumerableメソッドを使いこなしてコードをもっと効率的で読みやすくする方法を解説します。


each:繰り返し処理の基本

主な用途: 副作用を伴う処理(例えばメール送信やログ記録)。戻り値が不要な場合に使います。


users = User.where(active: true)
users.each do |user|
  NotificationMailer.send_welcome_email(user).deliver_now
end

ポイント: 副作用が目的の処理には適切ですが、データ変換には向いていません。

map:データの変換

主な用途: 要素を変換して新しい配列を作る場合に使います。


users = User.where(active: true)
user_emails = users.map(&:email)

eachとの違いは、mapは新しい配列を返すことです。以下の例のように、mapを使うと意図が明確になります。


# 悪い例
emails = []
users.each { |user| emails << user.email }

# 良い例
emails = users.map(&:email)

selectとreject:要素のフィルタリング

主な用途:
select: 条件を満たす要素を取得。
reject: 条件を満たさない要素を除外。


# selectで条件を満たすユーザーを取得
active_users = users.select(&:active?)

# rejectで条件を満たさないユーザーを除外
inactive_users = users.reject(&:active?)

ActiveRecordのwhereを使った方が効率的な場合もありますが、複雑な条件処理が必要な場合にはselectが便利です。

番外編:partitionで条件分岐を簡潔に

partitionを使うと、条件に応じて要素を2つのグループに分けられます。


active_users, inactive_users = users.partition(&:active?)

メリット: selectrejectを2回使う代わりに1回の処理で済みます。

まとめ

  • each: 副作用を伴う処理に使用。
  • map: 配列の変換処理に最適。
  • select/reject: 条件に基づくフィルタリングに使用。
  • partition: 要素を2つのグループに分けたい場合に便利。

Railsのコードベースを読みやすく保つためには、状況に応じて適切なメソッドを選ぶことが大切です。意図が伝わるコードを目指して、日々の開発をより効率的にしていきましょう!

コメント

タイトルとURLをコピーしました