Hommer Smith
Hommer Smith

Reputation: 27852

Rails (validate: false) except one attribute

Is there any way to do object.save(validate: false) specifying an attribute that we actually want to validate?

So, for example, for the User model, I want to validate: false except for the name that I want it validated.

Upvotes: 0

Views: 1920

Answers (4)

Fran Martinez
Fran Martinez

Reputation: 3042

I don't understand the conditions on which you need to do so, but an obvious solution could be to overwrite the save method or create an additional one doing this single validation.

class User
  validates :name, presence: true
  validates :other_attribute, presence: true

  def my_custom_save
    save(validate: false) if has_valid_name?
  end

  private

  def has_valid_name?
    valid? || errors.messages.keys.exclude?(:name)
  end 
end

Upvotes: 0

borjagvo
borjagvo

Reputation: 2081

You can do this using Rails' Object#with_options and conditional validation:

On your model definition:


  attr_accessor :exclusive_name_validation

  with_options unless: -> {exclusive_name_validation.present?} do
   # All validations you don't want
  end


  validates_presence_of :the_name_you_always_validate

Then you can pass in the option:

object.save(exclusive_name_validation: true)

Hope it helps.

Upvotes: 0

mahfuz
mahfuz

Reputation: 3223

How I am doing it:

I only need validation for 1 attribute of User model. But I am not using User model for this validation.

I created AutoRegisterUser model only for validation.

class AutoRegisterUser < ApplicationRecord
  self.table_name = 'users'

  attr_accessor :business_booking

  validates :email,
    presence: true,
    format: { with: URI::MailTo::EMAIL_REGEXP, message: 'has invalid format' }

  validates :email, uniqueness: { message: 'has already been taken' }
end

Here I am using self.table_name = 'users' database table. so, I can check uniqueness validation from usersdatabase table.

Now, I can validate like this:

user = AutoRegisterUser.new({ email: '[email protected]'})
user.valid?
user.save # it will be saved to "users" database table

I hope this solution helps someone.

Upvotes: 1

Cjmarkham
Cjmarkham

Reputation: 9681

A convoluted way would be to do object.save without validation, then use update to update the attribute which should be validated. All other validations would be skipped and only your required attribute would be validated:

# save all other attributes other than the one that needs validation
object.assign_attributes params.except(:required_attribute)
object.save validate: false

if object.persisted?
  # update the attribute which requires validation
  object.update required_attribute: params[:required_attribute]

  if ! object.valid?
    # handle validation error
  end
end

Upvotes: 0

Related Questions