こんにちは!システムエンジニアのオオイシです。
Ruby on Railsのupdate_attributesをご存知ですか?
update_attributesはデータベースの値を複数同時に更新するために利用します。
この記事では、
- update_attributesとは
- update_attributesでモデルを更新してみよう
といった、基本的な解説から
- update_attributesはupdateの別名なので同じ
- update_attributesとsaveを比較して実行してみる
- update_attributes!はvalidationで例外を投げる
- validationをスキップする方法
- モデルの更新方法一覧
などの応用的な使い方関しても解説していきます。
今回はそんなupdate_attributesについてわかりやすく解説します!
update_attributesとは
update_attributesとは、Ruby on Railsのモデルに備わるメソッドで、
- モデルオブジェクト.update_attributes(キー: 値, キー: 値 … )
のようにHashを引数に渡してデータベースのレコードを複数同時に更新することができるメソッドです。
データベースへの更新タイミングは、update_attributesメソッドの実行と同時で、validationも実行されます。
そんな、update_attributesメソッドの使い方を次項で見ていきましょう。
なお、validationsの使い方はこちらで詳しく解説しているので、ぜひ参考にしてください。
update_attributesでモデルを更新してみよう
姓名(name)と年齢(age)をもつユーザ(User)モデルを作成し、
- 姓名:侍 太郎 → 侍 次郎
- 年齢:23 → 20
に変更するサンプルプログラムを確認してみましょう。
初めに、ユーザ(User)モデルを作成します。
$ bin/rails g model User name:string age:integer $ bin/rails db:create # 初めてデータベースを作成するときは実行 $ bin/rails db:migrate
railsコンソールから初期データをデータベースへ登録します。
$ bin/rails c >user = User.new( name: "侍 太郎", age: 23) >user.save
データベースへ登録されたデータを検索して登録されたか確認します。
>User.all => #<ActiveRecord::Relation [#<User id: 1, name: "侍 太郎", age: 23, created_at: "2018-07-03 01:30:32", updated_at: "2018-07-03 01:30:32">]>
姓名(name)は 侍 太郎→ 侍 次郎、年齢(age)は 18 → 20 に更新してみましょう。
> user.update_attributes(name: "侍 次郎", age: 20) (0.3ms) BEGIN SQL (0.5ms) UPDATE `users` SET `name` = '侍 次郎', `age` = 20, `updated_at` = '2018-07-03 01:37:34' WHERE `users`.`id` = 1 (2.2ms) COMMIT => true
データベースへ更新されたことを確認してみます。
>User.all User Load (0.5ms) SELECT `users`.* FROM `users` LIMIT 11 => #<ActiveRecord::Relation [#< User id: 1, name: "侍 次郎", age: 20, created_at: "2018-07-03 01:30:32", updated_at: "2018-07-03 01:37:34">]>
このように、データベースの値が更新されたことが確認できました!
つづいて、update_attributes の応用的な使い方について解説していきます。
なお、rails g modelコマンドの使い方については、こちらに詳しく解説していますので、ぜひ参考にしてください。
rails consoleについては、こちらで詳しく解説しています。
update_attributesのいろいろな使い方
update_attributesはupdateの別名なので同じ
update_attributesメソッドはupdateメソッドの別名(alias)です。
違いはないので、お好みで使っていただければと思います。
でも、update_attributesの方が複数の値を更新する意味で直感的かな?と思ってます。
update_attributesとsaveを比較して実行してみる
saveメソッドでもモデルの更新は可能です。
update_attributesとの違いを比較すると、
- save → 変更のあった属性(attribute)を更新
- update_attributes → 引数で指定したHashオブジェクトで更新
の違いがあります。
サンプルプログラムで確認してみましょう。
saveメソッドの例:
> user.name = "侍 三郎" > user.age = 16 > user.save # ここでデータベースに更新
update_attributesメソッドの例:
> user.update_attributes(name: "侍 三郎", age: 16) # 1行でデーターベースの更新
どちらも結果は同じです。
INSERT(新規にデータ登録)する場合やモデルを順次に変更する場合はsaveメソッドを使い、Ruby on Railsのパラメータなどで更新したいときは、update_attibutesを使うと言った使いわけが適しているでしょう。
update_attributes!はvalidationで例外を投げる
この節はバリデーションがかかっている前提でお話します。
update_attributesメソッドは、データベースに更新する直前にvalidationを実行します。
update_attributes!メソッドもありますが、違いは、validationで妥当性がなかった場合に、
- update_attributes → falseを返す
- update_attributes! → 例外を投げる
の違いがあります。
姓名(name)を必須入力とするユーザーモデル(User)でupdate_attributesとupdate_attributes!の違いを確認するサンプルコードをみてみましょう。
update_attributes:
irb(main):005:0> user.update_attributes(name: nil) (0.3ms) BEGIN (0.6ms) ROLLBACK => false
update_attributes!:
irb(main):006:0> user.update_attributes!(name: nil) (0.3ms) BEGIN (0.1ms) ROLLBACK ActiveRecord::RecordInvalid: Validation failed: Name can't be blank
このようにupdate_attributes!は例外が発生することが確認できました。
validationをスキップする方法
テストや開発中でvalidationを実行せずに保存したい場合もあるでしょう。
そのような場合はupdate_columnsを使うと直接SQLを実行するためvalidationをスキップできます。
確認してみましょう。
> user.update_columns(name: nil) SQL (3.0ms) UPDATE `users` SET `users`.`name` = NULL WHERE `users`.`id` = 1 => true
次項では、これまで紹介したメソッド以外にも便利なメソッドがあるので、一覧でまとめてみました!
モデルの更新方法一覧
モデルでデータベースのレコード更新するメソッドの一覧をまとめてみました。
この一覧でやりたいことの全てが実現できます。
メソッド | 説明 | 例 |
---|---|---|
モデル. update_attributes (Hashオブジェクト) | 引数の Hash オブジェクトを更新。 validationあり(false) | sample. update_attributes( key1: "value1", key2: "value2" ) |
モデル. update_attributes! (Hashオブジェクト) | 同上 validationあり(例外) | sample. update_attributes!( key1: "value1", key2: "value2" ) |
モデル. update (Hashオブジェクト) | #1の別名 | - |
モデル. update! (Hashオブジェクト) | #2の別名 | - |
モデル. save | 変更された オブジェクトを更新。 INSERT(新規登録) としても使う。 validationあり(※false) | sample.key1 = "value1" sample.key2 = "value2" sample.save |
モデル. save! | 同上 validationあり(※例外) | sample.key1 = "value1" sample.key2 = "value2" sample.save! |
モデル. update_columns (Hashオブジェクト) | 引数の Hashオブジェクトを更新 validationなし | sample. update_columns( key1: "value1", key2: "value2" ) |
モデルクラス. where(条件). update_all( Hashオブジェクト) | モデルで検索した結果を更新 validationなし | Sample.all. update_all( key1: "value1", key2: "value2", ) |
まとめ
いかかでしたか?
今回はupdate_attributesを使ったRuby on Railsのモデルの更新方法について解説しました。
update_attributesは、Hashを引数に渡してデータベースのレコードを更新できます。
モデルを更新するためにはupdate_attributes以外にもいろいろな方法があるので、本記事の一覧表をぜひ活用してみてください。
そして、update_attributesの使い方を忘れてしまったらこの記事を確認してくださいね!