4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【Rails】saveとsave!の挙動の違い

Posted at

Ruby on RailsのActiveRecordで使われるsaveとsave!。この二つのメソッドの違いについて、改めて学習した内容をメモとして記録しておきます。

saveメソッド

  • Ruby on RailsのActiveRecordで扱うメソッド。
  • データベースへの保存を試みるメソッドである。
  • savesave!の2種類がある。
  • 「!」は、日本語では感嘆符、カッコよく言うとエクスクラメーションマークと呼ぶ。
  • ビックリマークとは呼ばないww

saveとsave!

  • savesave!両メソッドは一見同じように思えるが、その挙動には違いがある。
  • 両者の違いは、保存に失敗したときの挙動にある。
    • saveは、バリデーションに失敗するとfalseを返す。
    • save!は、バリデーションに失敗するとActiveRecord::RecordInvalidという例外を発生させる。
  • save!はエラーを厳しくチェックするバージョンのsaveだと言える。

コード間違い例

class PostsController < ApplicationController
  def index
    @posts = Post.all
  end

  def create
    @post = Post.new(post_params)
    if @post.save! #ここに注目
      redirect_to @post
    else
      render :new
    end
  end

  private

  def post_params
    params.require(:post).permit(:title, :content)
  end
end
  • 投稿を保存するPostsControllerのコードの一部。
  • createメソッドにおいて新しい投稿(Post)を作成し、データベースへの保存を試みている。
  • if文を用いて、保存が成功した場合は投稿したpostの画面に遷移させている。
  • 保存に失敗した場合には、render :newによって、postの新規作成画面に戻るように指示している。
  • ここで、注目すべきなのが、if @post.saveである。
  • if文を使って、成功した場合、失敗した場合、両方の真偽値に応じた挙動を支持するところなのだが、save!メソッドの場合、保存失敗は例外を返すという特徴があるため、elseの次のrender :newが実行されずに例外処理が実行されてしまう。
  • そのため、今回の例においては、以下のようにsave!メソッドではなく、saveメソッドを用いるのが良い。

コード正解例

  def create
    @post = Post.new(post_params)
    if @post.save # この場合「save!」ではなくこっちが正解
      redirect_to @post
    else
      render :new
    end
  end

参考サイト

4
1
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
4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?