How to do a simple regex validation in rails - ruby-on-rails

How can perform a reguler expression to validate for either - or _ in the person username. i dont want to accept any other character like .#()$etc just - or _ so the person can either have a name like mike, mikel_mark or mike-mark. very simple. Thank you
example:
validate_format_of :username, with: "...."

The Rails 3 way to do validations is the following:
validates :username, :format => {:with => /\A[0-9a-z_]+\Z/i}
The form of validate_format_of is more Rails < 3 like and followed the "type of validation" concept, whereas the validates form is attribute based (you write all validations that apply to the attribute in one statement).
Check out the docs here: http://apidock.com/rails/v3.2.13/ActiveModel/Validations/ClassMethods/validates

Related

Rails 3 Validation - Comparison with database values

I'm trying to use Rails validations for a form text box to see if the text entered matches any existing values in a specific column of a table in the database. Is this possible with Rails?
Basically, like this:
User enters 'Foobar'
Table column values: 'Foobar,test,house,random'
Validation does not pass because 'Foobar' is already in the database.
Thanks!
dwmcc
You can do this in your model with something like validates_uniqueness_of :name or new in Rails 3 you can do multiple validations inline with validates :name, :presence => true, :uniqueness => true
From the Rails API.

Specifying two conditions with :if

I have a model which validates presence of an attribute if a check box is checked in the view.
The code is something like this:
validates_presence_of :shipping_first_name, :if => :receive_by_email_is_unchecked
I am looking to have another condition of this validation.So how do I go about doing this ??
My assumption is that something like this would do:
validates_presence_of :shipping_first_name, :if => {:receive_by_email_is_unchecked,:form_first_step_validation}
I am not sure if this is the write way of doing it or not ??
Any suggestions would be appreciated.
You can pass method names in an array:
validates_presence_of :shipping_first_name, :if => [:receive_by_email_is_unchecked, :form_first_step_validation]
Alternatively you can use proc if you don't want to define separate methods just for conditioning validations:
validates_presence_of :shipping_first_name, :if => proc { !receive_by_email? && form_first_step_validation }
I don't think that will work, but have a look at the source code for validates_presence_of https://github.com/rails/rails/blob/master/activemodel/lib/active_model/validations/presence.rb
You can build your own validator to do exactly that
Ryan Bates covered this in one of his first Rails casts
http://railscasts.com/episodes/41-conditional-validations
It's still valid although syntax may be slightly different for Rails v 3 +
I assume you are working on a Rails 2.x app as the syntax you use is not Rails 3 syntax
Rails 3.x syntax would be
validates :field_1, :field_2, :presence_of => true, :if => # Use a proc, or an array of conditions here. see the valid examples and comments that you have already received for this question from #jimworm and #MichaƂ Szajbe

how to customize rails activerecord validation error message to show attribute value

When a user tries to create a record with a name that already exists, I want to show an error message like:
name "some name" has already been taken
I have been trying to do:
validates_uniqueness_of :name, :message => "#{name} has already been taken"
but this outputs the table name instead of the value of the name attribute
2 things:
The validation messages use the Rails I18n style interpolation, which is %{value}
The key is value rather than name, because in the context of internationalization, you don't really care about the rest of the model.
So your code should be:
validates_uniqueness_of :name, :message => '%{value} has already been taken'
It looks like you can pass a Proc to the message. When you do this, you get two parameters:
A symbol along the lines of :activerecord.errors.models.user.attributes.name.taken
A hash that looks something like `{:model=>"User", :attribute=>"Name", :value=>"My Name"}
So if you allow for two parameters on a proc, you can use the attributes[:value] item to get the name that was used:
validates_uniqueness_of :name,
:message => Proc.new { |error, attributes|
"#{attributes[:value]} has already been taken."
}
What version of Rails do you use?
If Rails 3. then as i understand you should use :message => '%{value} has already been taken'. I am not sure about Rails 2.3. - but in any case you can create your own custom validation that performs what you need.

preventing rails validation based on previous validation

I have a model with 2 validations on the 'name' attribute. It goes something like this:
validates :name, :uniqueness => true
validate do
errors.add(:name, "is dumb") if name_is_dumb?
end
I don't want the 2nd validation to run if the first validation fails (the name is not unique).
What's the best and cleanest way to do this?
According to the documentation:
Callbacks are generally run in the
order they are defined, with the
exception of callbacks defined as
methods on the model, which are called
last.
So the following snippet should work:
validates :name, :uniqueness => true
validate do
errors.add(:name, "is dumb") unless errors[:name].nil?
end

Rails - How to build a custom validation

I have a Rails 3 form, with data-remote => true.
The form field is handle, like a twitter handle. I want to add validation to ensure it's handle friendly, meaning, no spaces, or non-url friendly characters.
Where to start, do I build a customer validation for this?
Thanks
Looks like you want to use validates_format_of
class Product < ActiveRecord::Base
validates_format_of :handle, :with => /\A[a-zA-Z]+\z/, :message => "Only letters allowed"
end
Change the regular expression pattern to match your needs. See the Rails Guides on validation for more information.
Look into validates_each
validates_each :handle do |record,attribute,value|
# your validation code here, and you can record.errors.add().
end
In rails 3 the best practice will be using
validates :handle, :format => {:with => /\A[a-zA-Z]+\z/, :message => "Only letters allowed"}

Resources