Rails Validation that use validates a string with a regex? - ruby-on-rails

I have a Message.uuid field which I want to add validations for which include:
Supported:
A-Z, a-z, 0-9
dashes in the middle but never starting or ending in a dash.
At least 5, no more than 500 characters
What is the best way in rails to write a model validation for these rules?
Thanks
UPDATE:
validates :uuid,
:length => { :within => 5..500 },
:format => { :with => /[A-Za-z\d][-A-Za-z\d]{3,498}[A-Za-z\d]/ }
With a valid UUID this is failing

I'd leave the length validation up to a validates_length_of validator, so that you get more specific error messages. This will do two things for you: Simplify the regex used with your validates_format_of validator, and provide a length-specific error message when the uuid is too short/long rather than showing the length error as a "format" error.
Try the following:
validates_length_of :uuid, :within => 5..500
validates_format_of :uuid, :with => /^[a-z0-9]+[-a-z0-9]*[a-z0-9]+$/i
You can combine the two validations into a single validates with Rails 3:
validates :uuid,
:length => { :within => 5..500 },
:format => { :with => /^[a-z0-9][-a-z0-9]*[a-z0-9]$/i }

Use:
validates :uuid, :format => {:with => /my regexp/}
As for the regexp, you've already asked for it in another question.

Related

Ruby on Rails check the datatype length limit

I have a Rails App and I am using an EachValidator method to check the length of the attribute and showing the error according to limit
the validation goes like this
validates :name, :presence => {
:message => 'Please enter name'
}, :string => self.columns_hash["name"].type
now in the :string custom Validation I am right now passing the datatype of the name column, but i want to pass the datatype length instead. How can i achieve this ?
Please try this,
validates :name, :presence => {
:message => 'Please enter name'
}, :length => {
:maximum => columns_hash['name'].limit
}
Let me know if it is working fine.
validates :name, :presence => {
:message => 'Please enter name'
}, :length => { maximum: 255 } # 255 for a string data type
If I understand you correctly you, there is a gem available for this:
gem 'validates_lengths_from_database'
Then in your model simply put:
validates_lengths_from_database
Which will generate validations based on the schema for maximum lengths of string and text fields.

Rails 4 model formatting and hashes (really basic)

I have this basic validation in my model:
validates :student_number, :presence => true,
:length => { :maximum => 255 },
:uniqueness => true
So what is all that? Here's my best guess, if you would kindly tell me where I'm mistaken, I'd appreciate it.
validates is a method. I send it the symbol :first_name, then :presence => true, which is...a hash with :presence for a key and true as a value?
Except it doesn't really look like a hash, at least not according to the docs.
And then :length => { :maximum => 255 } is the same sort of entity (hash?) as :presence => true but it expects another hash as an argument?
Thanks for any assistance.
Ruby allows you to drop parentheses and brackets if it can infer their locations by itself; in your case, you could rewrite the code as:
validates(:student_number, { :presence => true,
:length => { :maximum => 255 },
:uniqueness => true })
which is a method call, passing a first argument which is the attribute to validate, and a second argument which is the validation options, a hash.
Note: This explanation is a bit of a simplification, validates is actually a bit more complicated in how it handles its arguments. See here for more details on how this works exactly.
close but not close enough. All :presence => true, :length => { :maximum => 255 }, :uniqueness => true is ONE hash with three keys presence, length, uniqueness and three coresponding values. In fact it is the same as you would write
{ :presence => true, :length => { :maximum => 255 }, :uniqueness => true } but first way is shorter

Ruby on rails validation

I figured a way to do validation. I found that inside models, i need to add these lines
validates_presence_of :name
validates_uniqueness_of :name
What i'm trying to achieve is for example, i don't want the user to add :;!##$%^&*() [or special characters] in my text inputs. Need some inputs on this.
You can use format_of:
validates_format_of :name, :with => /\A[a-zA-Z]+([a-zA-Z]|\d)*\Z/
Or create your own validation:
validates :name,
:presence => true,
:format => { :with => regex } # Here you can set a 'regex'

Multiple format validations in Rails

I have a field string foo that must meet four conditions:
It must be non-blank
It must be unique for all records
It must only contain letters, digits, and hypens
It must not start with the string "bar"
The first two are handled by :presence and :uniqueness validations. The latter two are easily handled by :format validations through regexes.
Is it possible to include multiple :format validation rules, with different :message values?
I'd like to avoid combining the two conditions into a single regex. In addition to the multiple messages, I think it's easier to read and write if they're distinct.
Ideally I'd like all of these to be wrapped up in a single validates call, but that's not strictly required.
According to the source code for the validates method, there's no way to do it; you get one :format key and one set of options as the hash value.
However, there's nothing stopping me from calling validates twice:
validates :foo,
:presence => true,
:uniqueness => true,
:format => {
:with => /^[\w\-]*$/,
:message => 'may only contain letters, digits, and hyphen'
}
validates :foo, :format => {
:with => /^(?!bar)/,
:message => 'may not start with "bar"'
}
This seems to work fine.
One validate can embedded multi attributes, as the Validator#validate source code. So can more clean as below:
validates :foo,
:presence => true,
:uniqueness => true,
:format => {`enter code here`
:with => /^[\w\-]*$/,
:message => 'may only contain letters, digits, and hyphen'
},
:format => {
:with => /^(?!bar)/,
:message => 'may not start with "bar"'
}
}

Nested model validation context

I am using Ruby on Rails 3.0.9 and I am trying to validate a nested model in a specific context just for the email attribute uniqueness.
In my controller I have:
#user.valid? :uniqueness_context
In my nested model I have:
validates :email,
:format => {
:with => EMAIL_REGEX
},
:uniqueness => {
:on => :uniqueness_context # Here it doesn't work
},
:presence => true
What is wrong? How can I make the above validation code to work?
Notice: if in the model I use the following:
validates :email,
:format => {
:with => EMAIL_REGEX
},
:uniqueness => true,
:presence => true
all works as expected.
In order to solve the issue I have tried also to use the following in the model:
validates :email,
:format => {
:with => EMAIL_REGEX
},
:presence => true
validates_uniqueness_of :email, :on => :uniqueness_context
but it still doesn't work.
I ran into the same problem. Seems that Rails currently does not support custom validation contexts. :if will do the job for you.
Sorry, I spaced it for a minute because I didn't realize you could create a custom context.
Looking at the source, it doesn't appear that the UniquenessValidator supports the :on context option.
https://github.com/rails/rails/blob/master/activerecord/lib/active_record/validations/uniqueness.rb

Resources