method
expand_from_hash
Ruby on Rails latest stable (v7.1.3.2)
-
0 notes -
Class: ActiveRecord::PredicateBuilder
- 1.0.0
- 1.1.6
- 1.2.6
- 2.0.3
- 2.1.0
- 2.2.1
- 2.3.8
- 3.0.0
- 3.0.9
- 3.1.0
- 3.2.1
- 3.2.8
- 3.2.13
- 4.0.2
- 4.1.8
- 4.2.1
- 4.2.7
- 4.2.9
- 5.0.0.1 (0)
- 5.1.7 (0)
- 5.2.3 (0)
- 6.0.0 (0)
- 6.1.3.1 (0)
- 6.1.7.7 (0)
- 7.0.0 (0)
- 7.1.3.2 (0)
- 7.1.3.4 (0)
- What's this?
expand_from_hash(attributes, &block)
protected
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