<commit_before>require 'active_model_serializers'
require 'ostruct'
require_relative 'scope'

module Pinkman
  module Serializer

    class Base < ActiveModel::Serializer
      attr_accessor :errors
      attr_accessor :params

      def initialize *args
        super(*args)
        @errors = Base.format_errors(args.first.errors.to_h) if args.first.present? and args.first.errors.present? and args.first.errors.any?
        @params = OpenStruct.new(args[1][:params]) if args.length > 1 and args[1].is_a?(Hash) and args[1][:params]
        self
      end

      self.root = false

      def self.scope name=:public, &block
        @scopes ||= {}
        if block_given?
          @scopes[name.to_sym] = Pinkman::Serializer::Scope.new(serializer: self)
          yield(@scopes[name.to_sym]) 
        else
          if @scopes[name.to_sym]
            @scopes[name.to_sym]
          else
            raise ArgumentError.new("Scope '#{name}' not found/defined for #{self.to_s}.")
          end
        end
      end

      def self.scopes
        @scopes
      end

      def self.model
        @model || (begin eval(self.to_s.sub('Serializer','')) rescue nil end)
      end

      def self.model= value
        @model = value
      end

      def self.has_many *args
        args.each do |attribute|
          self.class_eval do |c|
            define_method attribute do
              reflection = object.class.reflections[attribute.to_s] 
              if reflection
                Pinkman::Serializer::array(object.send(attribute), scope: @scope, params: @params)
              end
            end
          end
        end
      end

      def self.has_one *args
        args.each do |attribute|
          self.class_eval do |c|
            define_method attribute do
              reflection = object.class.reflections[attribute.to_s] 
              if reflection
                reflection.klass.serializer.new(object.send(attribute), scope: @scope, params: @params)
              end
            end
          end
        end
      end

      def self.format_errors errors
        e = Hash.new
        errors.each {|k,v| e[k] = [v].flatten}
        e
      end

      def attributes *args
        hash = super(*args)
        if scope
          pinkmanscope = self.class.scope(scope)
          include_all = pinkmanscope.read.include?(:all)
          model = self.class.model
          model.column_names.each {|attribute| hash[attribute] = object.send(attribute) } if include_all && model && model.methods.include?(:column_names)
          pinkmanscope.read.each {|attribute| hash[attribute] = send(attribute) if self.methods.include?(attribute)}
          pinkmanscope.read.each {|attribute| hash[attribute] ||= object.send(attribute) if object.methods.include?(attribute)}
          pinkmanscope.read_ghost.each {|attribute| hash[attribute] ||= object.send(attribute) }
          hash[:errors] = self.class.format_errors(errors) if errors.present? and errors.any?
          hash<commit_msg>do not break when ghost attribute is not found (rescue behaviour)<commit_after>require 'active_model_serializers'
require 'ostruct'
require_relative 'scope'

module Pinkman
  module Serializer

    class Base < ActiveModel::Serializer
      attr_accessor :errors
      attr_accessor :params

      def initialize *args
        super(*args)
        @errors = Base.format_errors(args.first.errors.to_h) if args.first.present? and args.first.errors.present? and args.first.errors.any?
        @params = OpenStruct.new(args[1][:params]) if args.length > 1 and args[1].is_a?(Hash) and args[1][:params]
        self
      end

      self.root = false

      def self.scope name=:public, &block
        @scopes ||= {}
        if block_given?
          @scopes[name.to_sym] = Pinkman::Serializer::Scope.new(serializer: self)
          yield(@scopes[name.to_sym]) 
        else
          if @scopes[name.to_sym]
            @scopes[name.to_sym]
          else
            raise ArgumentError.new("Scope '#{name}' not found/defined for #{self.to_s}.")
          end
        end
      end

      def self.scopes
        @scopes
      end

      def self.model
        @model || (begin eval(self.to_s.sub('Serializer','')) rescue nil end)
      end

      def self.model= value
        @model = value
      end

      def self.has_many *args
        args.each do |attribute|
          self.class_eval do |c|
            define_method attribute do
              reflection = object.class.reflections[attribute.to_s] 
              if reflection
                Pinkman::Serializer::array(object.send(attribute), scope: @scope, params: @params)
              end
            end
          end
        end
      end

      def self.has_one *args
        args.each do |attribute|
          self.class_eval do |c|
            define_method attribute do
              reflection = object.class.reflections[attribute.to_s] 
              if reflection
                reflection.klass.serializer.new(object.send(attribute), scope: @scope, params: @params)
              end
            end
          end
        end
      end

      def self.format_errors errors
        e = Hash.new
        errors.each {|k,v| e[k] = [v].flatten}
        e
      end

      def attributes *args
        hash = super(*args)
        if scope
          pinkmanscope = self.class.scope(scope)
          include_all = pinkmanscope.read.include?(:all)
          model = self.class.model
          model.column_names.each {|attribute| hash[attribute] = object.send(attribute) } if include_all && model && model.methods.include?(:column_names)
          pinkmanscope.read.each {|attribute| hash[attribute] = send(attribute) if self.methods.include?(attribute)}
          pinkmanscope.read.each {|attribute| hash[attribute] ||= object.send(attribute) if object.methods.include?(attribute)}
          pinkmanscope.read_ghost.each {|attribute| begin hash[attribute] ||= object.send(attribute) rescue nil end }
          hash[:errors] = self.class.format_errors(errors) if errors.present? and errors.any?
          hash
{'fraction_non_alphanumeric': 0.1041014659858343, 'fraction_numerical': 0.0013177400757700543, 'mean_word_length': 2.1122501281394155, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, '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': '5897791', 'n_tokens_mistral': 1744, 'n_tokens_neox': 1732, 'n_words': 401}