Techioz Blog

Ruby on Rails - モデルに has_secure_password を使用する場合、パスワードを空白にすることはできませんエラー

概要

Ruby on Rails を使用して API のみのアプリケーションを構築しようとしています。認証には、User モデルの has_secure_password を使用しています。 したがって、私のアプリケーションには2種類のユーザーがあり、1つは管理者、もう1つはゲストです。管理者はゲストユーザーを非アクティブ化できます。問題は、ユーザーを非アクティブ化するためにputリクエストを呼び出すときです。

「パスワードを空白にすることはできません」というエラーが表示されます。私の問題はこの質問と非常に似ており、むしろこれのフォローアップです。

問題は、has_secure_password が params/body でパスワードとして提供することを期待していることだと思いますが、ゲスト ユーザーを非アクティブ化するために、管理者がそのユーザーのパスワードを知る必要はありませんよね?その場合はIDで十分です

putクエリのURLはこれ「/api/v1/users/:id/deactivate(.:format)」です。ここで、:idパラメータには、非アクティブ化したいゲストのIDを指定するだけです

ユーザーモデルはこちら

class User < ApplicationRecord
  has_secure_password

  before_create :generate_token

  has_many :registrations
  has_many :organized_events, class_name: 'Event', foreign_key: 'organizer_id'
  has_many :attended_events, through: :registrations, source: :event

  validates :username, presence: true, uniqueness: true
  validates :email, presence: true, uniqueness: true,
    format: { with: /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i }
  validates_presence_of :first_name, :password

  enum role: { admin: 0, guest: 1 }

  scope :active, -> { where active: true }

  private def generate_token
    self.authentication_token ||= SecureRandom.hex(6)
  end
end

そして、これがリクエストを非アクティブ化するリクエストを作成しようとしているコードブロックです

def deactivate(id)
    user = User.find_by(id: id)
    if user.blank?
      self.errors = "User not found"
    else
      self.errors = user.errors.full_messages unless user.update(active: false)
    end
  end

ここからどう進めばいいのか全く分からず行き詰まっています

解決策

ハッシュされたパスワードは、password_digest という名前の列に保存されます。データベースからユーザーをリロードすると、password_digest セットはまだ存在しますが、プレーン テキスト パスワードは存在しません。

したがって、この検証から :password 列を削除する必要があります。

validates_presence_of :first_name, :password

それを次のように変更します

validates_presence_of :first_name

そして実際には、has_secure_password が既にこれを自動的に追加しているため、パスワードに特別な存在検証を追加する必要はありません。