【Rails入門】update_attributesで更新する方法をわかりやすく解説

こんにちは!システムエンジニアのオオイシです。

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の使い方を忘れてしまったらこの記事を確認してくださいね!

この記事を書いた人

システムエンジニア歴15年のオオイシです!好物は Java と Ruby。プログラミング、システムアーキテクトからマネジメントに到るまでなんでも食べます。
システム開発の相談やお困りごとがあればお気軽に
makoto.oishi.0705@gmail.com まで連絡頂けると幸いです

目次