読者です 読者をやめる 読者になる 読者になる

もた日記

くだらないことを真面目にやる

Railsメモ(24) : Rails Best Practicesでコードの品質をチェックする

Ruby on Rails

Rails Best PracticesというRailsのベストプラクティスがまとめられているサイトがあって、コードがそのベストプラクティスに沿っているかをチェックしてくれるrails_best_practicesというgemがあるので試してみる。

github.com


rails_best_practicesのインストール


Gemfileに下記行を追加してbundle installする。

group :development do
  gem 'rails_best_practices'
end

これでrails_best_practicesというコマンドが使えるようになったので、アプリのディレクトリに移動して下記コマンドを実行する。

$ rails_best_practices
Source Codes: |===============================================================================================================================|
/home/vagrant/rails/billboard/app/helpers/songs_helper.rb:1 - remove empty helpers
/home/vagrant/rails/billboard/app/helpers/artists_helper.rb:1 - remove empty helpers

Please go to http://rails-bestpractices.com to see more useful Rails Best Practices.

Found 2 warnings.

2つの警告が検出されたが、何の記述もないヘルパーが存在しているのが問題らしいので削除してみる。そもそも、このファイルはrails g controllerで自動生成されたものなので、rails g controller --no-helperのようにオプションを追加して生成させないのがよいのだろう。
ヘルパーファイルを削除した結果、警告がなくなったことが確認できる。

$ rails_best_practices
Source Codes: |===============================================================================================================================|

Please go to http://rails-bestpractices.com to see more useful Rails Best Practices.

No warning found. Cool!

なお、-f htmlオプションを付ければ結果をhtml出力できる。Warning Messageのところがリンクになっており、どのようなベストプラクティスなのかが簡単に確認できるので便利。

$ rails_best_practices -f html

f:id:wonder-wall:20150819202809p:plain

rails_best_practicesの設定


そもそも何のベストプラクティスをチェックしているのかが気になるので、その場合は-gオプションで設定ファイルを生成してみる。
config/rails_best_practices.ymlという設定ファイルが生成され、それによると41種類のベストプラクティス(6種類はデフォルトでコメントアウト)があるようだ。
それぞれのベストプラクティスがどのような内容なのかはRails Best Pracitcesのサイトで同じ名前のものをチェックすればよい。

$ rails_best_practices -g
$ cat config/rails_best_practices.yml
AddModelVirtualAttributeCheck: { }
AlwaysAddDbIndexCheck: { }
#CheckSaveReturnValueCheck: { }
DefaultScopeIsEvilCheck: { }
DryBundlerInCapistranoCheck: { }
#HashSyntaxCheck: { }
IsolateSeedDataCheck: { }
KeepFindersOnTheirOwnModelCheck: { }
LawOfDemeterCheck: { }
#LongLineCheck: { max_line_length: 80 }
MoveCodeIntoControllerCheck: { }
MoveCodeIntoHelperCheck: { array_count: 3 }
MoveCodeIntoModelCheck: { use_count: 2 }
MoveFinderToNamedScopeCheck: { }
MoveModelLogicIntoModelCheck: { use_count: 4 }
NeedlessDeepNestingCheck: { nested_count: 2 }
NotRescueExceptionCheck: { }
NotUseDefaultRouteCheck: { }
NotUseTimeAgoInWordsCheck: { }
OveruseRouteCustomizationsCheck: { customize_count: 3 }
ProtectMassAssignmentCheck: { }
RemoveEmptyHelpersCheck: { }
#RemoveTabCheck: { }
RemoveTrailingWhitespaceCheck: { }
RemoveUnusedMethodsInControllersCheck: { except_methods: [] }
RemoveUnusedMethodsInHelpersCheck: { except_methods: [] }
RemoveUnusedMethodsInModelsCheck: { except_methods: [] }
ReplaceComplexCreationWithFactoryMethodCheck: { attribute_assignment_count: 2 }
ReplaceInstanceVariableWithLocalVariableCheck: { }
RestrictAutoGeneratedRoutesCheck: { }
SimplifyRenderInControllersCheck: { }
SimplifyRenderInViewsCheck: { }
#UseBeforeFilterCheck: { customize_count: 2 }
UseModelAssociationCheck: { }
UseMultipartAlternativeAsContentTypeOfEmailCheck: { }
#UseParenthesesInMethodDefCheck: { }
UseObserverCheck: { }
UseQueryAttributeCheck: { }
UseSayWithTimeInMigrationsCheck: { }
UseScopeAccessCheck: { }
UseTurboSprocketsRails3Check: { }

なお、ベストプラクティス単位でチェックしたくないファイルがある場合は以下のようにignored_filesで指定すれば無視できる。

DefaultScopeIsEvilCheck: { ignored_files: 'user\.rb' }
LongLineCheck: { max_line_length: 80, ignored_files: ['db/migrate', 'config/initializers'] }


guard-rails_best_practicesで自動実行する


github.com

RuboCopのときと同じようにGuardで自動実行してみる。
Gemfileに下記行を追加してbundle installする。

group :development do
  gem 'guard'
  gem 'guard-rails_best_practices'
end

Guardfileに設定を追加するために下記コマンドを実行。

$ guard init rails_best_practices
23:41:27 - ERROR - Could not load 'guard/rails_best_practices' or '~/.guard/templates/rails_best_practices' or find class Guard::Rails_best_practices
23:41:27 - ERROR - Error is: No such file or directory @ rb_sysopen - /home/vagrant/.guard/templates/rails_best_practices

ところがエラーで出てうまくいかない。

によると、バグっぽいので手動で下記内容をGuardfileに追記する。
(結果を通知するためにnotify: true、Guard起動時にrails_best_practicesを実行したくないのでrun_at_start: falseを追加)

guard :rails_best_practices, notify: true, run_at_start: false do
  watch(%r{^app/(.+)\.rb$})
end

Guardを起動してみると今度は別のエラーが出た。

$ guard
21:02:40 - ERROR - Could not load 'guard/rails_best_practices' or find class Guard::RailsBestPractices
21:02:40 - ERROR - Error is: cannot load such file -- guard/guard
21:02:40 - ERROR - /home/vagrant/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/guard-rails_best_practices-0.1.3/lib/guard/rails_best_practices
.rb:2:in `require'
 …

いろいろ調べたところGemfileを書き換えたらうまくいった。

gem 'guard-rails_best_practices', git: 'https://github.com/logankoester/guard-rails_best_practices.git'

これでRuboCopに続きRails Best Practicesも自動実行されるようになり、結果に問題があれば通知されるようになる。

f:id:wonder-wall:20150819212057p:plain

tmuxのステータスラインに通知されるようにしているのだが、両方に問題がある場合RuboCopの結果が表示された後すぐにRails Best Practicesの結果が表示されてしまう。どう対応するのがベストかはわからないが、とりあえずC-b ~を押せばステータスラインのメッセージ履歴が確認できる。

f:id:wonder-wall:20150819213426p:plain

パーフェクト Ruby on Rails

パーフェクト Ruby on Rails