selmertsxの素振り日記

ひたすら日々の素振り内容を書き続けるだけの日記

自プロダクトのRailsコーディング規約

参考図書

みんなでコーディングする上で、共通知識とする書籍を決める。

  • リーダブルコード
  • Object Oriented Programing in Ruby
  • Perfect Ruby
  • Effective Ruby

Service Objectsは使わない

理由としては、チームみんなで理解してやってくには難易度が高すぎるため。 基本的に app/models 下に置く。まずは、Object思考でちゃんとやれないか考えてみる。

https://www.netguru.co/blog/service-objects-in-rails-will-help

一つのテストの中で、expectを書きすぎてはいけない

何をテストしたいのかわかりにくくなるため。

https://github.com/reachlocal/rspec-style-guide#the-one-expectation

ActiveRecord standardのassociations, validations, or scopes はテストしない

これらのテストをすることは、ActiveRecordのmethodをテストしていることと同じであるため

https://signalvnoise.com/posts/3159-testing-like-the-tsa

でも、正規表現とかバリバリ使ってます!って話ならやってもいい。

Railsの controllerにて、before_action等でインスタンス変数のセットをしないこと

DRYに見えるかも知れないけれども、 viewにどのような変数を渡すのか判別が難しくなるので禁止。

Migrationの中でDBへのinsertをしてはいけない

たとえば、User.create(name: "hage") という形でレコードを追加する migrateがある。 その後、user table に対して、age カラムをnullや空文字を許容しない形で追加しようとすると、 migrate:reset 時に必ずエラーが出てしまう。

よって、以降の変更に制限を加えるコードになってしまうため、migrateの中での insertは許容しない

Rails のViewの中で、Databaseへのアクセスはしてはいけない

MVCの概念から考えても良くないし、queryが発行される場所を制御できなくなるため、 パフォーマンスチューニングが必要なときに難しくなるので。

ロガーを使わない程度のメッセージ標準出力には p ではなく puts を使う

MySQLにおけるString型カラムはNULLを許容しない

  • string型にnullを許容すると、nullチェックする必要性が生まれる
  • nullチェックするコストは省きたい
  • nullチェックする必要があるカラムなのか、常に判断するのは難しい
  • よって、原則としてstring型はnullを許容しないようにする

定数はconfig/initializers/constants.rb 周りに置く

railsconfig にデータを保持させると、データを追加させたときに、みんな railsconfig を更新しなければならなくて手間。settings はコードに乗せてはいけない情報のみを扱いたい。

http://guides.rubyonrails.org/autoloading_and_reloading_constants.html#autoloading-and-initializers

ActiveRecord モデルが存在しない _id のカラム命名は都度検討する

_id で終わるカラム名は慣例的な経緯もあり、ActiveRecord モデルの存在を想起する場合がある。 一方で、外部システム連携時など、外部システム側で使用しているフィールド名 xxx_idカラム名としてそのまま採用した方が見通しよく把握できるケースも多い。

ここはチーム内で良く議論する必要がある。

ActiveRecord Callbackは使わない

class User
  after_create :send_mail
end

mailを送られるの気づかなくて爆死などを防ぎたい。 あと、factoryを作るのがツラくなる。そのときは便利に見えても、後々負債になるから禁止。

Queryは基本的にScopeで書く

※ これはプロダクト毎に意見が分かれる部分があると思うので、一概に適用はしないこと。

Rails上で発行されるQueryについて、全てModelに集約されていると、どのモデルでどのようなQueryが発行されているのか見通しがよくなる。同じ様な結果を得るために、似たようで微妙に異なるQueryが大量に生成される問題を避けることにも繋がるため、基本的に発行されるQueryはModelで参照できるScopeとして定義すること。

参考文献