class ActiveRecord::QueryMethods::JsonbChain

Store chain for jsonb columns.

Constants

OPERATORS

Public Instance Methods

contains_values(*values) click to toggle source

Contains values

Example

Model.create!(name: 'first', store: {a: 1, b: 2})
Model.create!(name: 'second', store: {b: 1, c: 3})

Model.store(:store).contains_values(1, 2).all #=> [Model(name: 'first', ...)]
# File lib/pgrel/active_record/store_chain/jsonb_chain.rb, line 57
def contains_values(*values)
  update_scope(value_query(:contains), cast_values(values))
end
overlap_values(*values) click to toggle source

Overlap values

Example

Model.create!(name: 'first', store: {a: 1, b: 2})
Model.create!(name: 'second', store: {b: 1, c: 3})

Model.store(:store).overlap_values(1, 2).all
#=>[Model(name: 'first', ...), Model(name: 'second')]
# File lib/pgrel/active_record/store_chain/jsonb_chain.rb, line 46
def overlap_values(*values)
  update_scope(value_query(:overlap), cast_values(values))
end
path(*args) click to toggle source

Query by value in path.

Example:

Model.create!(name: 'first', store: {b: 1, c: { d: 3 } })
Model.create!(name: 'second', store: {b: 2, c: { d: 1 }})

Model.store(:store).path(c: {d: 3}).all #=> [Model(name: 'first', ...)]
Model.store(:store).path('c', 'd', [1, 3]).size #=> 2
# File lib/pgrel/active_record/store_chain/jsonb_chain.rb, line 17
def path(*args)
  args = flatten_hash(args.first) if args.size == 1
  val = args.pop

  path = "{#{args.join(",")}}"

  case val
  when Hash
    op = "#>"
    val = ::ActiveSupport::JSON.encode(val)
  when Array
    op = "#>>"
    val = val.map(&:to_s)
  else
    op = "#>>"
    val = val.to_s
  end

  where_with_prefix "#{quoted_store_name}#{op}", path => val
end

Private Instance Methods

cast_values(values) click to toggle source
# File lib/pgrel/active_record/store_chain/jsonb_chain.rb, line 79
def cast_values(values)
  values.map do |v|
    case v
    when Hash, Array, String
      v.to_json
    else
      v.to_s
    end
  end
end
flatten_hash(hash) click to toggle source
# File lib/pgrel/active_record/store_chain/jsonb_chain.rb, line 63
def flatten_hash(hash)
  case hash
  when Hash
    hash.flat_map { |k, v| [k, *flatten_hash(v)] }
  when Array
    [hash]
  else
    hash
  end
end
value_query(operator) click to toggle source
# File lib/pgrel/active_record/store_chain/jsonb_chain.rb, line 74
def value_query(operator)
  oper = OPERATORS[operator]
  "(SELECT array_agg(value) FROM jsonb_each(#{quoted_store_name})) #{oper} ARRAY[?]::jsonb[]"
end