【问题标题】:Skipping Validation for custom fields added to Devise user model跳过对添加到设计用户模型的自定义字段的验证
【发布时间】:2023-03-06 12:20:01
【问题描述】:

我曾尝试对此进行研究,但奇怪的是似乎没有其他人遇到此问题,或者我的搜索不正确。无论如何,这里是我的 user.rb。我可以毫无问题地创建用户,并且我的自定义字段“pin”已设置。我可以更新“pin”字段。但是,如果尝试更改名称、电子邮件或密码,它们会失败,因为根据我的模型中的验证,pin 是空白的。如果我不更新,如何跳过密码验证?此外,如果我更新我的电子邮件,它仍然会发送确认信息,但是当我单击链接时,它会再次验证 pin 并且确认失败。另外,我也不想在 after_validation 帮助器中重新生成哈希。

class User < ApplicationRecord
  has_many :profiles, dependent: :destroy
  has_many :general_settings, dependent: :destroy
  has_many :profile_settings, through: :profiles
  has_many :tags, dependent: :destroy
  has_many :videos, through: :profiles
  belongs_to :account_type
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable,
         :confirmable
  after_validation :create_parent_digest
  validates :pin, presence: true, length:{ is: 4 }, confirmation: true

  attr_accessor :pin, :pin_confirmation

  def valid_pin?(pin)
    Devise::Encryptor.compare(self.class, parent_digest, pin)
  end  

private

    def create_parent_digest
      self.parent_digest = Devise::Encryptor.digest(self.class, pin)
    end
end

【问题讨论】:

    标签: ruby-on-rails activerecord devise


    【解决方案1】:

    根据Rails Guide,您可以通过添加 `validate: false as on 选项来跳过保存验证。例如:

    @user.save(validate: false)
    

    【讨论】:

      【解决方案2】:
      1. 你应该使用选项on:http://guides.rubyonrails.org/active_record_validations.html#on

      例如: validates :pin, presence: true, length:{ is: 4 }, confirmation: true, on: :create

      或者您可以创建自定义上下文进行验证

      # in model
      validates :pin, presence: true, length:{ is: 4 }, confirmation: true, on: :validate_pin
      
      # in controller
      @user.save(context: :validate_pin)
      
      1. 我建议不要使用回调来创建某些东西,只需将create_parent_digest 设为公共方法并在控制器(或服务对象)中手动调用它

        # UsersController
        if @user.save
          @user.create_parent_digest
          ...
        end
        

      编辑:你可以这样做

      # in model
      validates :pin, presence: true, length:{ is: 4 }, confirmation: true, on: :validate_pin
      
      # in controller
      def create
        @user = User.new params
        if @user.valid?(:validate_pin)
          @user.create_parent_digest
          @user.save
        else
          # do something like render :new
        end
      end
      

      【讨论】:

      • 感谢您的回答。这将起作用,但当我更改它时它不会验证引脚。如果编辑页面上的 pin 和 pin 确认字段为空白,我需要以某种方式告诉 Devise 绕过验证。我注意到您可以创建自定义上下文,但需要将它们传递给有效的?而not_valid?明确的。
      • 至于回调如何防止在这种情况下存储裸引脚,因为设计控制器在引脚被散列之前保存记录?
      • 我想我可能必须创建一个自定义验证方法来完成 rails 为我做的所有事情,如果 pin/pin 确认为空白并且有 pin 摘要,则退出验证,然后不要' t 添加任何错误。
      • @GHall 你需要重新定义设计控制器github.com/plataformatec/devise#configuring-controllers,我编辑了答案
      猜你喜欢
      • 1970-01-01
      • 2016-02-01
      • 1970-01-01
      • 2011-07-26
      • 2011-11-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多