In Rails 3, how to validate string matches exactly only several strings - ruby-on-rails

I'm creating a model in Rails 3 as follows:
class Foo < ActiveRecord::Base
attr_accessible :bar
type_regex = /(dog)|(cat)|(bird)/
validates :bar, :presence => true,
:format => { :with => type_regex }
end
I need the type to match either dog, cat or bird exactly. In the above class, however, type_regex will match doggy, cathrine, etc.
How do I make the validation match those strings exactly?
Thank you

You'll need to add anchors to the regex. Specifically you need to add \A to the beginning and \Z to the end of the regex (\A and \Z meaning beginning- and end-of-string respectively).
Be careful with precedence though: due to the low precedence of | you'll either have to put a non-capturing group around the alternation or anchor each of the words separately. I.e. you have to do /\A(?:(dog)|(cat)|(bird))\Z/. Doing /\A(dog)|(cat)|(bird)\Z/ will not work because that way the \A will only apply to dog and the \Z only to bird.
The same is true if you use ^ and $ instead of \A and \Z. On that subject let me explain the difference between those: ^ and $ match the beginning and end of a line, not the string. So the string "dog\ngy" would still match the regex /^dog$/, but not the regex /\Adog\Z/.

The regex you need is:
type_regex = /(^dog$)|(^cat$)|(^bird$)/
The other suggestion by Augusto's will still match 'catherine', 'doggie'.

add $ at the end. For example:
type_regex = /[(dog)|(cat)|(bird)]$/
(you might need to escape the $). And to validate the start of string use ^
type_regex = /^[(dog)|(cat)|(bird)]/
so this is what you want... I think :)
type_regex = /^[(dog)|(cat)|(bird)]$/

Related

Discrepancy between Rubular regex and Rails regex

I want to validate U.S. phone numbers. On Rubular, the regex:
/^\(?([2-9][0-8][0-9])\)?[-.●]?([2-9][0-9]{2})[-.●]?([0-9]{4})$/
does not match the string:
'6463976583!'
as I expect. However, my Rails validator that uses the regex:
validates :phone, presence: true, format: {with: /^\(?([2-9][0-8][0-9])\)?[-.●]?([2-9][0-9]{2})[-.●]?([0-9]{4})$/}
seems to allow the same string.
Any thoughts as to where I'm going wrong?
pry(main)> '6463976583!'[/^\(?([2-9][0-8][0-9])\)?[-.]?([2-9][0-9]{2})[-.]?([0-9]{4})$/]?([0-9]{4})$/]
=> nil
pry(main)> '6463976583'[/^\(?([2-9][0-8][0-9])\)?[-.]?([2-9][0-9]{2})[-.]?([0-9]{4})$/]
=> "6463976583"
Perhaps try \A and \Z for your ActiveRecord validation: https://apidock.com/rails/ActiveModel/Validations/ClassMethods/validates_format_of
The documentation mentions it matches start and end of a string versus start and end of a line. I believe that Rails or Rubocop one, throws warnings if you don't use ^ and $ instead of \A or \Z
If you can't get the Rails validator to work, you can create a custom validator method and call your regex there

How can I include Polish letters in a validation regex?

I have validation for first_name:
validates :first_name, :format => {:with => /\A[a-zA-Z]+\z/}
Can somebody tell me how to add letters like:
ą,ż,ź,ć,ń,ł,ś,ę,ó, Ą,Ż,Ź,Ć,Ń,Ł,Ś,Ę,Ó
I think you need Oniguruma character classes. To verify that string consists of unicode letters, use alpha character class.
"abcÓ" =~ /\A[[:alpha:]]+\z/ # => 0
"abcÓ1" =~ /\A[[:alpha:]]+\z/ # => nil # contains digit
This, of course, will include not only said polish letters, but all unicode letters. Including japanese kana, for example (おにぐるま).

Regular expression format for modal validations of a text field?

I am having a simple title field for a question in the database.
validate :title, :presence => true, :format => { :with => regex,
:message => "Invalid Title" }
I should make sure that the title of the question doesn't contain only numbers and special characters. It can however contain them along with alphabets. But I should not allow the user to enter only numbers and special characters in the title field.
For example:
Will the temperature cross 40 degrees ?
Is a valid question.
But,
12213232323
?$2112121212
?
are invalid question titles.
What would be the format regex for this?
Try this simple one,
[a-zA-Z].*\?$
This will check the presence of have one or more alphabets in the question. Also check the question is ending with '?'.
I would go with something like this /\A.*[a-zA-Z].*\z/ - this will let you have alphabets in any position.
p.s. don't use ^ and $ for determining start and end of an input string. Here is the explanation Difference between \A \z and ^ $ in Ruby regular expressions

Validate that string belongs to specific language alphabet

How can I validate Rails model string attribute that it belongs to specific language alphabet characters?
Thanks.
There's a library called whatlanguage that recognize the languages of the string, example:
require 'whatlanguage'
"Je suis un homme".language # => :french
Works with Dutch, English, Farsi, French, German, Swedish, Portuguese, Russian and Spanish out of the box, so it recognize Cyrillic too.
You'll want to validate the value of the attribute against a regular expression.
# Only match characters a-z
validates_format_of :attr, :with => /[a-z]/
validates_format_of seems to be the right thing for you. the documentation says:
Validates whether the value of the specified attribute is of the correct form by matching it against the regular expression provided.
class Person < ActiveRecord::Base
validates_format_of :email, :with => /\A([^#\s]+)#((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i, :on => :create
end
Note: use \A and \Z to match the start and end of the string, ^ and $ match the start/end of a line.
A regular expression must be provided or else an exception will be raised.

Validate: Only letters, numbers and -

I would like to validate my users, so they can only use a-z and - in their username.
validates_format_of :username, :with => /[a-z]/
However this rule also allows spaces ._#
Username should use only letters, numbers, spaces, and .-_# please.
Any ideas?
Best regards.
Asbjørn Morell
You may need to say the whole string must match:
validates_format_of :username, :with => /^[-a-z]+$/
You may also need to replace ^ with \A and $ with \Z, if you don't want to match a newline at the start/end. (thanks to BaroqueBobcat)
Appending an i will cause it to match in a case-insensitive manner. (thanks to Omar Qureshi).
(I also originally left off the +: thanks to Chuck)
More complex solution but reusable and with more fine grained error messaging.
Custom validator:
app/validators/username_convention_validator.rb
class UsernameConventionValidator < ActiveModel::EachValidator
def validate_each(record, field, value)
unless value.blank?
record.errors[field] << "is not alphanumeric (letters, numbers, underscores or periods)" unless value =~ /^[[:alnum:]._-]+$/
record.errors[field] << "should start with a letter" unless value[0] =~ /[A-Za-z]/
record.errors[field] << "contains illegal characters" unless value.ascii_only?
end
end
end
(Notice it does allow ' . - _ ' and doesnt allow non ascii, for completeness sake)
Usage:
app/models/user.rb
validates :name,
:presence => true,
:uniqueness => true,
:username_convention => true
The [] may contain several "rules" so [a-z0-9] gives lowercase letters and numbers
the special character - must go at the start of the rule
Does
[-a-z0-9#_.]
give the effect you want?
validates_format_of :username, :with => /^[\w\-#]*$/
Note the *, which means '0 or more'
Simply change the regular expression to match all characters your specification states (\w covers all alphanumeric characters -- letters and numbers -- and an underscore).
validates_format_of :username, :with => /[\w \.\-#]+/
Validation to allow letters and whole numbers only:
/\A[a-zA-Z0-9]+\z/

Resources