Ruby on rails 如何在其他模型中重复使用我的验证逻辑,并减少重复代码

Ruby on rails 如何在其他模型中重复使用我的验证逻辑,并减少重复代码,ruby-on-rails,Ruby On Rails,我有2-3个“表单”模型,我正在验证密码的格式是否正确等 我如何重构我的代码,这样我就不会在代码库中重复这个逻辑3次了 class ResetPasswordForm include ActiveModel::Model attr_accessor :password, :password_confirmation validates_presence_of :password, presence: true,

我有2-3个“表单”模型,我正在验证密码的格式是否正确等

我如何重构我的代码,这样我就不会在代码库中重复这个逻辑3次了

class ResetPasswordForm
    include ActiveModel::Model

    attr_accessor :password, :password_confirmation

    validates_presence_of :password, presence: true, 
                                                length: { minimum: 8, maximum: 20},
                                                confirmation: true

    #validates_length_of :password, :minimum => 8, :maximum => 64, :allow_blank => false
    validate :password_complexity

    def password_complexity
        unless password.blank?
            errors.add(:password, "must contain a upper case character") unless password.match(/[A-Z]/)
        end
    end
end

如果您在Rails5上,您会注意到您的模型现在继承自ApplicationRecord,后者随后继承自ActiveRecord::Base。因此,如果在Rails5上,您可以将您的方法添加到ApplicationRecord,然后在您的模型中的before_操作中引用它。如果在Rails上,只需创建一个模块并将该方法粘贴在其中。然后像对待ActiveModel::Model那样包含它。但我还想验证存在,而不仅仅是密码复杂性方法。可能吗?我认为在这方面最干净的方法是创建一个结合这两种方法的模块(编写自己版本的validates\u presence\u of方法),然后使用它。您不必访问的validates_presence_没有明确包括在您的模块,这将是混乱的。我将更新我的答案。我使用的是rails 4.xIf,如果我想将文件放入/validations/password_complexity.rb,这将如何更改我的include?我认为您需要将该文件夹添加到rails加载路径。我认为Rails只在lib文件夹中加载一层,所以如果它在找不到模块时出现错误,您将希望通过config/application.rb文件添加该文件夹。类似于config.load\u路径
module PasswordComplexity

  def check_the_password
     password_present?
     password_complexity
  end

  def password_complexity
    unless self.password.blank?
      errors.add(:password, "must contain a upper case character") unless password.match(/[A-Z]/)
    end
  end

  def password_present?
     if self.password.blank? || self.password.length < 8 || self.password.length > 20 || self.password != self.password_confirmation
       errors.add(:password, "some message")
     end #Youll want to change this probably to multiple if's that have specific error messages.
  end
end
validate :check_the_password