Difference between the presence and allow_blank validators in Rails? - ruby-on-rails

I'm trying to figure out the difference between:
validates :foo, presence: false
validates :foo, allow_blank: true
When I use presence: false validation fails but when I use allow_blank: true it does not. According to the docs http://apidock.com/rails/ActiveRecord/Validations/ClassMethods/validates_presence_of uses the blank? method. Can someone please explain the difference?

First case:
validates :foo, presence: false
it does not validate the presence of :foo at all.
nil, '', 'anything' are all valid.
Second case: :allow_blank is an option, not a validator.
It skips validation if the attribute is blank (more here).
If you want to know how it works, you can see the code here.
Before call the selected validator, it checks the attribute is not blank, if it's then skip validation.
The only reason why it works as a validator is the way that source code is written.
At any moment Rails' team can change the code and :allow_blank stop working as a validator.

allow_blank only validates nil, presence validates nil as well as empty

Related

validate vs validate_uniquess_of?

Is there a difference between using
validates :foo, uniqueness: true
or
validates_uniqueness_of :foo?
I know this is a simple questions, but Google didn't help
When and why should one be used over the other?
The validates method is a shortcut to all the default validators that Rails provides. So, validates :foo, uniqueness: true would trigger UniquenessValidator under the hood. The source code for validates can be found in the API doc here. As shown there, it basically triggers the validators of the options passed and raises an error in case an invalid option is passed.
validates_uniqueness_of also triggers the UniquenessValidator, the same as validates. Its source code is
# File activerecord/lib/active_record/validations/uniqueness.rb, line 233
def validates_uniqueness_of(*attr_names)
validates_with UniquenessValidator, _merge_attributes(attr_names)
end
The only difference is that with validates_uniqueness_of, we can ONLY validate the uniqueness and not pass additional options, whereas validates accepts multiple options. So we could have the following validations with validates:
validates :name, presence: true, uniqueness: true, <some other options>
But the same would not be possible with validates_uniqueness_of.

Required Params Validations in Rails 5 API

Thank you for looking onto this. I have a rails 5 API application. I am using ActiveModel Validations to validate params.
I need to validate the keys of params. ie. all the keys are mandatory to keep the structure of request unique, but it can be blank(ie. the values)
I know the
validates :key presence: true
validation, but it is checking there is a value for that. As i said, it can have blank values.
I am using params.permit so that additional keys are not allowed
include ActiveModel::Validations
validates :key1, presence: true
def initialize
#key1 = "val"
#key2 = "val2"
params.permit(:key1,:key2)
end
I need to compel the user to do requests with all the parameters with blanks allowed
Thanks in advance
Hello you should add the allow_blank options to your model like this:
validates :key presence: true, :allow_blank => true
Hope it can help
From the doc you need to specify allow_blank like :
validates :key1, :presence => true, :uniqueness => { :allow_blank => true, :case_sensitive => false }
Hope this helps !
You can try like below:
validates :key, presence: true, allow_blank: true
allow_blank:
The :allow_blank option is similar to the :allow_nil option.This option will let validation pass if the attribute's value is blank?, like nil or an empty string for example.
Note: nil values will be allowed

rails validations allow_blank and presence

I am reading the book 'agile web development with rails' and I am at the part where they are going through validations, listed below:
class Product < ActiveRecord::Base
validates :description, :title, :image_url, presence: true
validates :price, numericality: {greater_than_or_equal_to: 0.01}
validates :title, uniqueness: true
validates :image_url, allow_blank: true, format: {
with: %r{\.(gif|jpg|png)\z}i,
message: 'Must include an image file extension'
}
end
Something I am not understanding is that we have image_url, allow_blank set to true, but then we have to verify that the image_url is present? This seems like a contradiction to me at first glance, but I'm sure it's from lack of understanding.
What is it that the allow_blank validation is doing? And why do we not validate the :price be present also?
I can see why you are confused about this---it is not very clear! The meaning of allow_blank: true is that if image_url is blank, then the format validator will not run. The presence validator will still run, because its declaration has no allow_blank option.
The reason the book is doing it this way is to avoid showing users 2 validation messages if they leave the field blank. You don't really want users to see "Image Url can't be blank; Image Url must include an image file extension". It's better to just show a message about it being blank. In other words, we only want to run the format validator if there is something to validate.

Rails Validation with if Condition

I just found the following line of code in a project I'm working on at my new employer:
validates :message, presence: true, if: :message
Am I missing something, or is this pointless?
It seems that it's validating the presence of the message, but only in the case that the message is set.
Validates is uses for Model level validation.
validates :message, presence: true
means you have to insert atleast one character.
If you are entering message on view then it is pointless to use if condition.
i assume this was used by someone who did not know about the allow_blank: true option. but this is a case for when you should use a comment on your code...

Validate a form field only if populated

I have a field in a form which is optional but if it is completed I want to validate that it is an integer value. In my model I have:
validates :number_of_employees, numericality: { only_integer: true }
This works but when I submit the form with the value not completed it raises an error because it is not numeric. I gather you can put and if condition in the validates statement but not sure if this is the correct way to handle this or what the syntax is to check for existance.
Any help appreciated.
Rather than using an :if option, the idiomatic way to allow empt fields to pass validation is to use the :allow_blank option. It's common to all the validators except the presence validator.
validates :number_of_employees, numericality: { only_integer: true, allow_blank: true }

Resources