method

expand_from_hash

Importance_0
v7.1.3.4 - Show latest stable - 0 notes - Class: ActiveRecord::PredicateBuilder
expand_from_hash(attributes, &block) protected

No documentation

This method has no description. You can help the Ruby on Rails community by adding new notes.

Hide source
# File activerecord/lib/active_record/relation/predicate_builder.rb, line 76
      def expand_from_hash(attributes, &block)
        return ["1=0"] if attributes.empty?

        attributes.flat_map do |key, value|
          if key.is_a?(Array)
            queries = Array(value).map do |ids_set|
              raise ArgumentError, "Expected corresponding value for #{key} to be an Array" unless ids_set.is_a?(Array)
              expand_from_hash(key.zip(ids_set).to_h)
            end
            grouping_queries(queries)
          elsif value.is_a?(Hash) && !table.has_column?(key)
            table.associated_table(key, &block)
              .predicate_builder.expand_from_hash(value.stringify_keys)
          elsif table.associated_with?(key)
            # Find the foreign key when using queries such as:
            # Post.where(author: author)
            #
            # For polymorphic relationships, find the foreign key and type:
            # PriceEstimate.where(estimate_of: treasure)
            associated_table = table.associated_table(key)
            if associated_table.polymorphic_association?
              value = [value] unless value.is_a?(Array)
              klass = PolymorphicArrayValue
            elsif associated_table.through_association?
              next associated_table.predicate_builder.expand_from_hash(
                associated_table.primary_key => value
              )
            end

            klass ||= AssociationQueryValue
            queries = klass.new(associated_table, value).queries.map! do |query|
              # If the query produced is identical to attributes don't go any deeper.
              # Prevents stack level too deep errors when association and foreign_key are identical.
              query == attributes ? self[key, value] : expand_from_hash(query)
            end

            grouping_queries(queries)
          elsif table.aggregated_with?(key)
            mapping = table.reflect_on_aggregation(key).mapping
            values = value.nil? ? [nil] : Array.wrap(value)
            if mapping.length == 1 || values.empty?
              column_name, aggr_attr = mapping.first
              values = values.map do |object|
                object.respond_to?(aggr_attr) ? object.public_send(aggr_attr) : object
              end
              self[column_name, values]
            else
              queries = values.map do |object|
                mapping.map do |field_attr, aggregate_attr|
                  self[field_attr, object.try!(aggregate_attr)]
                end
              end

              grouping_queries(queries)
            end
          else
            self[key, value]
          end
        end
      end
Register or log in to add new notes.