I can validate the phone_number for uniqueness like this in the model :
validates :phone_number, :uniqueness => true
The problem is that none of the users in the database have a phone number, and so they are all empty. While loading the page, without entring any phone number, I keep getting the following validation error :
Validation failed: Phone number has already been taken
Seems like it's even applying the validation for empty phone numbers.
How can I modify the validation to only apply to non-empty phone numbers in the params ?
Either this:
validates :phone_number, :uniqueness => true, :allow_nil => true
passes if phone_number is nil (or NULL in database), or this:
validates :phone_number, :uniqueness => true, :allow_blank => true
passes if phone_number is nil or empty string
Rails provides it out of the box. Check the docs: http://api.rubyonrails.org/classes/ActiveRecord/Validations/ClassMethods.html#method-i-validates_uniqueness_of
validates_uniqueness_of :phone_number, :allow_blank => true
Related
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
Hi I have a job model which has an string attribute called category. In the front end, I have a form with a dropbox where a user can fill out the category attribute with the selected value from the list. This is good enough front end validation for me, but now how will I do backend validation for the model?
I have dont other validations in the past for example:
validates :name, :presence => true
But is there anyway I can do something like
validates :category, :in => {"Food", "Drink", "Rental"}
You can do it like this:
validates :category, :inclusion => { :in => %w(Food Drink Rental) }
Or shorter:
validates :category, :inclusion => %w(Food Drink Rental)
Everything is in the documentation.
In my form validation of my model, I'm trying to say that if the params of a column called :virtual is false, then the :location field should validate for :presence => true.
My current code is:
validates :location, if :virtual => false, :presence => true
But that's giving me a syntax error. What's the correct way to format this?
Something like:
attr_accessor :virtual # sets up a "virtual attribute" called "virtual" to which you can read/write a value
# this step isn't necessary if you already have an attribute on the model called "virtual"
validates :location, :presence => true, :unless => :virtual?
The use of virtual? should check whether the attribute virtual is true or false. Using unless means this validation is only performed if virtual is false (or is a value that is considered false).
More detail on virtual attributes and validation: Rails: Using form fields that are unassociated with a model in validations
validates :location, presence: true, if: Proc.new { |p| p.virtual == false }
(A) Like this:
validates :network_id, :numericality => true
validates :direct_url, :presence => true
validates :domain_name, :presence => true
validates :merchant_id, :numericality => true
validates :is_paid_merchant, :presence => true
validates :is_top_merchant, :presence => true
validates :last_months_revenue, :presence => true,
:numericality => true
validates :name, :presence => true,
:length => { :maximum => 50 }
validates :primary_category_id, :numericality => true
validates :url, :presence => true
validates :url_tag, :presence => true,
:length => { :maximum => 45 }
-OR-
(B) like this:
validates :network_id,
:merchant_id,
:last_months_revenue,
:primary_category_id, :numericality => true
validates :direct_url,
:domain_name,
:is_paid_merchant,
:is_top_merchant,
:last_months_revenue,
:name,
:url,
:url_tag, :presence => true
validates :name, :length => { :maximum => 50 }
validates :url_tag, :length => { :maximum => 45 }
In the first case each field has it's own validates clause and in the second it's based on what is being validated (fields that have multiple validations appear multiple times). The first case is also in alphabetical order so is a little more helpful to jump right to a specific field.
-OR-
(C) Am I just too anal retentive about how my code reads and looks?
I think the first style is better for the following reason:
It's most likely that you have a specific field name 'in mind' when working on a validation - or editing one - or adding a new validation for that field. So a system that lists each field and then all the validations for each one works well to read.
The other style - group validations together tends to lead to seeing a field in one spot but then having to search and scroll around for other validations for that field - and there's a good chance that you will not see or know about the other validations for that field which may be 'off-screen' and thus missed.
This also may not be that big a deal when initially building the application (when the first style might actually seem easier) but going forward when you are adding or removing or changing fields and validations (i.e. 'application building in the real world!') it will be easier and less error-prone if all the validations for a given field are together.
Another example of why B) is bad...
Imagine this:
validates :network_id,
:merchant_id,
:last_months_revenue,
:primary_category_id, :numericality => true
validates :network_id,
:direct_url,
:domain_name,
:merchant_id,
:url,
:url_tag, :presence => true
validates :network_id :uniqueness => true
See how field are repeated all over the place?
Now imagine removing network_id - yuch!
Now imagine adding another _id field that needs numericality, uniqueness and presence - yuch!
Another example - one might think (ok, I've done long ago), i'll group all the 'required's together and then put a nice comment for them and then all the uniquesness of's, with a comment header label for all of them, etc. So there is a 'standard' for developers to follow. The problem with an approach like this (apart from the previous comments) is that this is a 'local' standard that other programmers (both current and future) will need to understand and then... hopefully... follow. Much as I love them myself, personal standards like this often contribute to technical debt unless clearly thought out.
Personally I'd prefer the first style. Because I'd kick you for having to read through 30 lines of code to find out what validations are set on a single field.
For me better is A. One declaration for one attribute is not redundant but clear.
I trying to spec validations of my model this is my model
class Account < CouchRest::Model::Base
property :user, String
property :password, String
property :name, String
property :email, String
property :activate, TrueClass, :default => true
validates_presence_of :user, :password, :name, :email
validates_length_of :password, :in => 6..15, :if => lambda{|account| !account.password.blank? }
validates_uniqueness_of :user, :if => (lambda{|account| !account.user.blank?})
end
and into my model_spec i'm trying to do this
account = Account.new
account.should have(1).error_on_presence_of(:email)
But instead 1 error, I'm getting 6
I think that might be caused by validates of couchrest but not sure.
Can someone clarify this for me please?
P.S.: If I validate the same model into console I get 4 errors corresponding the four empty properties
It seems you're expecting 1 error, but there are actually 6. To figure out what is in the error hash, you can set a temporary expectation:
`account.errors.should == {}
Then the example will fail and RSpec will print the value of the error hash, and you can see which errors are actually being generated.