Module: ActiveRecordExtended::ArrayAndJsonbQueryMethods
- Defined in:
- lib/active_record_extended/array_and_jsonb_query_methods.rb
Instance Method Summary collapse
-
#any_of(*conditions) ⇒ Object
WHERE (cond_a) OR (cond_b) OR ...
-
#contains(opts) ⇒ Object
column @> value -- jsonb (Hash) or array (Array) containment.
-
#overlap(opts) ⇒ Object
column && ARRAY[...] -- true when any element overlaps.
Instance Method Details
#any_of(*conditions) ⇒ Object
WHERE (cond_a) OR (cond_b) OR ... -- each condition is a Hash of
attribute filters or an existing Relation. Mirrors the gem's
where.any_of(...) API so call sites stay readable.
Branches are built FROM @scope (not from @scope.klass) so any
joins/references already on the chain carry into each OR branch.
Otherwise Model.joins(:assoc).where.any_of(...) would build OR
branches without the join context and produce invalid SQL.
68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
# File 'lib/active_record_extended/array_and_jsonb_query_methods.rb', line 68 def any_of(*conditions) return @scope if conditions.empty? relations = conditions.map do |cond| case cond when ActiveRecord::Relation then @scope.merge(cond) when Hash then @scope.where(cond) else raise ArgumentError, "where.any_of expects Hash or Relation; got #{cond.class}" end end relations.reduce { |memo, rel| memo.or(rel) } end |
#contains(opts) ⇒ Object
column @> value -- jsonb (Hash) or array (Array) containment.
Same element-type-cast discipline as overlap for the array branch.
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
# File 'lib/active_record_extended/array_and_jsonb_query_methods.rb', line 42 def contains(opts) scope = @scope opts.each do |column, value| qualified = qualify_column(scope, column) scope = case value when Hash scope.where("#{qualified} @> ?", value.to_json) when Array cast = pg_array_cast(scope, column) scope.where("#{qualified} @> ARRAY[?]#{cast}", value) else raise ArgumentError, "where.contains expects Hash (jsonb) or Array; got #{value.class}" end end scope end |
#overlap(opts) ⇒ Object
column && ARRAY[...] -- true when any element overlaps. Empty input
short-circuits to none (overlap with empty array is always false).
PG requires matching array element types for &&. We discover the
column's element type from AR column metadata and cast the RHS literal
accordingly — otherwise varchar[] && ARRAY['x'] (which defaults to
text[]) errors with "operator does not exist: character varying[] && text[]".
27 28 29 30 31 32 33 34 35 36 37 38 |
# File 'lib/active_record_extended/array_and_jsonb_query_methods.rb', line 27 def overlap(opts) scope = @scope opts.each do |column, values| values = Array(values) return scope.none if values.empty? qualified = qualify_column(scope, column) cast = pg_array_cast(scope, column) scope = scope.where("#{qualified} && ARRAY[?]#{cast}", values) end scope end |