LoginSignup
9
14

More than 5 years have passed since last update.

Rails開発で最低限気をつけること(=気をつけてほしいこと)

Last updated at Posted at 2019-03-07

概要

Rails開発で最低限気をつけること(=気をつけてほしいこと)をメモ
少し長いですがRailsを覚え始めの人に読んでいただければと。

全般

タイポをしない

当たり前ですが、タイポの原因はタイピングをミスすることです
残念ながらrubyは動的型付け言語であり、タイポによるエラーはプログラム実行時に発生します
タイポを防ぐ方法として、

  • Lintを活用する
  • 変数はコピペする
  • スペルが間違っていないか辞書 or Google で検索するようにする

などが挙げられます
上記を徹底し、 視覚的にタイポを防ぐタイピングをやめる ことでタイポ0を目指しましょう

インデントを揃える

PullRequestを作成する前には、必ずコードのフォーマットを直しましょう
インデントが揃っていることはソフトウェアエンジニアのマナーの一つだと思います

String vs Symbol

Symbolの方がパフォーマンスが良いため、できるだけStringではなくSymbolを使うようにしてください
理由は下記の記事を参考ください
Rubyの文字列とシンボルの違いをキッチリ説明できる人になりたい - Qiita

if vs if not vs unless

rubyでは条件式の判定に、 if if not unless などがあります
条件式が複雑かつ、否定演算子などが組み合わされると一気に可読性が低下し、バグの原因につながるため、
条件式では「常に正常系を」書くようにしています
いくつか例を挙げてみます

例: if ~ else 構文

if @record.save # 条件式は正常系
  # 成功時の処理を書く
else
  # 失敗時の処理を書く
end

unless でGurad構文(=早期リターン)

def process(record)
  return false unless record.valid? # 早期リターン(=条件式は正常系)
  # 以下、正常系の処理を実行
end

「常に正常系を」を記述することのを推奨する理由については下記リンクを参考にしてみてください
ifとunlessの使い分け

boolean型のメソッド名には末尾に ? をつける

一般的に、rubyではbooleanを返すメソッドには末尾に ? をつける習慣があります
メソッド名の末尾に ? がついていることで boolean を返すことがわかり可読性が上がります

ぼっち演算子 &. をつける

rubyでは、2.3から &. 演算子(safe navigation operator = ぼっち演算子)が導入されました
実行時に nil なオブジェクトに対してメソッドチェーンを実行すると undifined method error for nil:NilClass
なってしまうため、nil になる可能性のあるメソッドチェーン呼び出しには全て &. をつけるようにすべきです

ソースコードの責任の範囲を意識する

OOPの思想に沿って、ソースコードの責任の範囲を考えて設計&実装する
Rails開発はMVCに依存しがちになますが、もっと柔軟にクラスを切った方が良いと思います
また、アプリケーションやビジネスロジックに依存せず汎用的に使えるクラスは lib 配下に記述することもおすすめします

例として、下記のようにディレクトリを切ると良いかなと思います

- app
  - controllers
  - decorators
  - forms # form経由の値を扱う(Controllerをファットにさせない)
  - helpers
  - jobs
  - listeners # wisperなど、Observerパターンでcallbackを処理する
  - mailers
  - models
  - operators # ビジネスロジックを扱う(ControllerやModelをファットにさせない)
  - policies # punditなどで権限管理
  - validators # 独自定義したバリデーション
  - values # Valueオブジェクト
- lib
  - xxx
  - xxx
  - xxx

Controller

before_action でインスタンス変数への代入を控える

before_action を複数記述した場合、記述した順番に実行されます
before_action 内で、他の before_action で代入された変数を呼び出すと、
プログラムが正しく動作するかどうかが before_action を呼び出す順番に依存してしまい、
スパゲッティコードにつながってしまいます
可能であれば変数を取得できるメソッドを作成することをおすすめします

× before_action を使う

