Railsで開発を続けていると
「Rubyのこの書き方って正しいのかな?」
「もっと綺麗な書き方があるんじゃないかな?」
「開発メンバーでコードの品質レベルを統一させたい!」
いまの書き方に不安になったり、コーディングルールの統一などについて、考える場面も出てくることでしょう。
そこで、ぜひ使ってほしいのが「RuboCop」です。
RuboCopとは、ソースコードの品質を下げないために使われるRubyのコーディングチェックツールです。
RuboCopを使うことで、誰でも簡単にソースコードの品質を維持できるようになります。
この記事では、RuboCopの導入から使い方までを詳しく紹介していきます。
もくじ
RuboCopとは
RuboCopとは、Rubyのコードがコーディング規約に沿っているかを確認できる「静的コード解析ツール(コーディングチェックツール)」の1つです。
RuboCopを使うことで、ソースコードに対して以下のようなチェックをおこないます。(ほかにもあります)
- インデント
- 文字数の長さ
- メソッド内の行数
- 条件式の見やすさ
- ソースコードの複雑度
- ハッシュなどの末尾にあるカンマの有無
これらのコーディング規約は、自分で追加したり削除したりとカスタマイズすることが可能です。
このような静的コード解析ツールを利用することで、複数メンバーで開発していても、コードを読みやすく品質を維持できるというメリットがあります。
もちろん、1人で開発しているときであっても、綺麗なコードで管理することに越したことはありませんよね。
RuboCopのインストール
RuboCopは、gemで簡単にインストールできます。
Gemfileに以下を追記して、Bundlerでインストールしましょう。
group :development do
:
:
gem 'rubocop', require: false
gem 'rubocop-rails'
end
$ bundle install

