Project

General

Profile

Feature #14059

Updated by nobu (Nobuyoshi Nakada) over 3 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.

Back