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

SideCI Blog

自動コードレビューサービスSideCIを提供している株式会社アクトキャットのコーポレートブログです。



Ruby on Railsのコードをよりモダンにするために、Rails Best Practices入門・おすすめ設定

Railsのベストプラクティスを教えてくれるgem, rails_best_practicesの使い方や設定のおすすめを紹介いたします。

rails_best_practicesはRailsのベストプラクティスを投票しあうサイト、Rails Best Practicesの投稿をまとめて、コードがそれにそっているかをチェック、どう変えたほうが良いかをアドバイスしてくれるツールです。

ぜひ試しに使ってみて下さい。また、気に入ったら、SideCI上で継続的にお使い頂く事も可能です。

Table Of Contents

  • rails_best_practicesとは
  • ymlによるカスタマイズ方法
  • おすすめのyml

rails_best_practicesとは

rails_best_practicesは、railsアプリのコードの質をチェックするメトリクスツールです。

rubocopとは違い、主にrailsに特化したコード品質チェックが可能になります。

これより先の説明は、以下のバージョンで動作確認しています。 * MacOSX 10.10.1 * ruby 2.2.1p85 (2015-02-26 revision 49769) [x86_64-darwin14] * rails_best_practices 1.15.7

チェックの一例

チェックの一例をお見せします。

db/schema.rbが以下の様な内容だったとします。

ActiveRecord::Schema.define(version: 20131103153637) do
  create_table "book_authors", force: true do |t|
    t.integer  "book_id"
    t.integer  "author_id"
    t.datetime "created_at"
    t.datetime "updated_at"
  end

  create_table "books", force: true do |t|
    t.string   "name"
    t.datetime "created_at"
    t.datetime "updated_at"
  end

  create_table "authors", force: true do |t|
    t.string   "name"
    t.datetime "created_at"
    t.datetime "updated_at"
  end
end

これですとテーブル book_authorsの外部キーに、インデックスが付いていません。

これはrails_best_practicesが定義しているAlways add DB indexというルールに違反しています。

rails_best_practices コマンドでルール違反として検出することが出来ます。

$ rails_best_practices db/schema.rb
Source Codes: |====================================================================================|
/Users/me/repos/homework/db/schema.rb:16 - always add db index (book_authors => [book_id])
/Users/me/repos/homework/db/schema.rb:16 - always add db index (book_authors => [author_id])

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

Found 2 warnings.

always add db index と ルール違反を指摘されました。

rails_best_practicesには、以上のような、railsに特化したチェック項目が、複数個定義されています(version1.15時点で、41個)。

多くのチェック項目はrails_best_practicesのウェブサイトで参照できます。

rails_best_practicesのインストール

rails_best_practicesは、gemで提供されます。

Bundlerを利用する場合、Gemfileに

gem 'rails_best_practices', require: false

を追加します。

Gemfileを編集した後、

$ bundle

でインストールできます。

Bundlerを利用しない場合、$ gem install rails_best_practices でインストールできます。

基本的な使い方

実行コマンドは以下のとおりです。 以下、Bundlerを利用している場合は適宜bundle execを先頭につけてください。

$ rails_best_practices [options] path

htmlに結果を出力する

標準出力ではなく、htmlフォーマットで出力してみます。

お使いのrailsアプリのディレクトリに移動してください。

$ rails_best_practices -f html .

-f(--format)オプションで出力形式を指定できます。

実行するとrails_best_practices_output.htmlというファイルが生成されます。

ブラウザで開いてみます。

$ open rails_best_practices_output.html

alt="rails_best_practices output"

