Class: ActiveRecord::QueryMethods::StoreChain
- Inherits:
-
Object
- Object
- ActiveRecord::QueryMethods::StoreChain
- Defined in:
- lib/pgrel/active_record/store_chain.rb
Overview
Base class for different store chains (hstore, jsonb, array). Provides containment queries methods. Provides basic methods.
Direct Known Subclasses
Instance Attribute Summary collapse
-
#quoted_store_name ⇒ Object
readonly
Returns the value of attribute quoted_store_name.
-
#store_name ⇒ Object
readonly
Returns the value of attribute store_name.
Instance Method Summary collapse
-
#contained(opts) ⇒ Object
Whether the store is contained within provided store.
-
#contains(opts) ⇒ Object
Whether the store contains provided store.
-
#initialize(scope, store_name) ⇒ StoreChain
constructor
A new instance of StoreChain.
-
#not(opts = :chain) ⇒ Object
Add negation to condition.
-
#where(*opts) ⇒ Object
Query by store values.
Constructor Details
#initialize(scope, store_name) ⇒ StoreChain
Returns a new instance of StoreChain.
11 12 13 14 15 16 |
# File 'lib/pgrel/active_record/store_chain.rb', line 11 def initialize(scope, store_name) @scope = scope @store_name = store_name @inverted = false @quoted_store_name = "#{@scope.klass.quoted_table_name}.#{@scope.klass.connection.quote_column_name(store_name)}" end |
Instance Attribute Details
#quoted_store_name ⇒ Object (readonly)
Returns the value of attribute quoted_store_name.
9 10 11 |
# File 'lib/pgrel/active_record/store_chain.rb', line 9 def quoted_store_name @quoted_store_name end |
#store_name ⇒ Object (readonly)
Returns the value of attribute store_name.
9 10 11 |
# File 'lib/pgrel/active_record/store_chain.rb', line 9 def store_name @store_name end |
Instance Method Details
#contained(opts) ⇒ Object
Whether the store is contained within provided store
Example
Model.create!(name: 'first', store: {b: 1})
Model.create!(name: 'second', store: {b: 1, c: 3})
data = {b: 1, c: 2}
Model.store(:store).contains(data).all #=> [Model(name: 'first', ...)]
38 39 40 |
# File 'lib/pgrel/active_record/store_chain.rb', line 38 def contained(opts) update_scope "#{quoted_store_name} <@ #{type_cast(opts)}" end |
#contains(opts) ⇒ Object
Whether the store contains provided store
Example
Model.create!(name: 'first', store: {a: 1, b: 2})
Model.create!(name: 'second', store: {b: 1, c: 3})
data = {a: 1}
Model.store(:store).contains(data).all #=> [Model(name: 'first', ...)]
26 27 28 |
# File 'lib/pgrel/active_record/store_chain.rb', line 26 def contains(opts) update_scope contains_clause(opts) end |
#not(opts = :chain) ⇒ Object
Add negation to condition.
Example
Model.create!(name: 'first', store: {b: 2})
Model.create!(name: 'second', store: {b: 1, c: 3})
Model.store(:store).not.contains({c: 3}).all #=> [Model(name: 'first')]
Model.store(:store).not(b: 2).all #=> [Model(name: 'second')]
51 52 53 54 55 |
# File 'lib/pgrel/active_record/store_chain.rb', line 51 def not(opts = :chain) @inverted = true return where(opts) unless opts == :chain self end |
#where(*opts) ⇒ Object
Query by store values. Supports array values.
NOTE: This method uses “@>” (contains) operator with logic (AND/OR) and not uses “->” (value-by-key). The use of “contains” operator allows us to use GIN index effectively.
Example
Model.create!(name: 'first', store: {b: 1, c: 2})
Model.create!(name: 'second', store: {b: 2, c: 3})
Model.store(:store, c: 2).all #=> [Model(name: 'first', ...)]
#=> (SQL) select * from ... where store @> '"c"=>"2"'::hstore
Model.store(:store, b: [1, 2]).size #=> 2
#=> (SQL) select * from ... where (store @> '"c"=>"1"'::hstore) or
(store @> '"c"=>"2"'::hstore)
74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
# File 'lib/pgrel/active_record/store_chain.rb', line 74 def where(*opts) opts.map! { |opt| opt.is_a?(Hash) ? opt : [opt] } update_scope( opts.map do |opt| opt.map do |k, v| case v when Array "(#{build_or_contains(k, v)})" else contains_clause(k => v) end end.join(" and ") end.join(" or ") ) @scope end |