module Mobility::Plugins::ActiveRecord::Query::QueryExtension::QueryBuilder
Constants
- IDENTITY
Public Class Methods
build(scope, where_opts, invert: false) { || ... }
click to toggle source
# File lib/mobility/plugins/active_record/query.rb, line 208 def build(scope, where_opts, invert: false, &block) return yield unless ::Hash === where_opts opts = where_opts.with_indifferent_access locale = opts.delete(:locale) || Mobility.locale _build(scope, opts, locale, invert, &block) end
Private Class Methods
_build(scope, opts, locale, invert) { || ... }
click to toggle source
Builds a translated relation for a given opts hash and optional invert boolean.
# File lib/mobility/plugins/active_record/query.rb, line 221 def _build(scope, opts, locale, invert) return yield if (mods = translation_modules(scope)).empty? keys, predicates = opts.keys.map(&:to_s), [] query_map = mods.inject(IDENTITY) do |qm, mod| i18n_keys = mod.names & keys next qm if i18n_keys.empty? mod_predicates = i18n_keys.map do |key| build_predicate(scope.backend_node(key.to_sym, locale), opts.delete(key)) end invert_predicates!(mod_predicates) if invert predicates += mod_predicates ->(r) { mod.backend_class.apply_scope(qm[r], mod_predicates, locale, invert: invert) } end return yield if query_map == IDENTITY relation = opts.empty? ? scope : yield(opts) query_map[relation.where(predicates.inject(:and))] end
build_predicate(node, values)
click to toggle source
# File lib/mobility/plugins/active_record/query.rb, line 249 def build_predicate(node, values) nils, vals = partition_values(values) return node.eq(nil) if vals.empty? predicate = vals.length == 1 ? node.eq(vals.first) : node.in(vals) predicate = predicate.or(node.eq(nil)) unless nils.empty? predicate end
invert_predicate(predicate)
click to toggle source
Adapted from AR::Relation::WhereClause#invert_predicate
# File lib/mobility/plugins/active_record/query.rb, line 268 def invert_predicate(predicate) case predicate when ::Arel::Nodes::In ::Arel::Nodes::NotIn.new(predicate.left, predicate.right) when ::Arel::Nodes::Equality ::Arel::Nodes::NotEqual.new(predicate.left, predicate.right) else ::Arel::Nodes::Not.new(predicate) end end
invert_predicates!(predicates)
click to toggle source
# File lib/mobility/plugins/active_record/query.rb, line 263 def invert_predicates!(predicates) predicates.map!(&method(:invert_predicate)) end
partition_values(values)
click to toggle source
# File lib/mobility/plugins/active_record/query.rb, line 259 def partition_values(values) Array.wrap(values).uniq.partition(&:nil?) end
translation_modules(scope)
click to toggle source
# File lib/mobility/plugins/active_record/query.rb, line 245 def translation_modules(scope) scope.model.ancestors.grep(::Mobility::Translations) end