Kristis
Kristis

Reputation: 377

Skip uniqueness validation for nil class Rails 3

Currently, I can't create an empty field with nil value, because nil counts as unique. I want to do if field has value then it must be unique if nil then not and also it can't return an empty string value.

This is my validation:

validates :subdomain, :allow_nil => true, uniqueness: true

Update

With this validation I get an error message:

Subdomain can't be blank

  validates_uniqueness_of :subdomain, presence: true, allow_nil: true, if: -> (x) { x.subdomain.present? }

Without "presence: true" in console, I can create a record with subdomain nil value, but if I do this in a browser, it creates subdomain with empty string.

Upvotes: 1

Views: 1708

Answers (2)

Kristis
Kristis

Reputation: 377

My solution:

controller create method

@organisation = Organisation.new(params[:organisation].delete_if{ |key, value| !value.present? })

and in model:

validates   :subdomain, :allow_nil => true, uniqueness: true

Upvotes: 0

SRack
SRack

Reputation: 12213

As @Pavan has said in a comment, you'll need to run this validation conditionally.

Because of the :allow_nil option, nil is an accepted value; however, it will still run the uniqueness test against this value unless you add on the additional check.

I would use the following code:

validates :subdomain, allow_nil: true, uniqueness: true, if: -> (x) { x.subdomain.present? }

Presonally, I feel present? is a nice, readable way of including this.

With this in place, I'm 99% certain you'll also be able to do away with the :allow_nil option, using simply:

validates :subdomain, uniqueness: true, if: -> (x) { x.subdomain.present? }

Hope that helps - let me know how you get on or if you have any questions.


Edit based on comment, here is an example to reject empty strings:

validates :subdomain, allow_nil: true, uniqueness: true, presence: true, if: :subdomain
# or
validates :subdomain, uniqueness: true, presence: true, if: :subdomain

Again, don't think you'll need the :allow_nil in there: I've updated the conditional so the validation runs simply on record.subdomain, which will return true for an empty string, false for nil.

Upvotes: 2

Related Questions