<commit_before>module Ancestry
  module ClassMethods
    # Fetch tree node if necessary
    def to_node object
      if object.is_a?(self.ancestry_base_class)
        object
      else
        unscoped_where { |scope| scope.find(object.try(primary_key) || object) }
      end
    end

    # Scope on relative depth options
    def scope_depth depth_options, depth
      depth_options.inject(self.ancestry_base_class) do |scope, option|
        scope_name, relative_depth = option
        if [:before_depth, :to_depth, :at_depth, :from_depth, :after_depth].include? scope_name
          scope.send scope_name, depth + relative_depth
        else
          raise Ancestry::AncestryException.new(I18n.t("ancestry.unknown_depth_option", scope_name: scope_name))
        end
      end
    end

    # Orphan strategy writer
    def orphan_strategy= orphan_strategy
      # Check value of orphan strategy, only rootify, adopt, restrict or destroy is allowed
      if [:rootify, :adopt, :restrict, :destroy].include? orphan_strategy
        class_variable_set :@@orphan_strategy, orphan_strategy
      else
        raise Ancestry::AncestryException.new(I18n.t("ancestry.invalid_orphan_strategy"))
      end
    end


    # these methods arrange an entire subtree into nested hashes for easy navigation after database retrieval
    # the arrange method also works on a scoped class
    # the arrange method takes ActiveRecord find options
    # To order your hashes pass the order to the arrange method instead of to the scope

    # Get all nodes and sort them into an empty hash
    def arrange options = {}
      if (order = options.delete(:order))
        arrange_nodes self.ancestry_base_class.order(order).where(options)
      else
        arrange_nodes self.ancestry_base_class.where(options)
      end
    end

    # Arrange array of nodes into a nested hash of the form
    # {node => children}, where children = {} if the node has no children
    # If a node's parent is not included, the node will be included as if it is a top level node
    def arrange_nodes(nodes)
      node_ids = Set.new(nodes.map(&:id))
      index = Hash.new { |h, k| h[k] = {} }

      nodes.each_with_object({}) do |node, arranged|
        children = index[node.id]
        index[node.parent_id][node] = children
        arranged[node] = children unless node_ids.include?(node.parent_id)
      end
    end

     # Arrangement to nested array for serialization
     # You can also supply your own serialization logic using blocks
     # also allows you to pass the order just as you can pass it to the arrange method
    def arrange_serializable options={}, nodes=nil, &block
      nodes = arrange(options) if nodes.nil?
      nodes.map do |parent, children|
        if block_given?
          yield parent, arrange_serializable(options, children, &block)
        else
          parent.serializable_hash.merge 'children' => arrange_serializable(options, children)
        end
      end
    end

     # Fix for issue #559: implements tree_view from the arrange method
     # returns tree_view of a subtree
    def tree_view(column, data = nil)
      data = arrange unless data
      data.each do |parent, children|
        if parent.depth == 0
          puts parent[column]
        else
          num = parent.depth - 1
          indent = "   "*num
          puts " #{"|" if parent.depth > 1}#{indent}|_ #{parent[column]}"
        end
        tree_view(column, children) if children<commit_msg>remove unneeded comments<commit_after>module Ancestry
  module ClassMethods
    # Fetch tree node if necessary
    def to_node object
      if object.is_a?(self.ancestry_base_class)
        object
      else
        unscoped_where { |scope| scope.find(object.try(primary_key) || object) }
      end
    end

    # Scope on relative depth options
    def scope_depth depth_options, depth
      depth_options.inject(self.ancestry_base_class) do |scope, option|
        scope_name, relative_depth = option
        if [:before_depth, :to_depth, :at_depth, :from_depth, :after_depth].include? scope_name
          scope.send scope_name, depth + relative_depth
        else
          raise Ancestry::AncestryException.new(I18n.t("ancestry.unknown_depth_option", scope_name: scope_name))
        end
      end
    end

    # Orphan strategy writer
    def orphan_strategy= orphan_strategy
      # Check value of orphan strategy, only rootify, adopt, restrict or destroy is allowed
      if [:rootify, :adopt, :restrict, :destroy].include? orphan_strategy
        class_variable_set :@@orphan_strategy, orphan_strategy
      else
        raise Ancestry::AncestryException.new(I18n.t("ancestry.invalid_orphan_strategy"))
      end
    end


    # these methods arrange an entire subtree into nested hashes for easy navigation after database retrieval
    # the arrange method also works on a scoped class
    # the arrange method takes ActiveRecord find options
    # To order your hashes pass the order to the arrange method instead of to the scope

    # Get all nodes and sort them into an empty hash
    def arrange options = {}
      if (order = options.delete(:order))
        arrange_nodes self.ancestry_base_class.order(order).where(options)
      else
        arrange_nodes self.ancestry_base_class.where(options)
      end
    end

    # Arrange array of nodes into a nested hash of the form
    # {node => children}, where children = {} if the node has no children
    # If a node's parent is not included, the node will be included as if it is a top level node
    def arrange_nodes(nodes)
      node_ids = Set.new(nodes.map(&:id))
      index = Hash.new { |h, k| h[k] = {} }

      nodes.each_with_object({}) do |node, arranged|
        children = index[node.id]
        index[node.parent_id][node] = children
        arranged[node] = children unless node_ids.include?(node.parent_id)
      end
    end

     # Arrangement to nested array for serialization
     # You can also supply your own serialization logic using blocks
     # also allows you to pass the order just as you can pass it to the arrange method
    def arrange_serializable options={}, nodes=nil, &block
      nodes = arrange(options) if nodes.nil?
      nodes.map do |parent, children|
        if block_given?
          yield parent, arrange_serializable(options, children, &block)
        else
          parent.serializable_hash.merge 'children' => arrange_serializable(options, children)
        end
      end
    end

    def tree_view(column, data = nil)
      data = arrange unless data
      data.each do |parent, children|
        if parent.depth == 0
          puts parent[column]
        else
          num = parent.depth - 1
          indent = "   "*num
          puts " #{"|" if parent.depth > 1}#{indent}|_ #{parent[column]}"
        end
        tree_view(column, children) if children
{'fraction_non_alphanumeric': 0.07632694838426671, 'fraction_numerical': 0.0024857435297558125, 'mean_word_length': 2.770672546857773, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 9, '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': '3076474', 'n_tokens_mistral': 1959, 'n_tokens_neox': 1907, 'n_words': 652}