Last Updated: February 25, 2016
·
1.209K
· alexeyfrank

Use Types in Rails for custom model validations

# In Gemfile...
gem 'virtus'
gem 'validates' # custom email validations

# In app/types/user_sign_in_type.rb
class UserSignInType
  include ActiveModel::Validations
  include ActiveModel::Conversion
  include Virtus

  attribute :email, String
  attribute :password, String

  validates :email, presence: true, email: true
  validates :password, presence: true

  validates_each :email do |record, attr, value|
    if !user.try(:authenticate, record.password)
      record.errors.add(attr, :user_or_password_invalid)
    end
  end

  def persisted?
    false
  end

  def user
    @user ||= User.find_by_email(email)
  end
end

# In your controller...

def new
  @type = UserSignInType.new
end

def create
  @type = UserSignInType.new(params[:user_sign_in_type])

  if @type.valid?
    user = @type.user
    flash_success
    sign_in(user)
    redirect_to root_path
  else
    render :new
  end
end