saygun
saygun

Reputation: 1438

rails ActiveRecord validation on specific controller and action

is it possible to run ActiveRecord validates on given controller and action.

For example I have user_controller and signup_controller

I need to run password required validation only on signup_controller#create action

Upvotes: 8

Views: 7301

Answers (3)

hungming
hungming

Reputation: 101

Just a tip for implementing @markets' answer

We can use

  with_options if: :validate_email? do |z|
    z.validates :email, presence: true
    z.validates :name, presence: true
  end

for multiple validations on our specific action.

Also, we use session to pass a variable which indicate params from this action will need some validations

Controller:

  before_action :no_validate, only: [:first_action, :second_action, ..]
  before_action :action_based_validation, only: [:first_action, :second_action, ..]


  def first_action; end
  def second_action; end

  def update
    ..
    @instance.validate = session[:validate]
    ..
    if @instance.update(instance_params)
      ..
    end
  end


  private

    def no_validate
      session[:validate] = nil
    end

    def action_based_validation
      # action_name in first_action will = "first_action"
      session[:validate] = action_name
    end

Model

  attr_accessor :validate

  with_options if: "validate == 'first_action'" do |z|
    z.validates :email, presence: true
    ..more validations..
  end

  with_options if: "validate == 'second_action'" do |z|
    z.validates :name, presence: true
    ..more validations..
  end

more details: http://guides.rubyonrails.org/active_record_validations.html#conditional-validation

Upvotes: 1

markets
markets

Reputation: 7033

You can run validations using an if conditional:

validates :email, presence: true, if: :validate_email?

Now you need to define this instance method (in your model):

def validate_email?
  validate_email == 'true' || validate_email == true
end

This validate_email attribute could be a virtual attribute in your model:

attr_accessor :validate_email

And now, you can perform email validation depending on that virtual attribute. For example, in signup_controller#create you can do something like:

def create
  ...

  @user.validate_email = true
  @user.save

  ...
end

Upvotes: 26

firien
firien

Reputation: 1568

use validates :password, :if => :password_changed? in user.rb

if form in users_controller does not submit password field then you should be ok.

Upvotes: 1

Related Questions