Skip to content

Instantly share code, notes, and snippets.

@mmontossi
Last active August 29, 2015 14:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mmontossi/984f8ebfd50ea843b5f2 to your computer and use it in GitHub Desktop.
Save mmontossi/984f8ebfd50ea843b5f2 to your computer and use it in GitHub Desktop.
module Validators
extend ActiveSupport::Concern
class CountValidator < ActiveModel::EachValidator
def initialize(options)
if range = (options.delete(:in) || options.delete(:within))
options[:minimum] = range.min
options[:maximum] = range.max
end
super
end
def validate_each(record, attribute, value)
count = select(value).size # Delivery use size to prevent extra queries
if options.has_key?(:minimum) && count < options[:minimum]
record.errors.add attribute, :too_few, count: options[:minimum]
elsif options.has_key?(:maximum) && count > options[:maximum]
record.errors.add attribute, :too_many, count: options[:maximum]
elsif options.has_key?(:is) && count != options[:is]
record.errors.add attribute, :wrong_count, count: options[:is]
end
end
private
def select(value)
if options[:selector]
options[:selector].call(value)
end || value
end
end
module ClassMethods
def validates_count_of(*attr_names)
validates_with CountValidator, _merge_attributes(attr_names)
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment