前提
PostmanでAPIをテストしています。
ユーザー名を更新するアクションをテストするにあたり、
- PATCHメソッド
- Bodyのform-dataの
KEY
に"name"、VALUE
に"Takashi"
以上の設定で実行しました。
すると、更新する必要の無いパスワードのバリデーションが実行され、それに引っかかってしまいユーザー名を更新できませんでした。
この点についてteratailで質問し、解決しました。
Ruby - 更新したいカラム以外のカラムのバリデーションが効いてしまい、カラムを更新ができない。|teratail
解決方法
パスワードのバリデーションに、allow_blank: trueを設定する
ご回答くださいましたmaisumakun様に謝意を申し上げます。
以上の経緯で疑問が新たに生まれたので、改めて質問します。
質問内容
表題の通りですが、あるカラムを更新する際は更新しないカラムの値もBodyに含める必要があるのでしょうか。
allow_blank: trueについてググると、
値が空の場合はバリデーションを実行しません。
という説明を見つけました。(Railsバリデーションまとめ - Qiita)
この説明と実際の挙動から考えるに、
- Bodyに無い値は
null
としてモデルに送られ保存しようとする - モデルからすると
null
にせよ値が送られ保存しようとしてきたので、バリデーションを実行した - なので「Bodyにパスワード設定してないし
null
になるから、バリデーションは実行しなくていいよ」という設定をするためにallow_blank: true
ということかなと思いました。
しかし上記の私の認識だと、腑に落ちない点があります。
Ruby - 更新したいカラム以外のカラムのバリデーションが効いてしまい、カラムを更新ができない。|teratail
上記質問には載せていなかったのですが、ユーザーモデルはemailカラムも設定しています。
ユーザー名を更新するテストをする際にパスワードと同じくBodyにメールアドレスを含めていませんでしたが、emailのバリデーションは実行されませんでした。
上記の私の認識が正しいならばBodyにemailを含める必要がある、またはemailのバリデーションにallow_blank: true
を設定する必要があります。
しかし、実際の挙動としてはパスワードのみにallow_blank: true
を設定することで、問題が発生しなくなりました。
ということは、私の上記の認識は誤っている、または一部しか合っていないということです。
なので、私の理解を是正していただきたく存じます。
ソースコード
models/user.rb
ruby
1class User < ApplicationRecord 2 has_secure_password 3 4 validates :name, length: { minimum: 1, maximum: 10 } 5 validates :password, format: { with: /\A[a-z\d]{8,100}+\z/i, 6 message: "英数字8文字以上" }, allow_blank: true 7 validates :email, format: { with: /\A[\w+\-.]+@[a-z\d\-.]+.[a-z]+\z/i, 8 message: "無効なメールアドレス" } 9end
db/migrate/..._create_users.rb
ruby
1class CreateUsers < ActiveRecord::Migration[6.0] 2 def change 3 create_table :users do |t| 4 t.string :name, :default => "foo" 5 t.string :password_digest, null: false 6 t.string :email, null: false 7 8 t.timestamps 9 end 10 end 11end
controllers/users_controller
ruby
1class UsersController < ApplicationController 2 def update 3 @user = User.find(params[:id]) 4 @user.update!(user_params) 5 render json: @user 6 end 7 8 private 9 def user_params 10 params.permit(:name) 11 end 12end
config/route.rb
ruby
1Rails.application.routes.draw do 2 resources :users 3end
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/05/31 12:51
2020/05/31 13:18