Skip to content

Instantly share code, notes, and snippets.

@ChaelCodes
Created May 20, 2024 19:25
Show Gist options
  • Save ChaelCodes/df345b80fbb462a9a3798afccff76728 to your computer and use it in GitHub Desktop.
Save ChaelCodes/df345b80fbb462a9a3798afccff76728 to your computer and use it in GitHub Desktop.
A Simple Example of Building a Custom Validator - for my talk "Validate Me!"
# frozen_string_literal: true
require "bundler/inline"
gemfile(true) do
source "https://rubygems.org"
gem "rails"
# If you want to test against edge Rails replace the previous line with this:
# gem "rails", github: "rails/rails", branch: "main"
end
require "active_support"
require "active_model"
require "active_support/core_ext/object/blank"
require "minitest/autorun"
class MeValidator < ActiveModel::EachValidator
def validate_each(record, attr_name, value)
record.errors.add(attr_name, 'is not me?!', **options) unless ['me', 'chael', 'Rachael'].include? value
end
end
def validates_me_of(*attr_names)
validates_with MeValidator, _merge_attributes(attr_names)
end
class ExampleModel
include ActiveModel::API
attr_accessor :the_best
validates_me_of :the_best
end
class BugTest < Minitest::Test
def test_validator_registered
# assert_includes(ExampleModel._validators, '')
end
def test_validation_passes
example = ExampleModel.new(the_best: 'me')
assert(example.valid?)
assert_empty(example.errors)
end
def test_validation_fails
example = ExampleModel.new(the_best: 'not me')
assert_empty(example.errors) # No errors until valid? is called
assert_equal(example.valid?, false)
assert_includes(example.errors.full_messages, 'The best is not me?!')
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment