初めてのRubocop 自分なりのメモ
RuboCopとは
Rubyの静的コード解析を実行するgemです。難しく聞こえますが、要はRuboCopが.rbファイルに記述してあるコードを検査し、ここのコードは長すぎるね。とか、インデント入れたほうがいいよ。とかメソッド名変えようか。とかをコマンド1つでターミナルに吐き出しててくれます。(HTML、CSS、またはそれらの中の埋め込みrubyは解析してくれません。)
Rubocopのメリット
- コーディングスタイルをある程度統一できる
長いメソッド/モジュールの分割をほぼ強制される。
- Ruby 歴が短い人、改善意識の高い人の良い矯正になる
Rubocop 色に染まることで、どんどん怒られにくいコードを自発的に書く方向に矯正できる。
- Ruby の新しい構文、便利な構文を知る良い機会になる
Rubocop を使っていると「こういう風に書きたいならこう書いた方が分かりやすいよ」という提案を受けるとができ、知らなかったメソッドや慣習などを学ぶ機会を得ることができる。
RuboCopの基本
準備
group :development do
gem 'rubocop', require: false
gem 'rubocop-rails', require: false
end
→bundle install
$ rubocop
これでテストが開始される
関連ファイル
.rubocop.yml
RuboCopの設定ファイルです。対象となるファイルの種類だったり、チェックする構文のデフォルトを変えたりと,自分たちのコーディングスタイルに沿った現実的なルールをこのファイルで適用します。(RuboCopの設定アレコレに詳しく書いてあるので参考にしてみてください。)
.rubocop_todo.yml
あまりに警告が多い時に**$ rubocop --auto-gen-config**を実行することによって自動生成され、警告内容を全てこのファイルに一旦退避することができます。それ以降は退避された警告は無視されます。(git stashみたいな感じ?)
テスト結果
$ rubocop -a
で自動修正後、
git diff
で修正箇所を確認できる。
"(ダブルクオーテーション)は'(シングルクォーテーション)に
"派だったけど、'派になります。
コメントアウトの#とコメントの間は半角の空白を
コメントアウトが修正されていた!
条件に応じてカラムの値を格納していく記述
修正前
if params["task"][:matrix] == "1"
- @task.task_matrix = "重要で緊急でない"
- elsif params["task"][:matrix] == "0"
- @task.task_matrix = "重要かつ緊急"
- elsif params["task"][:matrix] == "3"
- @task.task_matrix = "重要でないかつ緊急でない"
- else
- @task.task_matrix = "重要でなく緊急"
- end
修正後
+ @task.task_matrix = if params['task'][:matrix] == '1'
+ '重要で緊急でない'
+ elsif params['task'][:matrix] == '0'
+ '重要かつ緊急'
+ elsif params['task'][:matrix] == '3'
+ '重要でないかつ緊急でない'
+ else
+ '重要でなく緊急'
+ end
ちゃんと動くよね??(不安)
unlessからのrender
修正前
- unless @task.update(task_params)
- render "edit"
- end
修正後
+ render 'edit' unless @task.update(task_params)
if文からのsave
def add_user(user)
@group_user = GroupUser.new(group: self, user: user)
- if @group_user.group.group_name.present?
- @group_user.save
- else
- end
+ @group_user.save if @group_user.group.group_name.present?
end
end
if文とsaveの順番が変わっていて心配
if文からのシリーズ
class Task < ApplicationRecord
# 自分の投稿に対するコメントの場合は、通知済みとする
- if notification.visitor_id == notification.visited_id
-
- notification.checked = true
- end
+ notification.checked = true if notification.visitor_id == notification.visited_id
notification.save if notification.valid?
end
-
-
end
if文やunless文が入ったときの構造変わり過ぎでは⋯
長過ぎるから折られたもの
修正前
def task_params
- params.require(:task).permit(:user_id, :task_title, :task_details, :start_date, :end_date, :task_status, :task_matrix)
end
修正後
+ params.require(:task).permit(:user_id, :task_title, :task_details, :start_date, :end_date, :task_status,
+ :task_matrix)
{}の初めと終わりは半角スペース
#修正前
num task_status: {未着手: 0, 進行中: 1, 保留: 2, 確認中: 3, 遅れ: 4, 完了: 5}
- enum task_matrix: {重要かつ緊急: 0, 重要で緊急でない: 1, 重要でなく緊急: 2, 重要でないかつ緊急でない: 3 }
-
#修正後
+ enum task_status: { 未着手: 0, 進行中: 1, 保留: 2, 確認中: 3, 遅れ: 4, 完了: 5 }
+ enum task_matrix: { 重要かつ緊急: 0, 重要で緊急でない: 1, 重要でなく緊急: 2, 重要でないかつ緊急でない: 3 }
配列を%記法に変換
# 変更前
- resources :users, only: [:edit, :update]
#変更後
+ resources :users, only: %i[edit update]
%i
%i記法は、%wと同様に空白区切りの文字列から配列を作成しますが、こちらは配列の要素がシンボルになります。
%i と%Iの違いは、
%I → 式展開あり
%i → 式展開なし
のみです。
自動テスト結果(心配修正)
@@ -35,12 +35,7 @@ class GroupsController < ApplicationController
@user = User.find_by(email: params[:email])
# 入力されたEmailのuserは存在するか
- unless @user.present?
- @group = Group.find(params[:id])
- @group_users = @group.group_users
- flash.now[:warning] = "メールアドレス: #{params[:email]} のメンバーは見つかりません。"
- render "show"
- else
+ if @user.present?
@group = Group.find(params[:id])
@group_user = GroupUser.where(user_id: @user.id).where(group_id: @group.id)
@@ -50,15 +45,20 @@ class GroupsController < ApplicationController
@group = Group.find(params[:id])
@group_users = @group.group_users
flash.now[:warning] = "#{@user.name}さんはすでに登録済みです"
- render "show"
+ render 'show'
end
+ else
+ @group = Group.find(params[:id])
+ @group_users = @group.group_users
+ flash.now[:warning] = "メールアドレス: #{params[:email]} のメンバーは見つかりません。"
+ render 'show'
end
else
@group = Group.find(params[:id])
@group_users = @group.group_users
- flash.now[:warning] = "登録したいメンバーのメールアドレスを入力してください"
- render "show"
+ flash.now[:warning] = '登録したいメンバーのメールアドレスを入力してください'
+ render 'show'
end
end
→正常に動いた!!
変えていいもの変えてるんだよね??
@@ -1,6 +1,6 @@
#!/usr/bin/env ruby
begin
- load File.expand_path('../spring', __FILE__)
+ load File.expand_path('spring', __dir__)
rescue LoadError => e
raise unless e.message.include?('spring')
end
diff --git a/bin/rake b/bin/rake
index d87d5f5..0ba8c48 100755
--- a/bin/rake
+++ b/bin/rake
何を変えたかわからない
#続きまして、自動修正できなかったものたち
サイズが大きすぎる
Offenses:
app/controllers/groups_controller.rb:10:3: C: Metrics/AbcSize: Assignment Branch Condition size for create is too high. [<5, 20, 2> 20.71/17]
def create ...
^^^^^^^^^^
app/controllers/groups_controller.rb:31:3: C: Metrics/AbcSize: Assignment Branch Condition size for confirm is too high. [<12, 42, 5> 43.97/17]
def confirm ...
^^^^^^^^^^^
app/controllers/tasks_controller.rb:14:3: C: Metrics/AbcSize: Assignment Branch Condition size for create is too high. [<5, 23, 8> 24.86/17]
def create ...
^^^^^^^^^^
89 files inspected, 3 offenses detected
太ったcontrollerを指摘してくれる。
schemaファイルも同様に指摘される。
Metrics/BlockLength:
Max: 60 (最大23!)
Offenses:
db/schema.rb:13:1: C: Metrics/BlockLength: Block has too many lines. [60/25]
ActiveRecord::Schema.define(version: 20_210_203_112_204) do ...
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
89 files inspected, 1 offense detected
Max 60でそれ以上になると指摘される。
今回の場合は80あったので指摘された。
メソッドが長いとのご指摘
Metrics/MethodLength:
Max: 23 (最大23!)
app/controllers/groups_controller.rb:10:3: C: Metrics/MethodLength: Method has too many lines. [12/10]
def create ...
コメントにはasciiのみを使用してください。
英語以外のコメントが入っていた場合指摘される。
Style::AsciiComments
non-ascii(英語以外)のコメントをチェック
app/controllers/groups_controller.rb:32:12: C: Style/AsciiComments: Use only ascii symbols in comments.
# Emailが入力されているか
自動修正できなかった者たちはわからないものが多かった⋯
都度確認していこう
参考