ruby-on-rails – How do I check the validity of only a mutable attribute?

Question:

There is a user model:

class User < ActiveRecord::Base
...

  validates :name,  presence: true, length: { maximum: 50 }
  VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-]+(\.[a-z]+)*\.[a-z]+\z/i
  validates :email, presence: true, format: { with: VALID_EMAIL_REGEX },
                uniqueness: { case_sensitive: false }
  validates :password, length: { minimum: 8 }

  has_secure_password
  ...

You need to make a method for changing email'a.

Made a method in the controller:

class UsersController < ApplicationController
...

def update_email
  @user = User.find(params[:id])
  if @user.update_attributes(user_email_params)
    flash[:success] = "Адрес электронной почты изменен"
    redirect_to @user
  else
    render 'settings'
  end
end
...
private

  def user_email_params
    params.require(:user).permit(:email)
  end

In this case, it does not work, because when you call update_email , it displays an error because the password is invalid. If using user.update_attribute(...) or user.save! , the validity of the attribute being changed is not checked.

How to make sure that the validity of the password is not checked, but only the validity of the email checked?

Is there a rails solution or is it just a .save! writing your own validation method and using it with .save! ?

Answer:

You can use if/unless validation if/unless

class User < ActiveRecord::Base
...
  attr_accessor_with_default :ignore_password_validation, false

  validates :password, length: { minimum: 8 }, unless: :ignore_password_validation

Then the controller method will be as follows:

class UsersController < ApplicationController
...
  def update_email
    @user = User.find(params[:id])
    if @user.update_attributes(user_email_params.merge(ignore_password_validation: true))
      flash[:success] = "Адрес электронной почты изменен"
      redirect_to @user
    else
      render 'settings'
    end
  end
Scroll to Top