Class: ActiveRecord::HierarchicalQuery::Query
- Inherits:
-
Object
- Object
- ActiveRecord::HierarchicalQuery::Query
- Defined in:
- lib/active_record/hierarchical_query/query.rb
Constant Summary collapse
- ORDERING_COLUMN_NAME =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
'__order_column'.freeze
- CHILD_SCOPE_METHODS =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
:where, :joins, :group, :having
Instance Attribute Summary collapse
- #child_scope_value ⇒ Object readonly private
- #connect_by_value ⇒ Object readonly private
- #distinct_value ⇒ Object readonly private
- #klass ⇒ Object readonly private
- #limit_value ⇒ Object readonly private
- #nocycle_value ⇒ Object readonly private
- #offset_value ⇒ Object readonly private
- #order_values ⇒ Object readonly private
- #start_with_value ⇒ Object readonly private
Instance Method Summary collapse
-
#connect_by(conditions = nil) {|parent, child| ... } ⇒ ActiveRecord::HierarchicalQuery::Query
Specify relationship between parent rows and child rows of the hierarchy.
-
#distinct ⇒ ActiveRecord::HierarchicalQuery::Query
Turn on select distinct option in the CTE.
-
#group(*values) ⇒ Object
Generate methods that apply filters to child scope, such as
where
orgroup
. -
#having(*conditions) ⇒ Object
Generate methods that apply filters to child scope, such as
where
orgroup
. -
#initialize(klass) ⇒ Query
constructor
A new instance of Query.
- #join_conditions ⇒ Arel::Nodes::Node private
-
#join_to(relation, join_options = {}) ⇒ Object
private
Builds recursive query and joins it to given
relation
. -
#joins(*tables) ⇒ Object
Generate methods that apply filters to child scope, such as
where
orgroup
. -
#limit(value) ⇒ ActiveRecord::HierarchicalQuery::Query
Specifies a limit for the number of records to retrieve.
-
#nocycle(value = true) ⇒ ActiveRecord::HierarchicalQuery::Query
Turn on/off cycles detection.
-
#offset(value) ⇒ ActiveRecord::HierarchicalQuery::Query
Specifies the number of rows to skip before returning row.
-
#order_siblings(*columns) ⇒ ActiveRecord::HierarchicalQuery::Query
(also: #order)
Specifies hierarchical order of the recursive query results.
- #ordering_column_name ⇒ Object private
- #orderings ⇒ ActiveRecord::HierarchicalQuery::Orderings private
-
#prior ⇒ Arel::Table
(also: #previous, #recursive_table)
Returns object representing parent rows table, so it could be used in complex WHEREs.
-
#select(*columns) ⇒ ActiveRecord::HierarchicalQuery::Query
Specify which columns should be selected in addition to primary key, CONNECT BY columns and ORDER SIBLINGS columns.
-
#start_with(scope = nil, *arguments, &block) ⇒ ActiveRecord::HierarchicalQuery::Query
Specify root scope of the hierarchy.
-
#table ⇒ Object
Returns object representing child rows table, so it could be used in complex WHEREs.
-
#where(*conditions) ⇒ Object
Generate methods that apply filters to child scope, such as
where
orgroup
.
Constructor Details
#initialize(klass) ⇒ Query
Returns a new instance of Query.
29 30 31 32 33 34 35 36 37 38 39 40 41 |
# File 'lib/active_record/hierarchical_query/query.rb', line 29 def initialize(klass) @klass = klass # start with :all @start_with_value = klass.__send__(HierarchicalQuery::DELEGATOR_SCOPE) @connect_by_value = nil @child_scope_value = klass.__send__(HierarchicalQuery::DELEGATOR_SCOPE) @limit_value = nil @offset_value = nil @nocycle_value = false @order_values = [] @distinct_value = false end |
Instance Attribute Details
#child_scope_value ⇒ Object (readonly)
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
16 17 18 |
# File 'lib/active_record/hierarchical_query/query.rb', line 16 def child_scope_value @child_scope_value end |
#connect_by_value ⇒ Object (readonly)
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
16 17 18 |
# File 'lib/active_record/hierarchical_query/query.rb', line 16 def connect_by_value @connect_by_value end |
#distinct_value ⇒ Object (readonly)
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
16 17 18 |
# File 'lib/active_record/hierarchical_query/query.rb', line 16 def distinct_value @distinct_value end |
#klass ⇒ Object (readonly)
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
16 17 18 |
# File 'lib/active_record/hierarchical_query/query.rb', line 16 def klass @klass end |
#limit_value ⇒ Object (readonly)
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
16 17 18 |
# File 'lib/active_record/hierarchical_query/query.rb', line 16 def limit_value @limit_value end |
#nocycle_value ⇒ Object (readonly)
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
16 17 18 |
# File 'lib/active_record/hierarchical_query/query.rb', line 16 def nocycle_value @nocycle_value end |
#offset_value ⇒ Object (readonly)
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
16 17 18 |
# File 'lib/active_record/hierarchical_query/query.rb', line 16 def offset_value @offset_value end |
#order_values ⇒ Object (readonly)
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
16 17 18 |
# File 'lib/active_record/hierarchical_query/query.rb', line 16 def order_values @order_values end |
#start_with_value ⇒ Object (readonly)
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
16 17 18 |
# File 'lib/active_record/hierarchical_query/query.rb', line 16 def start_with_value @start_with_value end |
Instance Method Details
#connect_by(conditions = nil) {|parent, child| ... } ⇒ ActiveRecord::HierarchicalQuery::Query
Specify relationship between parent rows and child rows of the hierarchy. It can be specified with Hash where keys are parent columns names and values are child columns names, or with block (see example below).
133 134 135 136 137 138 139 140 141 142 143 144 |
# File 'lib/active_record/hierarchical_query/query.rb', line 133 def connect_by(conditions = nil, &block) # convert hash to block which returns Arel node if conditions block = conditions_to_proc(conditions) end raise ArgumentError, 'CONNECT BY: Conditions hash or block expected, none given' unless block @connect_by_value = block self end |
#distinct ⇒ ActiveRecord::HierarchicalQuery::Query
Turn on select distinct option in the CTE.
277 278 279 280 |
# File 'lib/active_record/hierarchical_query/query.rb', line 277 def distinct @distinct_value = true self end |
#group(*values) ⇒ Object
Generate methods that apply filters to child scope, such as where
or group
.
181 182 183 184 185 186 187 |
# File 'lib/active_record/hierarchical_query/query.rb', line 181 CHILD_SCOPE_METHODS.each do |method| define_method(method) do |*args| @child_scope_value = @child_scope_value.public_send(method, *args) self end end |
#having(*conditions) ⇒ Object
Generate methods that apply filters to child scope, such as where
or group
.
181 182 183 184 185 186 187 |
# File 'lib/active_record/hierarchical_query/query.rb', line 181 CHILD_SCOPE_METHODS.each do |method| define_method(method) do |*args| @child_scope_value = @child_scope_value.public_send(method, *args) self end end |
#join_conditions ⇒ Arel::Nodes::Node
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
284 285 286 |
# File 'lib/active_record/hierarchical_query/query.rb', line 284 def join_conditions connect_by_value.call(recursive_table, table) end |
#join_to(relation, join_options = {}) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Builds recursive query and joins it to given relation
.
306 307 308 309 310 311 312 313 |
# File 'lib/active_record/hierarchical_query/query.rb', line 306 def join_to(relation, = {}) raise 'Recursive query requires CONNECT BY clause, please use #connect_by method' unless connect_by_value table_alias = .fetch(:as, "#{normalized_table_name}__recursive") JoinBuilder.new(self, relation, table_alias, ).build end |
#joins(*tables) ⇒ Object
Generate methods that apply filters to child scope, such as where
or group
.
181 182 183 184 185 186 187 |
# File 'lib/active_record/hierarchical_query/query.rb', line 181 CHILD_SCOPE_METHODS.each do |method| define_method(method) do |*args| @child_scope_value = @child_scope_value.public_send(method, *args) self end end |
#limit(value) ⇒ ActiveRecord::HierarchicalQuery::Query
Specifies a limit for the number of records to retrieve.
193 194 195 196 197 |
# File 'lib/active_record/hierarchical_query/query.rb', line 193 def limit(value) @limit_value = value self end |
#nocycle(value = true) ⇒ ActiveRecord::HierarchicalQuery::Query
Turn on/off cycles detection. This option can prevent endless loops if your tree could contain cycles.
237 238 239 240 |
# File 'lib/active_record/hierarchical_query/query.rb', line 237 def nocycle(value = true) @nocycle_value = value self end |
#offset(value) ⇒ ActiveRecord::HierarchicalQuery::Query
Specifies the number of rows to skip before returning row
203 204 205 206 207 |
# File 'lib/active_record/hierarchical_query/query.rb', line 203 def offset(value) @offset_value = value self end |
#order_siblings(*columns) ⇒ ActiveRecord::HierarchicalQuery::Query Also known as: order
Specifies hierarchical order of the recursive query results.
225 226 227 228 229 |
# File 'lib/active_record/hierarchical_query/query.rb', line 225 def order_siblings(*columns) @order_values += columns self end |
#ordering_column_name ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
295 296 297 |
# File 'lib/active_record/hierarchical_query/query.rb', line 295 def ordering_column_name ORDERING_COLUMN_NAME end |
#orderings ⇒ ActiveRecord::HierarchicalQuery::Orderings
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
290 291 292 |
# File 'lib/active_record/hierarchical_query/query.rb', line 290 def orderings @orderings ||= Orderings.new(order_values, table) end |
#prior ⇒ Arel::Table Also known as: previous, recursive_table
Returns object representing parent rows table, so it could be used in complex WHEREs.
254 255 256 |
# File 'lib/active_record/hierarchical_query/query.rb', line 254 def prior @recursive_table ||= Arel::Table.new("#{normalized_table_name}__recursive") end |
#select(*columns) ⇒ ActiveRecord::HierarchicalQuery::Query
Specify which columns should be selected in addition to primary key, CONNECT BY columns and ORDER SIBLINGS columns.
152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 |
# File 'lib/active_record/hierarchical_query/query.rb', line 152 def select(*columns) = columns. columns = columns.flatten.map do |column| column.is_a?(Symbol) ? table[column] : column end # TODO: detect if column already present in START WITH clause and skip it if .fetch(:start_with, true) start_with { |scope| scope.select(columns) } end @child_scope_value = @child_scope_value.select(columns) self end |
#start_with(scope = nil, *arguments, &block) ⇒ ActiveRecord::HierarchicalQuery::Query
Specify root scope of the hierarchy.
84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 |
# File 'lib/active_record/hierarchical_query/query.rb', line 84 def start_with(scope = nil, *arguments, &block) raise ArgumentError, 'START WITH: scope or block expected, none given' unless scope || block case scope when Hash, String @start_with_value = klass.where(scope, *arguments) when ActiveRecord::Relation @start_with_value = scope else # do nothing if something weird given end if block object = @start_with_value || @klass @start_with_value = if block.arity == 0 object.instance_eval(&block) else block.call(object) end end self end |
#table ⇒ Object
Returns object representing child rows table, so it could be used in complex WHEREs.
270 271 272 |
# File 'lib/active_record/hierarchical_query/query.rb', line 270 def table @klass.arel_table end |
#where(*conditions) ⇒ Object
Generate methods that apply filters to child scope, such as where
or group
.
181 182 183 184 185 186 187 |
# File 'lib/active_record/hierarchical_query/query.rb', line 181 CHILD_SCOPE_METHODS.each do |method| define_method(method) do |*args| @child_scope_value = @child_scope_value.public_send(method, *args) self end end |