Devise の User モデルのパラメータを、Devise の Controller/View を使わずに更新してみることとします。
現在、User モデルの内容の変更は、Devise の View と Controller を使って更新しています。registrations_controller の edit と update がその機能を具備していますが、User モデル内の個々のパラメータを個別に更新するには、更新しないパラメータを空にしておいて更新する、という感じで、なんとなく気持ちが悪いです。そこで、パラメータ個別に Controller と View を用意して更新してみます。
まずは、Devise でのパラメータの更新について、コマンドラインで確認します。
Devise でのパラメータの変更
Deviseでのパラメータの変更は、現在のパスワードを指定しての変更と、指定しない変更が可能です。
現在のパスワードを指定しないパラメータの更新
パスワードを指定しないで変更を行う場合、update を叩けばパラメータを変更することが可能です。例えば username を変更したい場合は、次のようになります。
1 2 3 4 5 6 7 8 9 10 11 12 |
$ bundle exec rails c Loading development environment (Rails 5.2.3) irb(main):001:0> user = User.first User Load (0.1ms) SELECT "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT ? [["LIMIT", 1]] => #<User id: 1, email: "kayama.hiroshi@example.com", created_at: "2019-09-17 03:30:14", updated_at: "2019-09-20 04:19:09", username: "kayama.hiroshi"> irb(main):002:0> user.update(username: "kayama.hiroshi.update") (0.1ms) begin transaction User Update (0.3ms) UPDATE "users" SET "updated_at" = ?, "username" = ? WHERE "users"."id" = ? [["updated_at", "2019-09-20 04:21:03.596677"], ["username", "kayama.hiroshi.update"], ["id", 1]] (1.5ms) commit transaction => true irb(main):003:0> user => #<User id: 1, email: "kayama.hiroshi@example.com", created_at: "2019-09-17 03:30:14", updated_at: "2019-09-20 04:21:03", username: "kayama.hiroshi.update"> |
同様にメールアドレスも変更できます。
1 2 3 4 5 6 |
irb(main):004:0> user.update(email: "kayama.hiroshi.update@example.com") (0.1ms) begin transaction User Exists (0.2ms) SELECT 1 AS one FROM "users" WHERE "users"."email" = ? AND "users"."id" != ? LIMIT ? [["email", "kayama.hiroshi.update@example.com"], ["id", 1], ["LIMIT", 1]] User Update (0.3ms) UPDATE "users" SET "email" = ?, "updated_at" = ? WHERE "users"."id" = ? [["email", "kayama.hiroshi.update@example.com"], ["updated_at", "2019-09-20 04:22:16.366067"], ["id", 1]] (1.2ms) commit transaction => true |
パスワードも変更可能
1 2 3 4 5 |
irb(main):005:0> user.update(password: "password") (0.1ms) begin transaction User Update (0.3ms) UPDATE "users" SET "encrypted_password" = ?, "updated_at" = ? WHERE "users"."id" = ? [["encrypted_password", "$2a$11$o7VoEXManfmHebYOj9V4h.zRGcjgAx1D6lfYECrgj2dD4od29qSkm"], ["updated_at", "2019-09-20 04:23:29.129428"], ["id", 1]] (1.3ms) commit transaction => true |
ただ、パスワードの変更は password confirmation するのが一般的です。その場合も以下のように password_confirmation に値を設定してあげれば、同じパスワードを指定されていれば変更を実行、そうでなければ失敗、という動作をしてくれます。
1 2 3 4 5 6 7 8 9 |
irb(main):008:0> user.update(password: "password", password_confirmation: "passwd") (0.1ms) begin transaction (0.1ms) rollback transaction => false irb(main):009:0> user.update(password: "password", password_confirmation: "password") (0.1ms) begin transaction User Update (0.4ms) UPDATE "users" SET "encrypted_password" = ?, "updated_at" = ? WHERE "users"."id" = ? [["encrypted_password", "$2a$11$RTAr6/tCJ8UUrD1OE5uWCuywaTf8pdEsHlOFuaJfKR39G/c9kA3.."], ["updated_at", "2019-09-20 04:26:27.979694"], ["id", 1]] (1.4ms) commit transaction => true |
現在のパスワードを指定するパラメータの更新
パスワードを指定して変更を行う場合、update_with_password を叩けばパラメータを変更することが可能です。例えば username を変更したい場合は、次のようになります。
1 2 3 4 5 6 7 |
irb(main):010:0> user.update_with_password(username: "kayama.hiroshi", current_password: "password") (0.1ms) begin transaction User Update (0.4ms) UPDATE "users" SET "updated_at" = ?, "username" = ? WHERE "users"."id" = ? [["updated_at", "2019-09-20 04:32:11.371836"], ["username", "kayama.hiroshi"], ["id", 1]] (1.6ms) commit transaction => true irb(main):011:0> user.update_with_password(username: "kayama.hiroshi", current_password: "passwd") => false |
現在のパスワードが一致していない場合、エラーになります。メールアドレスやパスワード変更も同様です。