Phone Number Regex in Ruby -- Anchor error with ^$ - ruby-on-rails

I'm trying to validate user phone numbers in Ruby with the following format:
123-456-7890
(123) 456-7890
123 456 7890
123.456.7890
+91 (123) 456-7890
I used the following regex:
/^(\+\d{1,2}\s)?\(?\d{3}\)?[\s.-]?\d{3}[\s.-]?\d{4}$/
And got this error when trying to create a user in the rails console:
ArgumentError: The provided regular expression is using multiline anchors (^ or $), which may present a security risk. Did you mean to use \A and \z, or forgot to add the :multiline => true option?
I know there are gems for this but I would like to create the user model myself, making the phone number validation similar to the email:
User.rb
class User < ActiveRecord::Base
before_save { self.email = email.downcase }
validates :name, presence: true, length: { maximum: 50 }
VALID_EMAIL_REGEX = /\A[\w+\-.]+#[a-z\d\-.]+\.[a-z]+\z/i
validates :email, presence: true, length: { maximum: 255 },
format: { with: VALID_EMAIL_REGEX },
uniqueness: { case_sensitive: false }
VALID_PHONE_NUMBER_REGEX = /^(\+\d{1,2}\s)?\(?\d{3}\)?[\s.-]?\d{3}[\s.-]?\d{4}$/
validates :phone_number, presence: true, length: {maximum: 15},
format: { with: VALID_PHONE_NUMBER_REGEX }
has_secure_password
validates :password, length: { minimum: 6 }
end
I've tried switching the anchors to \A and \z because that's what it seems to want me to do, but I cannot get the regex to accept the range of phone number inputs I want. How can I fix the regex?

The issue is at this line
VALID_PHONE_NUMBER_REGEX = /^(\+\d{1,2}\s)?\(?\d{3}\)?[\s.-]?\d{3}[\s.-]?\d{4}$/
it should be changed to
VALID_PHONE_NUMBER_REGEX = /\A(\+\d{1,2}\s)?\(?\d{3}\)?[\s.-]?\d{3}[\s.-]?\d{4}\z/
Personally, I would suggest to avoid trying to use a single regex to validate all those formats. Either group similar formats, and use different regexps, or normalize the input and validate a few formats.
You may also want to have a look at Phony.

Related

Rails ActiveRecord - field vallidation

I am new to rails and in my models am doing some field validation and i need some help
has_many :stats
validates :name, presence: true, uniqueness: true, length: { minimum: 2 }
validates :age, presence: true
validates :title, presence: true, format: { with: ???????????????
message: "must begin with abc_ and have numbers after" }
I am stuck trying to validate title to be in the format abc_8943578945794
Is this where I should really create a method to validate?
Thanks, Nigel.
Apparently you're looking for a regular expression to match the title, try this:
with: /^[a-z]+_[0-9]+$/
Fernando Almeida's anwers is right, you need a regex to match the expected value, but for the format that "OP" have passed (abc_8943578945794), this seems more suitable:
/^[a-z]{3}_[0-9]{13}$/
The only thing that I'm doing more than his, is setting the number of digits (3) and characters (13) that the string should have.
I would use the following regexp:
with: /\Aabc_\d+\z/
Explanation:
\A # beginning of the string
abc_ # string prefix you are looking for
\d+ # one or more digits
\z # end of the string

Regex validation in rails