Check allをチェックすれば、警告箇所の内容(ファイル名(Filename)、該当違反箇所付近の行数(Line Number)、警告内容(Warning Messages)を表示させることが出来ます。

警告内容(Warning Messages)は、それぞれrails_best_practicesのウェブサイトへのリンクになっており、それぞれの警告内容の説明ページヘのリンクになっています。

ページの内容は英語ですが比較的簡素ですので、すぐ修正作業に着手することが出来ます。

ymlによるカスタマイズ方法

設定ファイル

設定ファイル(config/rails_best_practices.yml)を編集することにより、チェックする項目を減らしたり、オプションを調整することができます。

最初は-g(--generate)オプションで設定ファイルのひな形を生成することができます。

$ rails_best_practices -g

中身は、以下の様なyamlになっています。全体はこちら

AddModelVirtualAttributeCheck: { }
AlwaysAddDbIndexCheck: { }
#CheckSaveReturnValueCheck: { }
DefaultScopeIsEvilCheck: { }
DryBundlerInCapistranoCheck: { }
...(中略)...
UseTurboSprocketsRails3Check: { }

それぞれのルールについて、コメントイン・コメントアウトすることで有効・無効にすることができます。

また、ignored_files というオプション記法を用いて、それぞれのルールごとに、ルールの適用しないファイルを指定することができます。 例えば

DefaultScopeIsEvilCheck: { ignored_files: 'user\.rb' }

とすると「DefaultScopeIsEvilCheck」というルールについては、user.rbにおいては適用しない、ということができます。また、

LongLineCheck: { max_line_length: 80, ignored_files: ['db/migrate', 'config/initializers'] }

のようにパスを配列で渡すことも可能です。

おすすめの設定

最後に、おすすめのrails_best_practices.ymlを以下に提示します。
Download

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: { }

特徴としては、ほとんどデフォルトの設定を採用し、 以下の2つだけを、コメントアウトして無効化しています。

RemoveTrailingWhitespaceCheckの無効化

#RemoveTrailingWhitespaceCheck: { }

このルールは、「各行末にスペースがあってはいけない」というルールなのですが、railsに限った話ではなく、rubocopなどのツールで代用が効く話なので、チェックを割愛すべきと考えます。

RemoveUnusedMethodsInControllersCheckの無効化

#RemoveUnusedMethodsInControllersCheck: { except_methods: [] }

このルールは、「利用していないController中のmethodは除去すべき」というルールなのですが、routes.rb内で動的にルートを組み立てている時に誤判定率が高くなってしまうので、チェックを割愛すべきと考えます。

また、この2つ以外にも、RemoveUnusedMethodsInHelpersCheckRemoveUnusedMethodsInModelsCheckなども、誤判定することがあります。

一度走らせてみて誤判定が多いようでしたignored_filesオプションで部分的に無効化したり、コメントアウトすることをおすすめします。

UnusedMethods系はRubyの性質上、なかなかどこで呼ばれているかを追うのが難しいため、現状では誤検出してしまうケースも多々あるようです。誤検出で「使ってないから消しちゃえ」と思い消して、困ってしまう場合もあるかと思います。プロジェクト全体の見通しが良い場合にはUnusedMethods系は有効で良いと思いますが、見通しが悪い場合にはUnusedMethods系は、有効にするのに加えて、目視での確認を怠らないようにご注意下さい。

上記おすすめ設定はこちらからダウンロード下さい。
Download

UnusedMethods系を全て無効にしたバージョンはこちらからダウンロード下さい。
Download

rails_best_practicesの残念なところ

残念なところも一応紹介しておきます。。rails_best_practicesは解析が複雑なせいか、プロジェクトによっては、rails_best_practicesのgemが正常に動かない(異常終了もしくはProcessがフリーズ)するケースもあるようです。。

RemoveUnused系など、今回紹介しているオフにしてもいいかも?オプションをオフにしたら動くようになったという事例も聞きます。unusedなものを探すのはプロジェクトのコード全体をループして探さないといけないため、この部分にバグがあるのかもしれません。
ますますオフお勧めです。

まとめ

いかがでしたでしょうか。

本エントリーでは、Ruby on Railsのコードをよりモダンにするのに有用な、rails_best_practicesというgemの使い方、設定例、設定例の根拠などをご紹介させて頂きました。

継続的に使っていきたい方やチームに対して導入していきたい方、今後書くコードについてだけ、Railsのベストプラクティスを気にしながら書いていきたい、という方はぜひSideCI上で動くrails_best_practicesをお試し下さい!

GitHub Pull Request x rails_best_practices による自動コードレビューが出来る唯一のウェブサービスです。(本記事投稿時点)