【Rails保存版】Active Recordで作ったオブジェクトを保存しよう!(save/update)
Ruby on Railsでデータベースを操作するのに使うActive Record。
今回は、save
やupdate
を使って実現するオブジェクトの保存方法紹介します。
今回利用するテーブル情報はこちらです。
基本的な使い方
保存する役割を果たすメソッドは以下の通りいっぱいあります。
- save
- save!
- update
- update!
- update_attribute
- update_attributes
- update_attributes!
- update_column
- update_columns
- update_all
それぞれの違いは、「戻り値の違い」と「コールバックの有無」です。
使い所や実行結果などをそれぞれ見ていきたいと思います。
save
- よく使う処理: コントローラーのcreate
- 戻り値: true/false
基本的に利用するのは、create
アクションです。戻り値がtrue/falseになるので保存が成功したか失敗したかで処理を分けるように記述します。
# new_users_controller.rb def create @user = NewUser.new(new_user_params) if @user.save redirect_to :new_users_path, notice: 'ユーザーを登録しました。' else render :new end end
# 成功する場合 > user.name = 'opiyo' => "opiyo" > user.save (0.3ms) BEGIN NewUser Create (0.9ms) INSERT INTO "new_users" ("name", "created_at", "updated_at") VALUES ($1, $2, $3) RETURNING "id" [["name", "opiyo"], ["created_at", "2019-10-07 12:09:45.517006"], ["updated_at", "2019-10-07 12:09:45.517006"]] (0.6ms) COMMIT => true # 失敗する場合 > user.save (0.3ms) BEGIN (4.8ms) ROLLBACK => false
save!
- よく使う処理: モデル、rakeタスク
- 戻り値: 例外(ActiveRecord::RecordInvalid)
基本的に利用するのは、モデルやrakeタスクなどで利用します。合わせて例外処理を書く場面が多いと思います。
self.transaction do self.name = 'opiyo' self.save! end begin user.name = 'opiyo' user.save! rescue => e puts e end
update
- よく使う処理: コントローラーのupdate
- 戻り値: true/false
基本的に利用するのは、updateアクションです。
def update if @user.update new_user_params redirect_to new_users_path(@magazine), notice: 'ユーザーを保存しました' else render 'edit' end end
> user.update(name: 'opiyo') (0.3ms) BEGIN NewUser Create (5.8ms) INSERT INTO "new_users" ("name", "created_at", "updated_at") VALUES ($1, $2, $3) RETURNING "id" [["name", "opiyo"], ["created_at", "2019-10-07 13:03:40.364928"], ["updated_at", "2019-10-07 13:03:40.364928"]] (1.3ms) COMMIT => true
update!
- よく使う処理: モデル
- 戻り値: 例外(ActiveRecord::RecordInvalid)
基本的に利用するのは、モデルやrakeタスクなどで利用します。合わせて例外処理を書く場面が多いと思います。
self.transaction do self.save!(name: 'opiyo') end begin self.save!(name: 'opiyo') rescue => e puts e end
update_attribute
- よく使う処理: モデルやrakeタスク
- 戻り値: true/false
基本的に利用するのは、モデルやrakeタスクです。
update
との違いは、保存できるのは1つのカラムでvalidationを無視します。
# validationの設定 class NewUser < ApplicationRecord validates :name, presence: true end # 実行結果 > user.update(age: 1) (0.3ms) BEGIN (0.3ms) ROLLBACK => false > user.update_attribute(:age, 1) (0.3ms) BEGIN NewUser Create (0.4ms) INSERT INTO "new_users" ("age", "created_at", "updated_at") VALUES ($1, $2, $3) RETURNING "id" [["age", 1], ["created_at", "2019-10-07 13:29:20.417777"], ["updated_at", "2019-10-07 13:29:20.417777"]] (2.0ms) COMMIT => true
update_attributes
- よく使う処理: モデルやrakeタスク
- 戻り値: true/false
基本的に利用するのは、モデルやrakeタスクです。
update_attribute
との違いは、複数保存ができ、validationは実行されます。なので処理の内容としてはupdate
と全く同じです。
> user.update_attributes(age: 2) (0.3ms) BEGIN (0.2ms) ROLLBACK => false > user.update_attributes(name: 'opiyo', age: 2) (0.3ms) BEGIN NewUser Update (0.6ms) UPDATE "new_users" SET "name" = $1, "age" = $2, "updated_at" = $3 WHERE "new_users"."id" = $4 [["name", "opiyo"], ["age", 2], ["updated_at", "2019-10-07 13:32:12.006308"], ["id", 7]] (2.9ms) COMMIT => true
update_attributes!
- よく使う処理: モデルやrakeタスク
- 戻り値: 例外(ActiveRecord::RecordInvalid)
基本的に利用するのは、モデルやrakeタスクです。
update_attributes
との違いは、例外が発生します。なので処理の内容としてはupdate!
と全く同じです。
update_column
- よく使う処理: ajax使ってデータ更新するときやモデルやrakeタスク
- 戻り値: 例外(ActiveRecord::RecordInvalid)
基本的に利用するのは、モデルやrakeタスクです。
update
やupdate_attribute
との違いは、「validationを無視」「コールバック無視」「update_at無視」です。つまり保存するだけ。
update_columns
- よく使う処理: ajax使ってデータ更新するときやモデルやrakeタスク
- 戻り値: 例外(ActiveRecord::RecordInvalid)
基本的に利用するのは、モデルやrakeタスクです。
update_attributes
と同じで複数カラムを同時に更新するときに使います。内容はupdate_column
と同じで「validationを無視」「コールバック無視」「update_at無視」です。
まとめ
- create: save!
- update: update
- モデルやrakeタスク: save/update_attributes
- ただ保存したい: update_columns
- 例外: !
各メソッドの実行結果や、どうゆう時に何を使うかまとめてきました。
改めて見直すと、各メソッドの微妙な違いを意識して処理できてたか曖昧な部分もあるので見直したいなーと思いました。