I am new with rails and I am trying to register my user's names without special characters and spaces but allowing the - symbol.
Example :
##Pierre! => invalid
Pierre-Louis => valid
Pierre Louis => invalid
In the User.rb file I have :
class User < ApplicationRecord
...
validates :first_name, presence: true, length: {maximum: 25}, format: {with: Regexp.new('[^0-9A-Za-z-]')}
...
I don't have any error message and I'm still able to register using special characters.
Also, I'd like to add an error message if the name isn't validated.
Do you have any leads ?
Any help would be much appreciated !
When you validate format with regex, you need to ensure you match the whole string that is being validated. In order to do that your regex needs to start with \A and end with \z that are anchors marking beginning and ending of the string.
In your case:
validates :first_name,
presence: true,
length: {maximum: 25},
format: {with: /\A[-0-9A-Za-z]\z'/}
message: "Custom message"
assuming you accept numbers, small and big letters and a minus sign.

ActiveRecord validation: maximum length of one symbol to be value minus length of another symbol

I have two symbols, the values of which are set by the user.
I need to validate the length of them. The maximum length of each symbol needs to be 32 minus the length of the other symbol.
I've written it like so so far but this does not work. Does anyone have any suggestions for how this could work?
validates :id, presence: true, uniqueness: { scope: :name }, length: { maximum: 32 - :name.length }
validates :name, uniqueness: { scope: :id }, length: { maximum: 32 - :id.length }
NB: I am only a graduate, so there's a big chance i've done this totally wrong because I'm still learning and don't really understand symbols yet.
Sounds like you need a custom validation here:
validates :id, presence: true, uniqueness: { scope: :name }
validates :name, uniqueness: { scope: :id }
validate :name_and_id_max_length
def name_and_id_max_length
if (id || '').length + (name || '').length > 32
errors.add(:base, "id and name combined must be 32 or fewer characters")
end
end
Btw: Usually id in Rails is an integer, but you seem to be treating it as a string. That suggests some other confusion.
Also :id.length is not valid Ruby. In these validates declarations you are calling class methods, so there is no instance with an id yet. To do arithmetic against actual values you'd need a proc. Rails doesn't support this here AFAIK, but in other contexts it's a useful pattern to embed snippets of per-instance computation that you declare at the class level:
validates :name, length: { maximum: proc { 32 - id.length } }
For instance for a real example:
scope :recent, -> { where("created_at > ?", 24.hours.ago) }

Rails 4 active record validation - conditionally validate presence of 4 attributes if at least one is present while allowing none to be present

I have a form with 10 attributes.
Among them I have 4 attributes which I need to apply what I'd call a"mutually conditional presence" Active Record validation.
I want that
(A) if one at least is present, then the other 3 must be present
(B) still allow none to be present (if the other 3 are blank, then the fourth has the right be be blank)
Here are the four attributes:
address_line_1
zipcode
state
country
It means that if the user fills ONE of them then ALL the others have to be present. But if all are blank, it's ok.
So far I have only be able to manage to enforce (A). But I fail to implement (B).
Indeed when i try putting allow_blank: true on one of the 4 attributes validates, then it breaks (A) , as after that, it does not ensure that if on of the attributes is present, the others must be as well.
How to do this?
Here is my current code
spec/models/users
validates :address_line_1,
presence: true, if: :pa_subelements_mutual_presence?
length: { maximum: 100,
minimum: 3 }
validates :zipcode,
presence: true, if: :pa_subelements_mutual_presence?,
length: { maximum: 20,
minimum: 4}
validates :state,
presence: true, if: :pa_subelements_mutual_presence?,
validates :country,
presence: true, if: :pa_subelements_mutual_presence?,
length: { maximum: 50}
private
def pa_subelements_mutual_presence? # method to help set validates on mutually dependent for presence for postal address
lambda { self.address_line_1.present? } ||
lambda { self.zipcode.present? } ||
lambda { self.state.present? } ||
lambda { self.country.present? }
end
It seems to me, it has to be all four or none of them. Not tested, but this should work.
validate :all_or_none
private
def all_or_none
errors[:base] << "all or nothing, dude" unless
(address_line_1.blank? && zipcode.blank? && state.blank? && country.blank?) ||
(!address_line_1.blank? && !zipcode.blank? && !state.blank? && !country.blank?)
end
all_or_none will either be true if all four fields are blank or none of them is.

Devise validation constantly failing on sign up

Making a simple Ruby on Rails app as practise that requires a user to sign up.
Everything works well until I implement regex validation on a 'profile_name' field
Here's my 'user' model:
validates :profile_name, presence: true,
uniqueness: true,
format: {
with: /^a-zA-Z0-9_-$/,
message: 'Must be formatted correctly.'
}
And yet the profile name 'jon' simply refuses to pass. Where could this error be coming from, other than my 'user' model?
You need to add brackets around the ranges so that the regex matches "any of the range" rather than "all of the range in order". Put a + on the end to allow it to match anything in the range more than once.
You also need to change your beginning and ending of lines to beginning and ending of strings!
validates :profile_name, presence: true,
uniqueness: true,
format: {
with: /\A[a-zA-Z0-9_-]+\z/,
message: 'Must be formatted correctly.'
}
Details:
\A # Beginning of a string (not a line!)
\z # End of a string
[...] # match anything within the brackets
+ # match the preceding element one or more times
Really useful resource for generating and checking regex: http://www.myezapp.com/apps/dev/regexp/show.ws
Try like this , It is working fine
validates :name, presence: true,
uniqueness: true,
format: {
with: /\A[a-zA-Z0-9_-$]+\z/,
message: 'Must be formatted correctly.'
}
I just tested your regular expression in Rubular with the 'jon'. There is no matching.
I am not optimized regular expression coder. But still the below regular expression works.
/^[a-zA-Z0-9_-]+$/
So try
validates :name, presence: true,
uniqueness: true,
format: {
with: /^[a-zA-Z0-9_-]+$/,
message: 'Must be formatted correctly.'
}

Resources