Rails验证具有变量的两个属性

时间:2018-03-09 23:38:48

标签: ruby-on-rails validation helper

我真的需要你的帮助,因为自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

2 个答案:

答案 0 :(得分:2)

根据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

答案 1 :(得分:0)

您不需要自定义验证:

可以使用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”