Help us understand the problem. What is going on with this article?

【Rails/ActiveRecord】createとcreate!の違いについて

概要

新規レコードを作成するActiveRecordメソッドcreateについて。
createcreate!の違いについて学んだので解説します。


結論 : 例外を発生させるかどうか

!の有り無しで何が違うのか。
結論「例外を発生させるかどうか」です。

とはいえ「例外」というのもわかりにくいですよね。
あくまで実際に起こる違いで説明すると、!の有り無しで変わるのは、処理に失敗した時に「あの赤い画面がでるかでないか」です。


create!の場合

create!にした場合、バリデーションに引っかかると、下記のようにActiveRecord::RecordInvalid例外が発生し、おなじみの画面が表示されます。

domo

実際の動作を追ってみましょう。

今回用いたコードは次の通りです(※createアクションの記述は非推奨です)。

① ルーティング

app/config/routes.rb
Rails.application.routes.draw do
  root to: 'comments#index'
  resources :comments, only: [:create]
end
  1. index.html.erbのフォームで空の値を送信
  2. comments#createをリクエスト

② comments#createアクションを実行

app/controllers/comments_controller.rb
class CommentsController < ApplicationController

  def index
    @comments = Comment.all.order("created_at DESC")
    @comment = Comment.new
  end

  def create
    # このcreateアクションの書き方は非推奨です。
    @comment = Comment.create!(comment_params)
    redirect_to root_path
  end

  private

  def comment_params
    params.require(:comment).permit(:text)
  end
end
  1. ActiveRecordメソッドcreate(new + save)を読み込み
  2. comment_paramsでパラメータを取得 (textカラムの値は空)
  3. createのsave部分でバリデーションチェック

③ Commentモデルでバリデーションチェック

app/models/comment.rb
class Comment < ApplicationRecord
  validates :text, presence: true
end
  1. textカラムに設定したvalidationに引っかかる
  2. 保存できないので、例外発生
  3. あの赤い画面が表示される

✔ 以上の流れを追ったGIF

しっかりエラー画面が表示されました。

demo


!なしの場合

下記のcreateアクションに対して、フォームを送信します。

app/controllers/comments_controller.rb
def create
  @comment = Comment.create(comment_params) # ! を除外
  redirect_to root_path
end

✔ この場合の動作の様子(GIF)

例外処理によるエラー画面発生が起こらず、リダイレクトされます。

demo


まとめ

  • create!!は例外を発生させる記述
  • 今回のケースではActiveRecord::RecordInvalid例外を発生させてエラー画面遷移
  • !がない場合は、保存されずにそのまま次のリダイレクトが実行される


参考

keisukesaito
25歳。猫派。2020/09からエンジニア転職。2021/01からWeb系エンジニアとして頑張ります。
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away