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

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

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

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

# 環境:
- Rails 7.0.4.3
- Ruby 3.2.1

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

```ruby:db/schema.rb(抜粋)
  create_table "users", force: :cascade do |t|
    t.string "name", null: false
    t.integer "age"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
  end
```

```ruby:app/models/user.rb
class User < ApplicationRecord
  validates :name, presence: true
end
```

# 戻り値一覧
## `save`
### `save (ActiveRecord::Persistence)`
データベースへの保存に成功した場合は `true` 、失敗した場合は `false` が戻り値になります。

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

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

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

### 参照
- [save (ActiveRecord::Persistence) - Ruby on Rails API](https://edgeapi.rubyonrails.org/classes/ActiveRecord/Persistence.html#method-i-save)

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

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

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

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

### 参照
- [save! (ActiveRecord::Persistence) - Ruby on Rails API](https://edgeapi.rubyonrails.org/classes/ActiveRecord/Persistence.html#method-i-save-21)

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

```ruby
# 成功
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)` と同じです。

```ruby
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 (ActiveRecord::Persistence::ClassMethods) - Ruby on Rails API](https://edgeapi.rubyonrails.org/classes/ActiveRecord/Persistence/ClassMethods.html#method-i-create)
- [create (ActiveRecord::Relation) - Ruby on Rails API](https://edgeapi.rubyonrails.org/classes/ActiveRecord/Relation.html#method-i-create)

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

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

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

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

```ruby
users = User.where(age: 15)

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

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

### 参照
- [create! (ActiveRecord::Persistence::ClassMethods) - Ruby on Rails API](https://edgeapi.rubyonrails.org/classes/ActiveRecord/Persistence/ClassMethods.html#method-i-create-21)
- [create! (ActiveRecord::Relation) - Ruby on Rails API](https://edgeapi.rubyonrails.org/classes/ActiveRecord/Relation.html#method-i-create-21)

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

```ruby
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)`と同じです。

```ruby
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` と同じです。

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

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

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

### 参照
- [update (ActiveRecord::Persistence::ClassMethods) - Ruby on Rails API](https://edgeapi.rubyonrails.org/classes/ActiveRecord/Persistence/ClassMethods.html#method-i-create)
- update (ActiveRecord::Relation)
  ドキュメントなし
- [update (ActiveRecord::Persistence) - Ruby on Rails API](https://edgeapi.rubyonrails.org/classes/ActiveRecord/Persistence.html#method-i-update)

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

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

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

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

### 参照
- [update! (ActiveRecord::Persistence) - Ruby on Rails API](https://edgeapi.rubyonrails.org/classes/ActiveRecord/Persistence.html#method-i-update-21)

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

```ruby
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` が戻り値となります。

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

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

### 参照
- [destroy (ActiveRecord::Persistence::ClassMethods) - Ruby on Rails API](https://edgeapi.rubyonrails.org/classes/ActiveRecord/Persistence/ClassMethods.html#method-i-destroy)
- [destroy (ActiveRecord::Persistence) - Ruby on Rails API](https://edgeapi.rubyonrails.org/classes/ActiveRecord/Persistence.html#method-i-destroy)

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


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

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

### 参照
- [destroy! (ActiveRecord::Persistence) - Ruby on Rails API](https://edgeapi.rubyonrails.org/classes/ActiveRecord/Persistence.html#method-i-destroy-21)


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