RuboCopの使い方
RuboCopの使い方は、とっても簡単です。
rubocop
コマンドを実行して、ソースコードがRuboCopの規約(ルール)に沿っているかをチェックするだけです。
$ rubocop
Inspecting 49 files
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
Offenses:
config.ru:1:1: C: Style/FrozenStringLiteralComment: Missing magic comment # frozen_string_literal: true.
# This file is used by Rack-based servers to start the application.
^
:
:
test/test_helper.rb:6:81: C: Metrics/LineLength: Line is too long. [82/80]
# Setup all fixtures in test/fixtures/*.yml for all tests in alphabetical order.
^^
49 files inspected, 166 offenses detected
おそらく、めちゃくちゃ警告が出たことでしょう。
このままの状態でRuboCopの警告をスルーするのは、ちょっと難しそうですね。
RuboCopの設定ファイルについて
本来であれば、RuboCopで警告された対象コードを確認し、しっかり対応するのがベストです。
ですが、RuboCopはデフォルトだとコーディング規約が厳しいうえにチェック範囲も広く、ライブラリなど実際に触れないファイルに関しても対象にしてしまいます。
普段、あまり触らないコードやファイルは除外したいですよね。
そこで、--auto-gen-config
オプションを使って、RuboCopのルールをカスタマイズするための「設定ファイル」を作ってみましょう。
$ rubocop --auto-gen-config
Added inheritance from `.rubocop_todo.yml` in `.rubocop.yml`.
Phase 1 of 2: run Metrics/LineLength cop
Inspecting 49 files
.CC.....................C..CCC..CC.C...C...CCC..C
49 files inspected, 64 offenses detected
Created .rubocop_todo.yml.
Phase 2 of 2: run all cops
Inspecting 49 files
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC.CCCCCCCCCCCCC
49 files inspected, 102 offenses detected
Created .rubocop_todo.yml.
上のコマンドを実行すると、以下の2つのファイルが作成されます。
- 「.rubocop.yml」…コーディング規約を設定するファイル
- 「.rubocop_todo.yml」…規約を無視するための設定ファイル
.rubocop.yml
は、独自のコーディング規約を設定するためのファイルです。
現段階では、規約を定義するような記述はありませんが、代わりに以下のような.rubocop_todo.yml
を読み込む記述があります。
inherit_from: .rubocop_todo.yml
.rubocop_todo.yml
は、現状は対応できない規約を一時的にスルーするための設定が書かれたファイルです。
そのため、最終的にはこのファイルの中身を空にすることが望ましいです。
ただし、現段階では「rubocopコマンドで出た警告をすべてスルーする」というような内容の記述がすでに書かれているはずです。
そのため、この状態でrubocop
コマンドを実行すると、以下のように警告が1つも出ない状態になります。
$ rubocop
Inspecting 49 files
.................................................
49 files inspected, no offenses detected
RuboCopの設定ファイルを変更
このままRuboCopを使い続けても、警告をすべてスルーする設定になっているため、まったく意味がありません。
そこで、もう少し現実的な設定にしてみます。
不要なコーディング規約や関係のないファイルを除外し、使いやすいコーディングチェックの設定に変更してみましょう。
ここでは.rubocop.yml
を以下のように設定しました。これはあくまで例なので、自分で調べながらカスタマイズしてみてくださいね。
また、.rubocop_todo.yml
の中身はすべて削除し、空にすることを忘れずに。
# 将来的には対応する規約の読込
inherit_from: .rubocop_todo.yml
# 追加した規約ファイル読込
require:
- rubocop-rails
AllCops:
# Rubyバージョン指定
TargetRubyVersion: 2.6
# 除外
Exclude:
- 'config.ru'
- 'bin/**'
- 'lib/**'
- 'db/**/*'
- 'config/**/*'
- 'script/**/*'
- !ruby/regexp /old_and_unused\.rb$/
# 日本語でのコメントを許可
AsciiComments:
Enabled: false
# クラスのコメント必須を無視
Documentation:
Enabled: false
# モジュール名::クラス名の定義を許可
ClassAndModuleChildren:
Enabled: false
# 文字リテラルのイミュータブル宣言を無視(freezeになるのはRuby3以降)
Style/FrozenStringLiteralComment:
Enabled: false
RuboCopでファイルを自動修正
RuboCopのコーディング規約の設定が終わったら、rubocop
コマンドを実行してみてください。警告の数がかなり減ったことに気付くはずです。
減ったとはいえ、すべて手作業で修正するのも面倒です。簡単なものはRuboCopに直してもらいましょう。
RuboCopには、警告している箇所を自動で修正してくれる機能があり、--auto-correct
オプションを使うことで、ある程度は自動で警告を修正してくれます。
「ある程度」というのは、RuboCopではどう修正していいのか判断できないところもあり、その場合はスキップされるという意味です。
RuboCopが自動修正できた箇所は「Corrected」と表示されます。
$ rubocop --auto-correct
Inspecting 19 files
CC..............C.C
Offenses:
Gemfile:44:81: C: Metrics/LineLength: Line is too long. [83/80]
# Call 'byebug' anywhere in the code to stop execution and get a debugger console
^^^
Gemfile:45:28: C: [Corrected] Style/SymbolArray: Use %i or %I for an array of symbols.
gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
^^^^^^^^^^^^^^^^^^^^^^^^^^
Gemfile:49:81: C: Metrics/LineLength: Line is too long. [98/80]
# Access an interactive console on exception pages or by calling 'console' anywhere in the code.
^^^^^^^^^^^^^^^^^^
Gemfile:51:3: C: [Corrected] Bundler/OrderedGems: Gems should be sorted in an alphabetical order within their section of the Gemfile. Gem listen should appear before web-co
nsole.
gem 'listen', '>= 3.0.5', '< 3.2'
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Gemfile:52:81: C: Metrics/LineLength: Line is too long. [130/80]
# Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Gemfile:54:3: C: [Corrected] Bundler/OrderedGems: Gems should be sorted in an alphabetical order within their section of the Gemfile. Gem rubocop should appear before sprin
g.
gem 'rubocop', require: false
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Gemfile:55:3: C: [Corrected] Bundler/OrderedGems: Gems should be sorted in an alphabetical order within their section of the Gemfile. Gem rubocop should appear before sprin
g-watcher-listen.
gem 'rubocop', require: false
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Gemfile:67:31: C: [Corrected] Style/SymbolArray: Use %i or %I for an array of symbols.
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Rakefile:2:81: C: Metrics/LineLength: Line is too long. [90/80]
# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
^^^^^^^^^^
test/application_system_test_case.rb:1:9: C: [Corrected] Style/StringLiterals: Prefer single-quoted strings when you don't need string interpolation or special symbols.
require "test_helper"
^^^^^^^^^^^^^
test/test_helper.rb:6:81: C: Metrics/LineLength: Line is too long. [82/80]
# Setup all fixtures in test/fixtures/*.yml for all tests in alphabetical order.
^^
19 files inspected, 11 offenses detected, 6 offenses corrected
RuboCopのリファクタリング手順
RuboCopの自動修正が終わったら、もういちどrubocop
コマンドを実行してみてください。
おそらく、いくつかの警告がまだ表示されるはずです。
$ rubocop
Inspecting 19 files
CC................C
Offenses:
Gemfile:44:81: C: Metrics/LineLength: Line is too long. [83/80]
# Call 'byebug' anywhere in the code to stop execution and get a debugger console
^^^
Gemfile:49:81: C: Metrics/LineLength: Line is too long. [98/80]
# Access an interactive console on exception pages or by calling 'console' anywhere in the code.
^^^^^^^^^^^^^^^^^^
Gemfile:52:81: C: Metrics/LineLength: Line is too long. [130/80]
# Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Rakefile:2:81: C: Metrics/LineLength: Line is too long. [90/80]
# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
^^^^^^^^^^
test/test_helper.rb:6:81: C: Metrics/LineLength: Line is too long. [82/80]
# Setup all fixtures in test/fixtures/*.yml for all tests in alphabetical order.
^^
19 files inspected, 5 offenses detected
この実行結果を見ると、警告が全部で5カ所でていますが、すべて「コメントの文字数が長すぎる」というものです。
これらのコメントが不要であれば、対象ファイルからコメントを削除してしまいましょう。
このようにRubCcopを実行、修正するという手順を繰り返し、ソースコードの品質を下げないようにするのが基本です。
そして、RuboCopの実行結果が最終的に以下のような状態になれば、ソースコードの品質が保たれていることになります。
$ rubocop
Inspecting 19 files
...................
19 files inspected, no offenses detected
RuboCopでRailsのコーディング規約を設定する際の注意点
もし、rubocop
を実行時に、Warning: unrecognized cop Rails found in .rubocop.yml
のようなエラーが出てしまった場合は、以下のような設定をしている可能性があります。
# バージョン0.72以降は使えないので注意
Rails:
Enabled: true
コメントにも書いてあるとおり、RuboCopのバージョンが0.72以降は「Rails Cops」が使えなくなりました。
RuboCopのバージョンが0.72以降の場合は、rubocop-rails
をgem
でインストールし、.rubocop.yml
にrequire: rubocop-rails
を追記してください。
まとめ
コーディングのルールは、会社やプロジェクトによっても様々でしょう。
開発メンバーとも相談し、現実的なラインで使い続けられるルールに設定するといいと思います。
また、RuboCopを使うことで、Rubyでの色々な記述方法を知ることもでき、Rubyを勉強し始めた方にとっても参考になるのでおすすめですよ。
RuboCopを導入して、快適なプログラミング生活を送ってくださいね!
またね、キツネ(@kitaaaa_kitsune)でした!

