Regular expressions with validations in RoR 4
^
and $
are Start of Line and End of Line anchors. While \A
and \z
are Permanent Start of String and End of String anchors.
See the difference:
string = "abcde\nzzzz"
# => "abcde\nzzzz"
/^abcde$/ === string
# => true
/\Aabcde\z/ === string
# => false
So Rails is telling you, "Are you sure you want to use ^
and $
? Don't you want to use \A
and \z
instead?"
There is more on the rails security concern that generates this warning here.
REGEX validation not working on Rails 4
I guess you are missing \A
(beginning of string),\z
(end of string)
PRICE_REGEX = /\A[0-9]+\z/
VALID_REGEX = /\A[a-zA-Z0-9]*\z/
Without \A
,\z
it could match anywhere in middle like in the case of Hello! Hi
which would match..With \A
,\z
you would explicitly match from start till end of string without matching anywhere in between
Refer to anchors in docs
Rails 4 model custom validation with method - works in console but fails in spec
You use the symbol instead of the variable when checking against the regex or for nil.
unless :bar =~ /^([0-4]{1}\.{1}\d{2})$/ || :bar == nil
errors.add(:bar, "incorrect format")
end
Remove the :
from the :bar
* EDIT *
It's not the specs that are failing but the model's validations upon creation. You should use build
instead of create
Rails validates with regex is not working?
Because it matches with you regex.
You have to specify the begin and end of the string, and add *
or it will just match one char.
format: { with: /\A[a-z]*\z/i, message: "Name must only contain letters." },
Also note don't use ^
and $
, in ruby, ^
and $
matches the begin and end of a line, not the string, so it will be broken on multiline strings.
How do I write a regex in my Rails model validation?
First and Foremost new method does not trigger any kind of validation on the object.
class Person < ApplicationRecord
validates :name, presence: true
end
>> p = Person.new
# => #<Person id: nil, name: nil>
>> p.errors.messages
# => {}
new method does not trigger any validation on an object as it is not hitting the database to save the record.
>> p.save
# => false
save method will try to create the record to the database and triggers the respective validation on the object.
>> p.valid?
# => false
When you hit the .valid? the method, it validates the object against the mentioned validation.
>> p.errors.messages
# => {name:["can't be blank"]}
>> p = Person.create
# => #<Person id: nil, name: nil>
Creating and saving a new record will send an SQL INSERT operation to the database.
Internal functionality of Person.create is Person.new and Person.save
When you are creating an object, it tries to create the valid record to the database and triggers the respective validation.
>> p.errors.messages
# => {name:["can't be blank"]}
>> p.save
# => false
>> p.save!
# => ActiveRecord::RecordInvalid: Validation failed: Name can't be blank
>> Person.create!
# => ActiveRecord::RecordInvalid: Validation failed: Name can't be blank
Secondly, validates_numericality_of and validates_format_of are the different set of validation helpers which you have mixed.
validates_numericality_of :my_attr, :only_integer => true, :allow_blank => true,
:greater_than => 0
validates_format_of :my_attr, :without => /(\d:\d|^\p{L}+$)/
This validation won't accept any such object :
MyObjectTime.new({:my_attr => "ab"})
MyObjectTime.new({:my_attr => "1:1"})
For more information you can take help from these validation helpers => http://api.rubyonrails.org/classes/ActiveModel/Validations/HelperMethods.html
Is this an error in Chapter 6 of Beginning Rails 4 related to format validation with regex?
It's precisely the security error you pointed to. It's insecure to use ^
and $
in this context. This warning appeared in Rails 4. If you are using Rails 3 your validation will never complain about this. But security risks is the same in Rails 3 as well.
:multiline => true
parameter is required if you actually need to compare beginning and end of the line, as opposed to comparing beginning and end of the string. It was introduced due to frequent misuse of ^
and $
instead \A
and \z
.
Rails 5 Validation with Regular expresion format
Ravi's answer has good regex. Here it is for your code
/\A[-+]?[0-9]*\.?[0-9]+\z/
Rails prefers to use \A or \z instead of ^ or $
This is reason why
Rails regex won't work, but Javascript regex does
Your regexp
for ruby part is correct, and it matches the provided string:
re = /\A((19[7-9][0-9])|(2[0-9][0-9][0-9]))\/((0[1-9])|(1[0-2]))\/(([0-2][0-9])|(3[0-1]))\s(([0-1][0-9])|(2[0-4]))\:([0-5][0-9])\z/
'2014/12/02 11:06' =~ re # => 0
Some notes:
See the
SO
topics 1, 2, and 3 with explanation on how to match date inruby
.Use regexp online services rubular.com, or rubyxp.com to validate regexp match for
ruby
language, embedded irb app, or debug pry gem.
Related Topics
Ruby: Kind_Of? Vs. Instance_Of? Vs. Is_A
Why Does Installing Nokogiri on MAC Os Fail With Libiconv Is Missing
Continuously Read from Stdout of External Process in Ruby
Find Indices of Elements That Match a Given Condition
Rescue_From Actioncontroller::Routingerror in Rails 4
Ruby: Inherit Code That Works With Class Variables
Avoiding Applescript Through Ruby: Rb-Appscript or Rubyosa
How to Avoid Tripping Over Utf-8 Bom When Reading Files
Checking If a Variable Is Defined
Converting Camel Case to Underscore Case in Ruby
How to Implement an Abstract Class in Ruby
An How to Support Tags in a Jekyll Blog
Ruby, Difference Between Exec, System and %X() or Backticks