if I do
validates :body, :presence => true, :length => {:maximum => 30000, :message => ' is a bit long...'}
validates :body, :length => {:minimum => 10, :message => ' is a bit short...'}
I still have a possibility of having a text which includes only spaces and /r or /n - non visible chars, which while the text isn't blank by definition, it is blank by looking at it
How can I validate that the text had a min and max length listed above and is also visible (not 10 spaces)
Rails adds the handy method blank? which checks for false, nil and empty strings as described here.
Rails also adds the handy validator allow_blank: false.
So in your case it should be:
validates :body, presence: true, allow_blank: false
Edit (original answer above):
As stated in the answer below, allow_blank: false is not needed as that's the default behaviour of presence: true.
presence: true already does that according to
http://guides.rubyonrails.org/active_record_validations.html#presence
This helper validates that the specified attributes are not empty. It uses the blank? method to check if the value is either nil or a blank string, that is, a string that is either empty or consists of whitespace.
What if you try adding something like this:
validates_format_of :body, :with => /\A[[:graph:]]\Z/i
Notes:
validates_format_of lets you validate with regex
[[:graph:]] lets you check a string for printable characters (see "Character Classes")
Related
I have some trouble here trying to include an include_blank option for 'option_groups_from_collection_for_select'
I would like to have include_blank option but have the currently selected value displayed instead of a blank selection on update action. I have tried this here but it still shows blank.
select_tag(:candidate_source, option_groups_from_collection_for_select(grouped_candidate_sources, :second, :first, :id, :source), { :include_blank => true, :selected => :source })
The last argument in the option_groups_from_collection_for_select is the selected option, which should map to your value.
Since your option_key_method (4th arg) is :id you're allowed to pass the form object directly as an argument. Example:
select_tag(:candidate_source, option_groups_from_collection_for_select(grouped_candidate_sources, :second, :first, :id, :source, f.object.source), { :include_blank => true }
Anyway, see here for more argument information: http://apidock.com/rails/ActionView/Helpers/FormOptionsHelper/option_groups_from_collection_for_select
I have a form which has a select box with categories. If a particular category is selected, another select box/dropdown is displayed to the user. I need this second dropdown to be a required field when this category is selected.
I cannot add validates :course, :presence => {:message => 'Course cannot be blank.'} to the model because this field is not always required, I need some other way to make it required only when certain category is selected in the first dropbox.
Thanks for your help
You could try using the if argument to validates, like this:
validates :course, :presence => {:message => "Course cannot be blink."}, :if => Proc.new { |u| u.first_dropdown_value == 'value_that_you_validate_courses_for' }
For more information, check out the Rails documentation on conditional validation.
This is my model:
class User < ActiveRecord::Base
attr_accessible :email, :name
validates :name, presence: true, length: { maximum: 50 }
VALID_EMAIL_REGEX = /\A[\w+\-.]+#[a-z\d\-.]+\.[a-z]+\z/i
validates :email, presence: true, format: { with: VALID_EMAIL_REGEX },
uniqueness: true
end
The author of Rails Tutorial Example said "Curly braces are optional when passing hashes as the final argument in a method", but here the presence validation is not final argument, but it can be used without curly braces and is valid code. The format validation of email attribute also works.
Anybody can explain me why?
:name, :presence: true, length: { maximum: 50 } is the last argument passed to validates, so you don't need curly braces for it.
A case where you would need curly braces would be if you were passing arguments after that hash:
validates { :name, presence: true, length: { maximum: 50 } }, some_other_argument
Where some_other_argument here is some hypothetical argument that comes after the hash. To process this correctly you would need the curly braces around the hash.
I have created a model with several fields that should accept the same data format (strings, but can be anything, FWIW). I'd like to apply the same validation rule to all those fields. Of course, I can just go ahead and copy/paste stuff, but that would be against DRY principle, and common sense too...
I guess this one is pretty easy, but I'm a Rails newcomer/hipster, so excuse-moi for a trivial question. =)
So if you had say three fields to validate:
:first_name
:last_name
:age
And you wanted them all to be validated? So something like this:
validates_presence_of :first_name, :last_name, :age
Edit: There are numerous different validation methods in Rails )and they're wonderfully flexible). For the format of the field you can use validates_format_of, and then use a Regular Expression to match against it. Here's an example of matching an email:
validates_format_of :email, :with => /^([^#\s]+)#((?:[-a-z0-9]+\.)+[a-z]{2,})$/i
I'd check out the Active Record Validations and Callbacks guide; it provides comprehensive insight about a lot of the features Active Record provides in terms of validation. You can also check out the documentation here.
If you are using any of the built-in validations (presence, length_of) you can apply a single validation to multiple attributes like this:
validates_presence_of :name, :email
If you have custom logic you can create a validator object to house the code and apply it individually
class EmailValidator < ActiveModel::EachValidator
def validate_each(record, attribute, value)
record.errors[attribute] << (options[:message] || "is not an email") unless
value =~ /^([^#\s]+)#((?:[-a-z0-9]+\.)+[a-z]{2,})$/i
end
end
def Person
validates :home_email, :email => true
validates :work_email, :email => true
end
see: http://thelucid.com/2010/01/08/sexy-validation-in-edge-rails-rails-3/
In Rails 4 you can apply the same validation to multiple columns by using a loop:
[:beds, :baths].each do |column|
validates column, allow_blank: true, length: { maximum: 25 }
end
Both beds and baths are validated using the same validations.
Edit:
In Rails 4.2 you can do this same thing by putting multiple symbols after the validates function call. Example:
validates :beds, :baths, allow_blank: true
Use Themis for this:
# Describe common validation in module
module CommonValidation
extend Themis::Validation
validates_presence_of :foo
validates_length_of :bar, :maximum => 255
end
class ModelA < ActiveRecord::Base
# import validations
include CommonValidation
end
class ModelB < ActiveRecord::Base
# import validations
include CommonValidation
end
Or you can use "with_options", for example:
with_options presence: true do |video|
REQUIRED_COLUMNS.map do |attr|
video.validates attr
end
end
This seems like a simple question but I can't seem to find an answer short of writing custom validators. I have this validator
validates :password, :presence => true, :confirmation => true, :length => { :minimum => 5}
there are more rules applied such as some regex for complexity, but this gives the gist.
The issue is that I only want presence applied on create, everything else needs to be on create and update. Because the user may not be changing a password when updating their information.
I tried splitting the rules
validates :password, :presence => true, :on => :create
validates :password, # The rest of the rules
This resulted in all rules being ignored for update. Is there a simple way to apply only one rule to create and the rest to everything?
You can try keeping it in one line, but applying :on => :create to just the :presence check:
validates :password, :presence => {:on => :create}, :confirmation => true, :length => { :minimum => 5}
However, I'm not sure it makes sense to always require a minimum length, but not always require presence -- if you update an existing record with a blank password, it's going to fail validations anyway since the length is 0.
My hunch is that the problem is that the validate :password call is not additive. Can you switch the presence check to:
validates_presence_of :password, :on=>:create
And then keep your other validations using the validate. Does that work?