開発備忘録 2018/10/15

[ActiveRecord] 関連するテーブルに対して where を適用する

users と comments が one-to-many の関係にあるときに、active な user のコメントを取得したいとする。

Comment.joins(:user).where(user: { deleted: :active })

Rails でのログ出力について

ログの出力レベル

ログレベル
debug
info
warn
error
fatal
unknown

出力レベルを設定することで、そのレベル未満のメッセージは表示されないようになる。
例えば production 環境では :info にして :debug の内容は表示しないようにするといった切り分けが可能になる。

標準出力に吐き出す場合

Rails.logger = Logger.new(STDOUT)

Rails.logger.debug 'debug'

特定のファイルに吐き出す場合

logger = ActiveSupport::Logger.new('log/test.log')

logger.error 'error'

ログ出力におけるパフォーマンスについて

まず :debug:fatal とでは出力される情報量が :debug の方が多いので与える負荷は大きくなる。
これを踏まえた上で、以下のログ出力におけるパフォーマンスについて考えてみる。

logger.debug "-- message: #{error.message}"

これは出力レベルが :debug でなくともパフォーマンスに影響が出る。

負荷を大きくしている原因は以下のふたつだ。

  • String のインスタンスの生成が比較的重め

  • 文字列の中で式展開している

この問題を回避するためには String のインスタンスではなくブロックを渡してやればいい。

logger.debug { "-- message: #{error.message}" }

ブロックを渡すことで遅延読み込みになるので、出力レベルが :debug より大きい場合はブロックの中身が評価されないようになる。