Rails 使用变量的两个属性进行验证

Rails Validation with two attributes of a variable

我真的需要你的帮助,因为 2 小时以来我无法自己找到解决方案。我尝试了许多不同的方法,但我只是不明白如何通过使用另一个属性作为条件来验证变量的属性。

这是我最后一次尝试:

class User < ApplicationRecord
validates :admin, absence: true,
              if: ["student?", :email]
                def student?(user)
                  user.email.include? 'stud'
                end
end

我想验证,具有属性 "admin" 的用户不能拥有包含 'stud' 的电子邮件地址。更好的是验证,'stud' 用户不能是管理员。

当我 运行 db:seed 我得到这个错误,如果我把 'stud' 放在方括号中,这个错误仍然存​​在:

rails aborted!
ArgumentError: wrong number of arguments (given 0, expected 1)
/home/studi/Bachelorarbeitsapp/sample_app/app/models/user.rb:22:in `student?'

请看一下这个问题! 我愿意分享解决问题所必需的任何其他代码。谢谢!

这是完整的辅助代码:

class User < ApplicationRecord
    has_many :preferences, dependent: :destroy
    accepts_nested_attributes_for :preferences

    attr_accessor :remember_token, :activation_token, :reset_token
    before_save   :downcase_email
    before_create :create_activation_digest

    has_secure_password

    validates :name, presence: true, length: { maximum: 50 }

    VALID_EMAIL_REGEX = /\A[\w+\-.]+@(stud.uni-hannover.de|wiwi.uni-hannover.de)+\z/i
    validates :email, presence: true, length: { maximum: 255 }, format: { with: VALID_EMAIL_REGEX }, uniqueness: {case_sensitive: false}

    validates :password, presence: true, length: { minimum: 6 }, allow_nil: true

    validates :mat_number, presence: true, length: { minimum: 7, maximum: 8 }, numericality: { only_integer: true }

    validates :admin, absence: true,
                  if: ["student?", :email]
                    def student?(user)
                      user.email.include? 'stud'
                    end

    validates :ects, numericality: { greater_than_or_equal_to: 0, less_than_or_equal_to: 170, only_integer: true }, allow_nil: true

    validates :grade_avg, numericality: { greater_than_or_equal_to: 1, less_than_or_equal_to: 4 }, allow_nil: true

    # Returns the hash digest of the given string.
  def User.digest(string)
    cost = ActiveModel::SecurePassword.min_cost ? BCrypt::Engine::MIN_COST :
                                                  BCrypt::Engine.cost
    BCrypt::Password.create(string, cost: cost)
  end

  # Returns a random token
  def User.new_token
    SecureRandom.urlsafe_base64
  end

  # Remembers a user in the database for use in persistent sessions
  def remember
    self.remember_token = User.new_token
    update_attribute(:remember_digest, User.digest(remember_token))
  end

  # Returns true if the given token matches the digest.
  def authenticated?(attribute, token)
    digest = send("#{attribute}_digest")
    return false if digest.nil?
    BCrypt::Password.new(digest).is_password?(token)
  end

  # Forgets a user.
  def forget
    update_attribute(:remember_digest, nil)
  end

  # Activates an account.
  def activate
    update_columns(activated: true, activated_at: Time.zone.now)
  end

  # Sends activation email.
  def send_activation_email
    UserMailer.account_activation(self).deliver_now
  end

  # Sets the password reset attributes.
  def create_reset_digest
    self.reset_token = User.new_token
    update_columns(reset_digest:  User.digest(reset_token), reset_sent_at: Time.zone.now)
  end

  # Sends password reset email.
  def send_password_reset_email
    UserMailer.password_reset(self).deliver_now
  end

  # Returns true if a password reset has expired.
  def password_reset_expired?
    reset_sent_at < 2.hours.ago
  end

  private

    # Converts email to all lower-case.
    def downcase_email
      self.email = email.downcase
    end

    # Creates and assigns the activation token and digest.
    def create_activation_digest
      self.activation_token  = User.new_token
      self.activation_digest = User.digest(activation_token)
    end

end

基于 Active Record Validations Guide section 6.2 Custom Methods,您似乎应该可以执行以下操作:

class User < ApplicationRecord

  validate :admin_cant_be_student

  def admin_cant_be_student 
    if admin and email.include?('stud')
      errors.add(:admin, "can't have a student email address")
    end
  end

end

您不需要自定义验证:

可以使用validates_exclusion_of

validates_exclusion_of :email, in: %w( stud ), if: -> { |user| user.email.include? “admin” }, message: “admins can’t have stud in email”


validates_exclusion_of :email, in: %w( admin ), if: -> { |user|user.email.include? “stud” }, message: “students can’t have admin in email”