###ユーザーオブジェクトを更新する
基本的な更新の方法は2つです。
>> user = User.new(name: "Michael Hartl", email: "michael@example.com")
=> #<User id: nil, name: "Michael Hartl", email: "michael@example.com", created_at: nil, updated_at: nil>
>> user
=> #<User id: nil, name: "Michael Hartl", email: "michael@example.com", created_at: nil, updated_at: nil>
>> user.email
=> "michael@example.com"
>> user.save
(0.1ms) SAVEPOINT active_record_1
User Create (1.8ms) INSERT INTO "users" ("name", "email", "created_at", "updated_at") VALUES (?, ?, ?, ?) [["name", "Michael Hartl"], ["email", "michael@example.com"], ["created_at", "2021-09-23 06:14:16.437338"], ["updated_at", "2021-09-23 06:14:16.437338"]]
(0.1ms) RELEASE SAVEPOINT active_record_1
=> true
保存を行わずにreloadを実行すると、データベースの情報を元にオブジェクトを再読み込みするので、次のように変更が取り消されます。
>> user.email
=> "michael@example.com"
>> user.email = "foo@bar.com"
=> "foo@bar.com"
>> user.reload.email
User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT ? [["id", 3], ["LIMIT", 1]]
=> "michael@example.com"
user.saveを実行したことでユーザーが更新できました。この時、6.1.3で触れたように、マジックカラムの更新日時も更新されていることにも注目してください。
>> user.created_at
=> Thu, 23 Sep 2021 06:14:16 UTC +00:00
>> user.updated_at
=> Thu, 23 Sep 2021 06:14:16 UTC +00:00
属性を更新するもう1つの方法は、updateを使うケースです
>> user.update(name: "The Dude", email: "dude@abides.org")
(0.1ms) SAVEPOINT active_record_1
User Update (0.2ms) UPDATE "users" SET "email" = ?, "updated_at" = ?, "name" = ? WHERE "users"."id" = ? [["email", "dude@abides.org"], ["updated_at", "2021-09-23 06:25:09.158880"], ["name", "The Dude"], ["id", 3]]
(0.1ms) RELEASE SAVEPOINT active_record_1
=> true
>> user.name
=> "The Dude"
>> user.email
=> "dude@abides.org"
>> user
=> #<User id: 3, name: "The Dude", email: "dude@abides.org", created_at: "2021-09-23 06:14:16", updated_at: "2021-09-23 06:25:09">
updateメソッドは属性のハッシュを受け取り、成功時には更新と保存を続けて同時に行います
。
(保存に成功した場合はtrueを返します)。ただし、検証に1つでも失敗すると、updateの呼び出しは失敗します。
例えば6.3で実装すると、パスワードの保存を要求するようになり、検証で失敗するようになります。
特定の属性のみを更新したい場合は、次のようにupdate_attribute
を使います。
このupdate_attributeには、検証を回避
するといった効果もあります。
>> user.update_attribute(:name, "El Duderino")
(0.1ms) SAVEPOINT active_record_1
User Update (0.1ms) UPDATE "users" SET "updated_at" = ?, "name" = ? WHERE "users"."id" = ? [["updated_at", "2021-09-23 06:32:24.202887"], ["name", "El Duderino"], ["id", 3]]
(0.0ms) RELEASE SAVEPOINT active_record_1
=> true
>> user.name
=> "El Duderino"
>> user
=> #<User id: 3, name: "El Duderino", email: "dude@abides.org", created_at: "2021-09-23 06:14:16", updated_at: "2021-09-23 06:32:24">
###演習
1.userオブジェクトへの代入を使ってname属性を使って更新し、saveで保存してみてください。
>> user.name = "foo"
=> "foo"
>> user.save
(0.1ms) SAVEPOINT active_record_1
User Update (0.1ms) UPDATE "users" SET "updated_at" = ?, "name" = ? WHERE "users"."id" = ? [["updated_at", "2021-09-23 06:37:14.863409"], ["name", "foo"], ["id", 3]]
(0.1ms) RELEASE SAVEPOINT active_record_1
=> true
>> user
=> #<User id: 3, name: "foo", email: "dude@abides.org", created_at: "2021-09-23 06:14:16", updated_at: "2021-09-23 06:37:14">
2.今度はupdateを使って、email属性を更新および保存してみてください。
>> user.update(email: "abc@def.com")
(0.1ms) SAVEPOINT active_record_1
User Update (0.1ms) UPDATE "users" SET "email" = ?, "updated_at" = ? WHERE "users"."id" = ? [["email", "abc@def.com"], ["updated_at", "2021-09-23 06:39:19.318963"], ["id", 3]]
(0.1ms) RELEASE SAVEPOINT active_record_1
=> true
>> user.save
=> true
>> user
=> #<User id: 3, name: "foo", email: "abc@def.com", created_at: "2021-09-23 06:14:16", updated_at: "2021-09-23 06:39:19">
3.同様にして、マジックカラムであるcreated_atも直接更新できることを確認してみてください。
ヒント: 更新するときは「1.year.ago」を使うと便利です。これはRails流の時間指定の1つで、現在の時刻から1年前の時間を算出してくれます。
>> user.update_attribute(:created_at, 1.year.ago)
(0.1ms) SAVEPOINT active_record_1
User Update (0.1ms) UPDATE "users" SET "created_at" = ?, "updated_at" = ? WHERE "users"."id" = ? [["created_at", "2020-09-23 06:48:13.304969"], ["updated_at", "2021-09-23 06:48:13.305409"], ["id", 3]]
(0.1ms) RELEASE SAVEPOINT active_record_1
=> true
>> user.save
=> true
>> user
=> #<User id: 3, name: "foo", email: "abc@def.com", created_at: "2020-09-23 06:48:13", updated_at: "2021-09-23 06:48:13">