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"'
}
}
Related
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
I am new to rails and currently learning about validations, so i have created a form within which i have a field named no (type integer), in the model for validation i have done something like this:
validates :no,
:presence => true,
:uniqueness => true,
:numericality => { :only_integer => true, :greater_than_or_equal_to => 1, :less_than_or_equal_to => 99999 }
now when nothing is entered than two error messages are displayed
1]Noを入力してください。 -> please input the no.
2]Noは数値で入力してください。 -> please enter the number in integer only.
sorry abt the japanese stuff as my os is in japanese ;-)
what i need is that when the 'no' field is empty it should only display the error_message for that emptiness. Currently it is displaying error_message for both presence & numericality when the field is just empty.
I'm sorry if this is a really basic question I have tried searching for answers but I can't seem to find any.
change your validation for numericality to only work when that field is present.
validates :no,
:presence => true,
:uniqueness => { :if => :no_is_present? },
:numericality => {
:only_integer => true,
:greater_than_or_equal_to => 1,
:less_than_or_equal_to => 99999,
:if => :no_is_present?
}
def no_is_present?
no.present?
end
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'
In an initializer I have a huge COUNTRY_CODES hash, with format:
{ :us => "United States, :de => "Germany" }
In my model I want to validate that the entered value is:
present
a key of my country code hash
How do I apporach this?
I can't use:
validates :country, :presence => true,
:inclusion => { :in => COUNTRY_CODES }
I've tried custom validators, but I get method errors when the value is nil, e.g. when I try to use value.to_sym, causing me to validate the validator and it becomes messy.
Trying to figure out the most DRY and efficient way of doing this.
You need to collect COUNTRY_CODES keys(symbols) as strings and validate for the inclusion. So use:
validates :country, :presence => true,:inclusion => { :in => COUNTRY_CODES.keys.map(&:to_s) }
Try COUNTRY_CODES.keys if you only want to check with the keys in the hash.
Hows this?
validates :country, :presence => true,
:inclusion => { :in => COUNTRY_CODES.keys.map{|c| c.to_s}
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.