Hi I have a model called users, and they have a cell phone attribute that must be entered as a 12 digit string leading with "+". I want to validate that the attribute they entered from a form is in fact in the correct format. Example "+11234567890" should save to the model, but "1232h" will not.
This is what I have in my model, but it does not work:
validates :cell, :format => { :with => /^[-+]?[0-9]+$/,
:message => "Only numbers allowed" }, :length => { :is => 10 }
Try this:
validates :cell, :format => { :with => /\A(\+1)?[0-9]{10}\z/, :message => "Not a valid 10-digit telephone number" }
I think the problem is that you're trying to do two different kinds of validations on a single validates line. The above combines the length constraint with the number constraint, and allows the variable +/- without messing up the length constraint.
Related
I have an input (it's text input) where users can set up the price.
The problem is, that users can sometimes set up the price like this:
9
9.99
9,99
$9.99
What's the best way to validate this input? I am running the app on Heroku (= PostgreSQL database), the data type column is decimal.
Rails 4 complains about using $ and ^, so use:
validates :price, :presence => true,
:format => { :with => /\A(\$)?(\d+)(\.|,)?\d{0,2}?\z/ }
Just trying to save people time ;-)
Try something like below. It matches all you examples.
validates :price, :presence => true,
:format => { :with => /^(\$)?(\d+)(\.|,)?\d{0,2}?$/ }
I would like to have a list of email domains that are validated against to prevent from registering on my app.
10minutemail.com, yopmail.com, mail.com, mail.ru etc...
I have a list of domains in my user model like so:
BAD_DOMAINS = [/10minutemail.com/, /yopmail.com/, /mail/
I would like to add a User validates on the email field to add an error if the user is registering with one of these domains.
BAD_DOMAINS.each { |rule| return true if !domain.match(rule).nil? }
I have that regex working, but how do I add that as a validates? I tried this:
validates :email, :format => { : exclusion => BAD_DOMAINS,
:message => "%{value} no good." }
Thanks
You need to combine all of your separate regular expressions into a singular one, but you might find it's easier to do that if you have a list of strings instead of a list of regular expressions:
EXCLUSION_DOMAINS = %w[
example.com
test.com
asdf.com
]
EXCLUSION_REGEXP = Regexp.new('(?:' + EXCLUSION_DOMAINS.collect { |d| Regexp.escape(d) }.join('|') + ')$')
You'll want to ensure that things don't match this, so it's a little different to use:
validates :email,
:format => {
:with => VALID_EMAIL_REGEXP,
:without => EXCLUSION_REGEXP,
:message => "%{value} no good."
}
You should use some kind of valid email tester as well to be sure the address is plausible. It's expressed here as VALID_EMAIL_REGEXP which is some kind of email validator regular expression. Try and use an RFC compliant one if you do that.
I'm building an app where users can create url slugs for their profile. To make sure the slugs are valid I've added a validation in the User model for slugs:
validates :slug, :uniqueness => true, :format => { :with => /[a-z]+/ }, :allow_nil => true, :allow_blank => true
However, validation seems to pass, regardless of what format the slug string is, for example:
u.slug = 'jlskdf .jc oi/slkdjfie\*asdf&(*&*ss%&'
=> "jlskdf .jc oi/slkdjfie\\*asdf&(*&*ss%&"
u.save
=> true
Apparently it doesn't matter what I change the regex to either, everything passes. I've tried this format as well:
validates_format_of :slug, :with => /[a-z]+/
which gives the same results. Anyone have any ideas of what could be happening?
Your regular expression isn't anchored, so the pattern matches as long as it contains at least one letter a-z. Anything else is valid. Add \A and \z to the beginning and end to prevent matching any substring within the larger input.
:with => /\A[a-z]+\z/
I am new at Ruby on Rails.
I was trying to validate format of one of the attribute to enter only float.
validates :price, :format => { :with => /^[0-9]{1,5}((\.[0-9]{1,5})?)$/, :message => "should be float" }
but when I enter only character in price, it accepts it and show 0.0 value for price.
can anybody tell, what is wrong in this or why this happens?
This is my solution,
validates :price,presence:true, numericality: {only_float: true}
when you fill in for example 7 it automatically transfer the value to 7.0
For rails 3:
validates :price, :format => { :with => /^\d+??(?:\.\d{0,2})?$/ },
:numericality =>{:greater_than => 0}
A float is a number and regular expressions are for strings.
It appears that when you enter a string for the float, it gets converted as 0.0 automatically by Rails.
Do you have a default (0.0) on the column? If yes, then you may try removing it and use validates_presence_of :price only.
Something to try: instead of putting the string directly into the price column, put it into a price_string attr and use a before_save callback to try to convert the string to price. Something like that:
attr_accessor :price_string
before_save :convert_price_string
protected
def convert_price_string
if price_string
begin
self.price = Kernel.Float(price_string)
rescue ArgumentError, TypeError
errors.add(ActiveRecord::Errors.default_error_messages[:not_a_number])
end
end
And in your form, change the name of the text_field to :price_string.
I have the following regex that I use in my routes.rb for /type-in-something-here
# A-Z, a-z, 0-9, _ in the middle but never starting or ending in a _
# At least 5, no more than 500 characters
In the routes this works well as:
match ':uuid' => 'room#show', :constraints => { :uuid => /[A-Za-z\d]([-\w]{,498}[A-Za-z\d])?/ }
I want to have this also as a validation so invalid records aren't created. So I added the following to room.rb:
validates_format_of :uuid, :with => /[A-Za-z\d]([-\w]{,498}[A-Za-z\d])?/i, :message => "Invalid! Alphanumerics only."
But this validates_format_of isn't working, and instead of adding an error it's allow the record to save.
Any ideas what's wrong?
Thanks
For validation purposes, remember to add the beginning and end of string markers \A and \Z:
validates_format_of :uuid, :with => /\A[A-Za-z\d]([-\w]{,498}[A-Za-z\d])?\Z/i
Otherwise your regex will happily match any string that contains at least a letter or a digit. For some reason Rails implicitly adds the boundaries in the routes. (Probably because it embeds the regex inside a larger one to match the entire URL, with explicit checks for / and the end of the URL.)
using something like this
validates :uuid, :format => {:with => /[A-Za-z\d]([-\w]{,498}[A-Za-z\d])?/i},
:message => "your message"
For more check this
validates :name, format: { with: /\A[a-zA-Z]+\z/,
message: "Only letters are allowed" }