class UsersController < ActionController::Base
  before_action :set_user, only: [:show]
  def show
  end
  def set_user
    @user = User.find(params[:id])
  end
end

◯ 専用のメソッドを用意する

class UsersController < ActionController::Base
  def show
  end
  def user
    @user = User.find(params[:id])
  end
  helper_method: user
end

helper_method :user とすることで、viewファイルでも変数を参照できるようになります

インスタンス変数をメモ化する

ActiveRecord 経由で取得するデータは、変数をメモ化することで値のキャッシュができます
展開された変数はリクエスト終了時にクリアされるため、可能な限りキャッシュすることをおすすめします

class UsersController < ActionController::Base
  def show
  end
  def user
    # @note @user がnilの場合のみ代入され、nilでなければキャッシュされたデータを返す
    @user ||= User.find(params[:id])
  end
  helper_method: user
end

レコードの保存処理を行う場合は flash を表示する

レコードの保存処理を行う場合は成功時&失敗時に合わせて適切なflashメッセージを表示するようにしてください

def create
  if @record.save
    redirect_to records_path
    flash[:success] = 'レコードの保存に成功しました'
  else
    render :new
    flash.now[:error] = 'レコードの保存に失敗しました'
  end
end

def destroy
  if @record.destroy
    redirect_to records_path, flash: { success: 'レコードを削除しました' }
  else
    redirect_to records_path, flash: { error: 'レコードを削除できませんでした' }
  end
end

また、レコードの更新に失敗し render を実行する場合は flash.now を使うようにしてください
参考: 【Rails】flashとflash.nowの違い - avosalmonのブログ

Model

belongs_to には required: true または presence: true をつける

belongs_to で必ず親となるレコードが存在する場合は、 required: true または presence: true を記述してください

has_one, has_many には class_name をつける

has_one または has_many を使う場合は、 class_name オプションをつけることで、
モデルが取得できずエラーとなってしまうことを防ぐことができる場合があるため、記述するようにするべきです
必要に応じて foreign_key も指定することをおすすめします

has_one, has_many には dependent オプションをつける

削除時に has_one または has_many 先の子モデルに対する振る舞いを dependent オプションで定義できます
不要なレコードはDBのパフォーマンスにも影響が出るので、適切に設定することをおすすめします
dependent オプションについては、下記リンクで詳しく説明されていたので参照してみてください

ActiveRecord::has_manyのdependentオプション

バリデーションを記述する

DB層でのバリデーションが必要なカラムに対しては、validates メソッド等を使って
適宜バリデーションを記述する
また、必要に応じて適宜カスタムバリデーションを作成して再利用できるようにすることもおすすめします
カスタムバリデーションを実行する

View

form_with を使う

Rails5.1からは form_forform_tagform_with というインターフェースに統合され、
URLベース、スコープ、モデルを指定してformタグを生成できるようになりました

Ruby on Rails 5.1リリースノート

form_for を使う場合は local: true を設定してください
https://qiita.com/bluegirl_beer/items/a361171f653edcd888ad

form_forform_with ではモデルの指定でaction先を絞る

railsで自動生成されるpathって読みづらいですよね
form_forform_with では、渡すオブジェクトが保存されているかどうかで
create のアクションを実行するか、 update のアクションを実行するかを自動的に判別してくれます
また、必要に応じて methodaction オプションを渡すことで、アクション先を絞ることができます

DB

migrationファイルでカラムを追加するときは comment をつける

comment オプションをつけることで、生成されるスキーマファイルにコメントを追加できます
可能な限りコメントの追加をお願いします

class CreateBlogs < ActiveRecord::Migration[5.1]
  def change
    create_table :blogs, comment: 'ブログ' do |t|
      t.string :title, comment: 'タイトル'
      t.text :body, comment: '本文'
      t.timestamps
      t.datetime :deleted_at
    end
  end
end
9
14
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
14