I’m working on a Rails app with two-factor authentication. The User model in this app has an attribute, two_factor_phone_number. I have the model validating that this attribute is present before the model can be saved.
To make sure the phone number is saved in a proper format, I’ve created a custom attribute assignment method that looks like this:
def two_factor_phone_number=(num)
num.gsub!(/\D/, '') if num.is_a?(String)
self[:two_factor_phone_number] = num.to_i
end
I’m doing some acceptance testing, and I’ve discovered that if this method is in the model, the ActiveRecord validation is ignored/skipped and a new model can be created without a two_factor_phone_number set.
The model code looks like this:
class User < ActiveRecord::Base
devise :database_authenticatable, :registerable, :confirmable,
:recoverable, :rememberable, :trackable, :validatable,
:lockable
attr_accessible :email, :password, :password_confirmation, :remember_me,
:first_name, :last_name, :two_factor_phone_number
validates :first_name, presence: true
validates :last_name, presence: true
validates :two_factor_phone_number, presence: true
# Removes all non-digit characters from a phone number and saves it
#
# num - the number to be saved
#
# Returns the digit-only phone number
def two_factor_phone_number=(num)
num.gsub!(/\D/, '') if num.is_a?(String)
self[:two_factor_phone_number] = num.to_i
end
end
You could add a format validation:
and/or create another method to set this attribute and call it before validation