Rails 6.1で生成コードをRuboCop適用済みにする

Rails 6.1 がリリースされたので、y-yagi さんによる待望のパッチが使えるようになった。

PR にあるように使い方はシンプルで、Rails 6.1 での config/environments/development.rb に以下の設定を足す。

config.generators.after_generate do |files|
  parsable_files = files.filter { |file| file.end_with?('.rb') }
  unless parsable_files.empty?
    system("bundle exec rubocop -A --fail-level=E #{parsable_files.shelljoin}", exception: true)
  end
end

RuboCop で Style/FrozenStringLiteralComment cop を有効にしているので、--auto-correct-all あるいは -A を指定している (RuboCop 0.87 以上は -ASafeAutoCorrect: false な cop への自動修正もされる) 。

bin/rails g を実行すると、コード生成の流れで rubocop コマンドが実行される。

% bin/rails g migration create_articles
Running via Spring preloader in process 80818
      invoke  active_record
      create    db/migrate/20201214064506_create_articles.rb
Inspecting 1 file
C

Offenses:

db/migrate/20201214064506_create_articles.rb:1:1: C: [Corrected] Style/FrozenStringLiteralComment: Missing frozen string literal comment.
class CreateArticles < ActiveRecord::Migration[6.1]
^
db/migrate/20201214064506_create_articles.rb:2:1: C: [Corrected] Layout/EmptyLineAfterMagicComment: Add an empty line after magic comments.
class CreateArticles < ActiveRecord::Migration[6.1]
^
db/migrate/20201214064506_create_articles.rb:4:1: C: [Corrected] Layout/EmptyLinesAroundBlockBody: Extra empty line detected at block body beginning.

1 file inspected, 3 offenses detected, 3 offenses corrected

すると、以下のように自動修正が適用されたコードが生成される。

% cat db/migrate/20201214064506_create_articles.rb
# frozen_string_literal: true

class CreateArticles < ActiveRecord::Migration[6.1]
  def change
    create_table :articles do |t|
      t.timestamps
    end
  end
end

自分はモデルやコントローラなどはコード生成しないが、マイグレーションファイルだけは bin/rails g を使っており、たまに fstring マジックコメントを書き忘れたまま CI に push してしまうので、この機能は待望していたものだった。

余談だけれど、かつて bin/rails g で生成するコードにデフォルトで fstring マジックコメントを足す PR を出して通せなかったことがあったけれど、これはアプリケーションレイヤーで (フックという抽象化によって) 問題解決をコントロールできる柔軟なアプローチで感動しました。

y-yagi さんありがとう!