module ActiveRecordExtended::QueryMethods::AnyOf
Public Instance Methods
any_of(*queries)
click to toggle source
# File lib/active_record_extended/query_methods/any_of.rb, line 6 def any_of(*queries) queries = hash_map_queries(queries) build_query(queries) do |arel_query, binds| if binds.any? @scope.where(unprepared_query(arel_query.to_sql), *binds) else @scope.where(arel_query) end end end
none_of(*queries)
click to toggle source
# File lib/active_record_extended/query_methods/any_of.rb, line 17 def none_of(*queries) queries = hash_map_queries(queries) build_query(queries) do |arel_query, binds| if binds.any? @scope.where.not(unprepared_query(arel_query.to_sql), *binds) else @scope.where.not(arel_query) end end end
Private Instance Methods
bind_attributes(query)
click to toggle source
Rails 5.1 fix In Rails 5.2 the arel table maintains attribute binds
# File lib/active_record_extended/query_methods/any_of.rb, line 62 def bind_attributes(query) return [] unless query.respond_to?(:bound_attributes) query.bound_attributes.map(&:value) end
build_query(queries) { |query_map, query_map| ... }
click to toggle source
# File lib/active_record_extended/query_methods/any_of.rb, line 38 def build_query(queries) query_map = construct_query_mappings(queries) query = yield(query_map[:arel_query], query_map[:binds]) query .joins(query_map[:joins].to_a) .includes(query_map[:includes].to_a) .references(query_map[:references].to_a) end
construct_query_mappings(queries)
click to toggle source
# File lib/active_record_extended/query_methods/any_of.rb, line 47 def construct_query_mappings(queries) # rubocop:disable Metrics/AbcSize { joins: Set.new, references: Set.new, includes: Set.new, arel_query: nil, binds: [] }.tap do |query_map| query_map[:arel_query] = queries.map do |raw_query| query = generate_where_clause(raw_query) query_map[:joins] << translate_reference(query.joins_values) if query.joins_values.any? query_map[:includes] << translate_reference(query.includes_values) if query.includes_values.any? query_map[:references] << translate_reference(query.references_values) if query.references_values.any? query_map[:binds] += bind_attributes(query) query.arel.constraints.reduce(:and) end.reduce(:or) end end
generate_where_clause(query)
click to toggle source
# File lib/active_record_extended/query_methods/any_of.rb, line 79 def generate_where_clause(query) case query when String, Hash @scope.unscoped.where(query) when Array @scope.unscoped.where(*query) else query end end
hash_map_queries(queries)
click to toggle source
# File lib/active_record_extended/query_methods/any_of.rb, line 30 def hash_map_queries(queries) if queries.size == 1 && queries.first.is_a?(Hash) queries.first.each_pair.map { |attr, predicate| Hash[attr, predicate] } else queries end end
translate_reference(reference)
click to toggle source
# File lib/active_record_extended/query_methods/any_of.rb, line 75 def translate_reference(reference) reference.map { |ref| ref.try(:to_sql) || ref }.compact end
unprepared_query(query)
click to toggle source
Rails 5.1 fix
# File lib/active_record_extended/query_methods/any_of.rb, line 69 def unprepared_query(query) query.gsub(/((?<!\\)'.*?(?<!\\)'|(?<!\\)".*?(?<!\\)")|(=\ \$\d+)/) do |match| Regexp.last_match(2)&.gsub(/=\ \$\d+/, "= ?") || match end end