Feature #14059
Updated by nobu (Nobuyoshi Nakada) about 7 years ago
Consider the following problem - I would like to be able to validate that a JSON string contains all things that can represent positive integers. In this case, it works well with refinements, because I can: ~~~ruby ~~~ class PositiveJSONValidator < ActiveModel::EachValidator using Module.new { refine String do def positive_integer? match?(/[1-9](?:[0-9])*/) end end refine Integer do def positive_integer? self > 0 end end refine Float do def positive_integer? self == self.to_i end end refine NilClass do def positive_integer? false end end refine Array do def positive_integer? false end end refine Hash do def positive_integer? false end end } def validate_each(record, attribute, value) return if valid_positive_json?(value) record.errors[attribute] << options[:message] || 'is invalid' end private def valid_positive_json?(value) JSON.parse(value).all? do |key, value| key.positive_integer? && value.positive_integer? end rescue JSON::ParserError false end end ~~~ However, this is kind of annoying because I need to specify each class manually. What I'd love to be able to do is group classes by passing all of the ones that need to be refined in the same way, as in: ~~~ruby ~~~ refine NilClass, Array, Hash do def positive_integer? false end end ~~~ Is this something that people would consider? It seems like a good use case for refinements because I just want to send a message to an object, so basically I want a default case. I could just refine `Object` Object but that feels wrong, I'd rather get an undefined method exception so that I know something unexpected occurred. If accepted I'd be happy to submit a patch.