class ActiveRecord::QueryMethods::KeyStoreChain

Base class for key-value types of stores (hstore, jsonb)

Public Instance Methods

any(*keys) click to toggle source

Any of the keys existence

Example

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

Model.store(:store).keys('a','b').count #=> 2
# File lib/pgrel/active_record/store_chain.rb, line 190
def any(*keys)
  update_scope(
    "#{quoted_store_name} ?| ARRAY[:keys]",
    keys: keys.flatten.map(&:to_s)
  )
end
key(key) click to toggle source

Single key existence

Example

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

# Get all records which have key 'a' in store 'store'
Model.store(:store).key('a').all #=> [Model(name: 'first', ...)]
# File lib/pgrel/active_record/store_chain.rb, line 165
def key(key)
  update_scope "#{quoted_store_name} ? :key", key: key.to_s
end
keys(*keys) click to toggle source

Several keys existence

Example

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

Model.store(:store).keys('a','b').all #=> [Model(name: 'first', ...)]
# File lib/pgrel/active_record/store_chain.rb, line 176
def keys(*keys)
  update_scope(
    "#{quoted_store_name} ?& ARRAY[:keys]",
    keys: keys.flatten.map(&:to_s)
  )
end

Protected Instance Methods

to_sql_literal(prefix, node) click to toggle source
# File lib/pgrel/active_record/store_chain.rb, line 199
def to_sql_literal(prefix, node)
  Arel::Nodes::SqlLiteral.new(
    "#{prefix}'#{node.name}'"
  )
end
where_with_prefix(prefix, opts) click to toggle source
# File lib/pgrel/active_record/store_chain.rb, line 206
def where_with_prefix(prefix, opts)
  where_clause = build_where_clause(opts)
  where_clause_ast = where_clause.ast

  # Converting `HomogenousIn` node to `In` type allows us to set its `left`
  # to sql literal as with other node types (`HomogenousIn` does not support this).
  if defined?(Arel::Nodes::HomogeneousIn) && where_clause_ast.is_a?(Arel::Nodes::HomogeneousIn)
    where_clause_ast = Arel::Nodes::In.new(where_clause_ast.left, where_clause_ast.right)
  end

  predicates = if where_clause_ast.is_a?(Arel::Nodes::And)
    where_clause.ast.children.map do |rel|
      rel.left = to_sql_literal(prefix, rel.left)
      rel
    end
  else
    where_clause_ast.left = to_sql_literal(prefix, where_clause_ast.left)
    [where_clause_ast]
  end

  params = if ActiveRecord.version.release >= Gem::Version.new("5.2.0")
    [predicates]
  else
    [predicates, where_clause.binds]
  end

  where_clause = ActiveRecord::Relation::WhereClause.new(*params)
  @scope.where_clause += @inverted ? where_clause.invert : where_clause
  @scope
end