概要
実務でRuboCopを以下の拡張Copをrequireして使っています。
今回はこの中からrubocop-railsについて、具体的にどんなCopが含まれているのか軽く調べてみました。
- rubocop-rails
- rubocop-rspec
- rubocop-performance
- rubocop-factory_bot
参考
RuboCopの拡張Copには、公式でメンテナンスされているものとサードパーティ製のものの2種類があります。
ちなみに上記の4つは全て公式のCopです。
- 公式の拡張Cop
https://docs.rubocop.org/rubocop/extensions.html#official-extensions - サードパーティ製の拡張Cop
https://docs.rubocop.org/rubocop/extensions.html#third-party-extensions
スレッドセーフとか低レイヤーな部分は自信ない方も多いと思うので、rubocop-thread_safetyとか助かるかもしれないですね。
rubocop-rails
rubocop-railsはRailsスタイルガイドに則った拡張Copです。
公式ドキュメントを軽くを目を通してみて、興味深かったもの、気づきのあったものをピックアップしてまとめました。
Rails/ReversibleMigration
migrationがロールバック可能な実装になっているかどうかをチェックしてくれるCopです。本番環境だと、バグやらデータ整備漏れが原因で不完全な状態のデータが生まれてしまい、マイグレーションにこけたりする場合もあるため、ロールバックできることをRuboCopが保証してくれると安心感があります。
Rails/DangerousColumnNames
既存メソッドを上書きしてしまうようなカラムが定義されていないかチェックしてくれるCopです。(例えばUserモデルにsaveという名前のカラムを定義すると、ActiveRecordのsaveメソッドを上書きしてしまう。)
Rails/Presence
a.present? ? a : nil
# ↓
a.presence
a.present? ? a : b
# ↓
a.presence || b
という修正を自動で行ってくれるCopです。
Rails/TimeZone
Time.now
やTime.parse
、to_time
等のメソッドはapplication.rb
で設定したタイムゾーンを無視して、システム時刻を基準に結果を表示します。
# システム時刻を基準に結果を表示するメソッド
Time.now
Time.parse('2015-03-02T19:05:37')
'2015-03-02T19:05:37'.to_time
このようなメソッドをapplication.rb
のタイムゾーンに従って時刻を表示するメソッドに修正してくれるCopになります。
# application.rbで設定したタイムゾーンに従って時刻を表示するメソッド
Time.current
Time.zone.now
Time.zone.parse('2015-03-02T19:05:37')
Time.zone.parse('2015-03-02T19:05:37Z')
Rails/WhereMissing
紐づく関連レコードが存在しないレコードを検索したいときは
Post.left_joins(:author).where(authors: { id: nil })
# と書かなくても
Post.where.missing(:author)
# と書けばよいそうです。
これを自動で修正してくれるCopです。
Rails/WhereMissing
リレーション先のレコードの存在をチェックする場合、where(条件).exists?
とexists?(条件)の2通りの実装パターンがあります。このCopsでどちらのパターンで統一するかを指定することができます。(デフォルトはパターン1のwhere+exists?になります。)
# パターン1(where+exists?)
Author.includes(:articles).where(articles: {id: id}).exists?
# パターン2(exists?)
Author.includes(:articles).exists?(articles: {id: id})
なおパターン1の場合はeager_load, パターン2の場合はpreloadとして振る舞うため、実行結果は同じでも実行されるクエリの内容、実行回数が異なります。