<commit_before>module ActiveTools
  module ActiveModel
    module DelegateAttributes
      extend ::ActiveSupport::Concern
      
      included do
        class FakeErrors < ::ActiveModel::Errors
          private
          def normalize_message(attribute, message, options)
            message ||= :invalid
          end
        end
        
      end
      
      module ClassMethods
        def delegate_attributes(*args)
          options = args.extract_options!
          errors_option = options.delete(:errors)
          writer_option = options.delete(:writer)

          writer_regexp = /=\z/
          readers = args.select {|a| a.to_s !=~ writer_regexp}
          writers = args.select {|a| a.to_s =~ writer_regexp}
          if writer_option == true
            writers += readers.map {|a| "#{a}="}
          end

          class_eval do
            delegate *(readers + writers), options.dup
          end          

          unless errors_option == false
            class_eval <<-EOV
              validate do
                object = #{options[:to]}
                #{"object.instance_variable_set(:@errors, FakeErrors.new(object))" if errors_option.to_s == "fit"}
                if !object.valid?
                  object.errors.messages.each do |attribute, suberrors|
                    if attribute.to_s.in? %w{#{readers.join(" ")}}
                      suberrors.each do |suberror|
                        errors.add(attribute, suberror)
                      end
                    end
                  end
                end
              end
            EOV
          end
        end
      end
      
      
    end

	  ::ActiveModel::Validations.send(:include, ActiveModel::DelegateAttributes)    

  end
  
  module OnLoadActiveRecord
    #::ActiveRecord::Base.send(:include, ActiveModel::DelegateAttributes)
  end
  
end<commit_msg>prefix applies to validation errors too<commit_after>module ActiveTools
  module ActiveModel
    module DelegateAttributes
      extend ::ActiveSupport::Concern

      included do
        class FakeErrors < ::ActiveModel::Errors
          private
          def normalize_message(attribute, message, options)
            message ||= :invalid
          end
        end

      end

      module ClassMethods
        def delegate_attributes(*args)
          options = args.extract_options!
          errors_option = options.delete(:errors)
          writer_option = options.delete(:writer)
          prefix_option = options[:prefix]
          error_prefix = prefix_option ? "#{prefix_option}_" : ""

          writer_regexp = /=\z/
          readers = args.select {|a| a.to_s !=~ writer_regexp}
          writers = args.select {|a| a.to_s =~ writer_regexp}
          if writer_option == true
            writers += readers.map {|a| "#{a}="}
          end

          class_eval do
            delegate *(readers + writers), options.dup
          end

          unless errors_option == false
            class_eval <<-EOV
              validate do
                object = #{options[:to]}
                #{"object.instance_variable_set(:@errors, FakeErrors.new(object))" if errors_option.to_s == "fit"}
                if !object.valid?
                  object.errors.messages.each do |attribute, suberrors|
                    if attribute.to_s.in? %w{#{readers.join(" ")}}
                      suberrors.each do |suberror|
                        errors.add("#{error_prefix}" + attribute.to_s, suberror)
                      end
                    end
                  end
                end
              end
            EOV
          end
        end
      end


    end

	  ::ActiveModel::Validations.send(:include, ActiveModel::DelegateAttributes)

  end

  module OnLoadActiveRecord
    #::ActiveRecord::Base.send(:include, ActiveModel::DelegateAttributes)
  end

end

{'fraction_non_alphanumeric': 0.09143005991143527, 'fraction_numerical': 0.0, 'mean_word_length': 1.6016260162601625, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4224782', 'n_tokens_mistral': 1013, 'n_tokens_neox': 972, 'n_words': 224}