Class: ActiveRecord::PredicateBuilder
- Inherits:
-
Object
- Object
- ActiveRecord::PredicateBuilder
- Defined in:
- ext/active_record/finder_methods.rb
Overview
:nodoc:
Instance Method Summary collapse
Instance Method Details
#expand_from_hash(attributes, &block) ⇒ Object
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
# File 'ext/active_record/finder_methods.rb', line 7 def (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) (key.zip(ids_set).to_h) end grouping_queries(queries) elsif value.is_a?(Hash) && !table.has_column?(key) ka = table.associated_table(key, &block) .predicate_builder.(value.stringify_keys) if self.table.instance_variable_get(:@klass).connection.is_a?(ActiveRecord::ConnectionAdapters::SunstoneAPIAdapter) ka.each { |k| if k.left.is_a?(Arel::Attributes::Attribute) || k.left.is_a?(Arel::Attributes::Relation) k.left = Arel::Attributes::Relation.new(k.left, key) end } end ka 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.( 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] : (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 |