<commit_before>module HydraAttribute
  module ActiveRecord
    module Relation
      module QueryMethods
        extend ActiveSupport::Concern

        MULTI_VALUE_METHODS = [:hydra_joins_aliases, :hydra_select_values, :hydra_attributes]

        included do
          attr_writer *MULTI_VALUE_METHODS

          MULTI_VALUE_METHODS.each do |value|
            class_eval <<-EOS, __FILE__, __LINE__ + 1
              def #{value}; @#{value} ||= [] end
            EOS
          end

          alias_method_chain :where, :hydra_attribute
        end

        def where_with_hydra_attribute(opts, *rest)
          return self if opts.blank?

          if opts.is_a?(Hash)
            opts.inject(self) do |relation, (name, value)|
              if ::HydraAttribute::HydraAttribute.names_by_entity_type(klass.model_name).include?(name.to_s)
                relation, name = relation.clone, name.to_s
                relation.hydra_attributes    << name
                relation.hydra_joins_aliases << hydra_helper.ref_alias(name, value)
                relation.joins_values += hydra_helper.build_joins(name, value)
                relation.where_values += build_where(hydra_helper.where_options(name, value))
                relation
              else
                relation.where_without_hydra_attribute(name => value)
              end
            end
          else
            where_without_hydra_attribute(opts, *rest)
          end
        end

        def build_arel
          @group_values = hydra_helper.quote_columns(@group_values.uniq.reject(&:blank?))
          @order_values = hydra_helper.quote_columns(@order_values.uniq.reject(&:blank?))

          # detect hydra attributes from select list
          @hydra_select_values, @select_values = @select_values.partition { |value| ::HydraAttribute::HydraAttribute.names_by_entity_type(klass.model_name).include?(value.to_s) }
          @hydra_select_values.map!(&:to_s)
          @select_values.map!{ |value| hydra_helper.prepend_table_name(value) }

          # attributes "id" and "hydra_set_id" are required for models which use HydraAttribute::ActiveRecord model
          # but if calculation method is performed, obtained data from database aren't converted to models
          # so these attributes should not be forcibly added to query
          if !hydra_attribute_performs_calculation && (@hydra_select_values.any? or @select_values.any?)
            @select_values << hydra_helper.prepend_table_name(klass.primary_key)
            @select_values << hydra_helper.prepend_table_name('hydra_set_id')
          end

          # Add filter by sets which have all this attributes<commit_msg>Add some notes to arel building process<commit_after>module HydraAttribute
  module ActiveRecord
    module Relation
      module QueryMethods
        extend ActiveSupport::Concern

        MULTI_VALUE_METHODS = [:hydra_joins_aliases, :hydra_select_values, :hydra_attributes]

        included do
          attr_writer *MULTI_VALUE_METHODS

          MULTI_VALUE_METHODS.each do |value|
            class_eval <<-EOS, __FILE__, __LINE__ + 1
              def #{value}; @#{value} ||= [] end
            EOS
          end

          alias_method_chain :where, :hydra_attribute
        end

        def where_with_hydra_attribute(opts, *rest)
          return self if opts.blank?

          if opts.is_a?(Hash)
            opts.inject(self) do |relation, (name, value)|
              if ::HydraAttribute::HydraAttribute.names_by_entity_type(klass.model_name).include?(name.to_s)
                relation, name = relation.clone, name.to_s
                relation.hydra_attributes    << name
                relation.hydra_joins_aliases << hydra_helper.ref_alias(name, value)
                relation.joins_values += hydra_helper.build_joins(name, value)
                relation.where_values += build_where(hydra_helper.where_options(name, value))
                relation
              else
                relation.where_without_hydra_attribute(name => value)
              end
            end
          else
            where_without_hydra_attribute(opts, *rest)
          end
        end

        def build_arel
          # remove duplicate columns and add table prefix to all of them
          @group_values = hydra_helper.quote_columns(@group_values.uniq.reject(&:blank?))
          @order_values = hydra_helper.quote_columns(@order_values.uniq.reject(&:blank?))

          # detect hydra attributes from select list
          @hydra_select_values, @select_values = @select_values.partition { |value| ::HydraAttribute::HydraAttribute.names_by_entity_type(klass.model_name).include?(value.to_s) }
          @hydra_select_values.map!(&:to_s)
          @select_values.map!{ |value| hydra_helper.prepend_table_name(value) }

          # attributes "id" and "hydra_set_id" are required for models which use HydraAttribute::ActiveRecord model
          # but if calculation method is performed, obtained data from database aren't converted to models
          # so these attributes should not be forcibly added to query
          if !hydra_attribute_performs_calculation && (@hydra_select_values.any? or @select_values.any?)
            @select_values << hydra_helper.prepend_table_name(klass.primary_key)
            @select_values << hydra_helper.prepend_table_name('hydra_set_id')
          end

          # Add filter by hydra sets which have all these attributes
{'fraction_non_alphanumeric': 0.07985983032091479, 'fraction_numerical': 0.00036886757654002215, 'mean_word_length': 2.553735255570118, 'pattern_counts': {'":': 0, '<': 23, '<?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': '2273728', 'n_tokens_mistral': 1594, 'n_tokens_neox': 1504, 'n_words': 325}