0

I need validate that user's email contains the value of it's association:

class Company << ApplicationRecord
  validates :name, presence: true
  has_many :users
end

class User << ApplicationRecord
  belongs_to :company
  validate :email, presence: true
end

I need that before an user is saved, its email contents its company's name, for example.

if company's name is: fedex, the user's email has to be: example@fedex.com

I am using Rails 5.0

Update:

As mrlew said, I write the validator as methods, but besides this I wrote it at app/validator as follows:

#User model
class User << ApplicationRecord
  belongs_to :company
  validate :email, presence: true
  validates_with UserEmailValidator
end

#Validator
# app/validator/user_email_validator.rb

class UserEmailValidator < ActiveModel::Validator

  def validate(record)
    unless record.email =~ /\A[\w+\-.]+@#{record.company.name}\z/i
      record.errors[:email] << "invalid email"
    end
  end
end
Iván Cortés
  • 581
  • 1
  • 9
  • 22
  • try this one `validates_format_of :email, :with => =/^[\w\d]+@self.company.name+(.[\w\d]+)+$/` hope it will work – uzaif Jan 18 '17 at 01:53
  • interpolating `self.company.name` this error ir shown `method_missing': undefined method 'company' for User (call 'User.c onnection' to establish a connection):Class (NoMethodError)` – Iván Cortés Jan 18 '17 at 02:24

1 Answers1

0

You can create a custom validator method. Something like this:

class User << ApplicationRecord
    belongs_to :company
    validate :email, presence: true
    validate :valid_company_email

    private

    def valid_company_email
        unless self.email.match(/\S+@#{self.company.name}\.com/)
            errors.add(:email, :invalid) #or replace :invalid with a custom message
        end
    end

end

Some considerations:

  • All domains must be .com, like you described.
  • Before the @: accepts everything except whitespace. It's difficult to construct a email regex (checked this answer), but it's up to you.
Community
  • 1
  • 1
mrlew
  • 7,078
  • 3
  • 25
  • 28