Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
25
Help us understand the problem. What are the problem?

More than 1 year has passed since last update.

RailsのCRUD系メソッドの戻り値

概要

# 作成したインスタンスを変数に格納したい
user = User.build(
  name: 'Taro',
  age: 20,
)
user.save

# ↓これでええやん・・・。
user = User.create(
  name: 'Taro',
  age: 20,
)

うっかり冗長に書いてしまうのを防ぐため、
備忘録としてRailsのCRUD系メソッドの戻り値をまとめました。
(save(!)create(!)update(!)destroy(!)を取り扱います。)

環境:

  • Rails 6.0.2.1
  • Ruby 2.6.3

前提

こんな感じのテーブルとモデルです。

db/schema.rb(抜粋)
  create_table "users", force: :cascade do |t|
    t.string "name", null: false
    t.integer "age"
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
  end
app/models/user.rb
class User < ApplicationRecord
  validates :name, presence: true
end

戻り値一覧

save

save (ActiveRecord::Persistence)

データベースへの保存に成功した場合は true 、失敗した場合は false が戻り値になります。

user = User.create(name: 'Taro', age: 15)

# 成功
user.name = 'Jiro'
user.save
# => true

# 失敗
user.name = nil
user.save
# => false

参照

save!

save! (ActiveRecord::Persistence)

データベースへの保存に成功した場合は true が戻り値になります。
バリデーションに失敗した場合は、例外が発生します。

user = User.create(name: 'Taro', age: 15)

# 成功
user.name = 'Jiro'
user.save!
# => true

# 失敗
user.name = nil
user.save!
# ActiveRecord::RecordInvalid (Validation failed: Name can't be blank)

参照

create

create (ActiveRecord::Persistence::ClassMethods)

メソッドの内部では save (ActiveRecord::Persistence) を実行しています。
データベースへの保存の成功・失敗に拘らず、作成したインスタンスが戻り値になります。

# 成功
User.create(name: 'Taro', age: 15)
# => #<User id: 1, name: "Taro", age: 15,...>

# 失敗
User.create(name: nil, age: 15)
# => #<User id: nil, name: nil, age: 15, created_at: nil, updated_at: nil>

create (ActiveRecord::Relation)

メソッドの内部では create (ActiveRecord::Persistence::ClassMethods) を実行しています。
戻り値もcreate (ActiveRecord::Persistence::ClassMethods) と同じです。

users = User.where(age: 15)

# 成功
users.create(name: 'Taro')
# => #<User id: 1, name: "Taro", age: 15,...>

# 失敗
users.create(name: nil)
# => #<User id: nil, name: nil, age: 15, created_at: nil, updated_at: nil>

参照

create!

create! (ActiveRecord::Persistence::ClassMethods)

メソッドの内部では save! (ActiveRecord::Persistence) を実行しています。
データベースへの保存に成功した場合、作成したインスタンスが戻り値になります。
データベースへの保存に失敗した場合は、例外が発生します。

# 成功
User.create!(name: 'Taro', age: 15)
# => #<User id: 1, name: "Taro", age: 15,...>

# 失敗
User.create!(name: nil, age: 15)
# ActiveRecord::RecordInvalid (Validation failed: Name can't be blank)

create! (ActiveRecord::Relation)

メソッドの内部では create! (ActiveRecord::Persistence::ClassMethods) を実行しています。
戻り値も create! (ActiveRecord::Persistence::ClassMethods)と同じです。

users = User.where(age: 15)

# 成功
users.create!(name: 'Taro')
# => #<User id: 1, name: "Taro", age: 15,...>

# 失敗
users.create!(name: nil)
# ActiveRecord::RecordInvalid (Validation failed: Name can't be blank)

参照

update

update (ActiveRecord::Persistence::ClassMethods)

メソッドの内部では save (ActiveRecord::Persistence) を実行しています。
データベースへの保存の成功・失敗に拘らず、作成されたインスタンスが戻り値になります。

User.create(name: 'Taro', age: 15)

# 成功
User.update(1, name: 'Jiro') # 1はid
# => #<User id: 1, name: "Jiro", age: 15,...>

# 失敗
User.update(1, name: nil)
# => #<User id: 1, name: nil, age: 15,...>

update (ActiveRecord::Relation)

メソッドの内部では update (ActiveRecord::Persistence::ClassMethods) を実行しています。
戻り値も update (ActiveRecord::Persistence::ClassMethods)と同じです。

users = User.where(age: 15)

# 成功
users.update(1, name: 'Taro')
# => #<User id: 1, name: "Taro", age: 15,...>

# 失敗
users.update(1, name: nil)
# => #<User id: nil, name: nil, age: 15, created_at: nil, updated_at: nil>

update (ActiveRecord::Persistence)

メソッドの内部では save (ActiveRecord::Persistence) を実行しています。
戻り値も save と同じです。

user = User.create(name: 'Taro', age: 15)

# 成功
user.update(name: 'Taro')
# => true

# 失敗
user.update(name: nil)
# => false

参照

update!

update! (ActiveRecord::Persistence)

メソッドの内部では save! (ActiveRecord::Persistence) を実行しています。
そのため、データベースへの保存に失敗すると例外が発生します。
戻り値も save! と同じです。

user = User.create(name: 'Taro', age: 15)

# 成功
user.update!(name: 'Taro')
# => true

# 失敗
user.update!(name: nil)
# ActiveRecord::RecordInvalid (Validation failed: Name can't be blank)

参照

destroy

destroy (ActiveRecord::Persistence::ClassMethods)

メソッドの内部では destroy (ActiveRecord::Persistence) を実行しています。
戻り値は destroy (ActiveRecord::Persistence) の戻り値と同じです。

User.create(name: 'Taro', age: 15)
# => #<User id: 1, name: "Taro", age: 15,...>

# 成功
User.destroy(1)
# => #<User id: 1, name: "Taro", age: 15,...>

destroy (ActiveRecord::Persistence)

成功時は、フリーズされたインスタンスが戻り値となります。
before_destroy:abort を投げた場合は、 destory は実行されず、 false が戻り値となります。

user = User.create(name: 'Taro', age: 15)

# 成功
user.destroy
# => #<User id: 1, name: "Taro", age: 15,...>

参照

destroy!

destroy! (ActiveRecord::Persistence)

成功時は、フリーズされたインスタンスが戻り値となります。
before_destroy:abort を投げた場合は、 destory! は実行されず、 例外が発生します。

user = User.create(name: 'Taro', age: 15)

# 成功
user.destroy!
# => #<User id: 1, name: "Taro", age: 15,...>

参照

おわりに

ここまで細かく activerecord の中身を見に行ったことがなかったので、結構勉強になりました。
「あれ?戻り値 boolean やっけ・・・インスタンスやっけ・・・?」となっていたのが解消されてよかったです。
それぞれのメソッドの詳しい内容を見たい方は、参照先のURLを見てください。

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
25
Help us understand the problem. What are the problem?