对添加到设计用户模型的自定义字段的跳过验证

时间:2017-10-25 02:05:50

标签: ruby-on-rails activerecord devise

我试图研究这个,但奇怪的是没有其他人似乎有这个问题,或者我没有正确搜索。无论如何这里是我的user.rb.我可以创建一个用户没问题,我的自定义字段'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

2 个答案:

答案 0 :(得分:0)

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

@user.save(validate: false)

答案 1 :(得分:0)

  1. 您应该使用选项on: http://guides.rubyonrails.org/active_record_validations.html#on
  2. 例如: 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
      
    2. 修改:您可以这样做

      # 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