Ruby on Rails使用has_secure_password停用用户时出现密码不能为空错误
解决Rails API中停用用户时的"Password can't be blank"错误
问题根源在于你给User模型添加的validates_presence_of :password验证会在所有更新操作中触发,而管理员停用用户时并没有传递密码参数,因此触发了错误。以下是两种可行的解决方案:
方案一:限定密码验证仅在创建用户时生效(推荐)
修改User模型的验证规则,让密码的存在性验证只在创建用户时执行,更新操作跳过该验证:
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 :first_name, presence: true # 仅在创建用户时验证密码是否存在 validates :password, presence: true, on: :create enum role: { admin: 0, guest: 1 } scope :active, -> { where active: true } private def generate_token self.authentication_token ||= SecureRandom.hex(6) end end
修改后,调用user.update(active: false)时不会触发密码的存在性验证,停用操作可以正常执行。这种方式保留了模型验证的完整性,后续其他更新操作也不会出现类似问题。
方案二:使用update_columns跳过模型验证(适合简单场景)
如果停用用户只是单纯修改active字段,不需要触发任何模型回调或其他验证,可以直接使用update_columns方法更新数据库字段,跳过所有模型层的验证和回调:
def deactivate(id) user = User.find_by(id: id) if user.blank? self.errors = "User not found" else # 直接更新数据库字段,跳过模型验证与回调 update_success = user.update_columns(active: false) self.errors = ["Deactivation failed"] unless update_success end end
注意:update_columns不会触发任何回调(如before_save、after_save),如果后续你的User模型添加了与停用相关的回调逻辑,这种方式会导致逻辑缺失,因此仅推荐在简单场景下使用。
内容的提问来源于stack exchange,提问作者IshAsh
相关产品推荐
相关产品推荐

