Class: ActionBlocks::SelectionsViaWhereEngine
- Inherits:
-
Object
- Object
- ActionBlocks::SelectionsViaWhereEngine
- Defined in:
- lib/action_blocks/data_engine/selections_via_where_engine.rb
Overview
Data Engine
Instance Attribute Summary collapse
-
#joins ⇒ Object
Returns the value of attribute joins.
-
#root_klass ⇒ Object
Returns the value of attribute root_klass.
-
#selection_filter_reqs ⇒ Object
Returns the value of attribute selection_filter_reqs.
-
#selection_match_reqs ⇒ Object
Returns the value of attribute selection_match_reqs.
-
#selects ⇒ Object
Returns the value of attribute selects.
-
#tables ⇒ Object
Returns the value of attribute tables.
Instance Method Summary collapse
- #froms ⇒ Object
-
#initialize(root_klass, user: nil, table_alias_prefix: nil, type: :many_to_many, selection_filter_reqs: [], selection_match_reqs: [], additional_where: nil) ⇒ SelectionsViaWhereEngine
constructor
A new instance of SelectionsViaWhereEngine.
- #ordered_joins ⇒ Object
- #process ⇒ Object
- #query ⇒ Object
- #subquery_for_many_to_many_selections ⇒ Object
- #walk_selection_match_path(klass, node, parent_key, col_path) ⇒ Object
- #wheres ⇒ Object
Constructor Details
#initialize(root_klass, user: nil, table_alias_prefix: nil, type: :many_to_many, selection_filter_reqs: [], selection_match_reqs: [], additional_where: nil) ⇒ SelectionsViaWhereEngine
Returns a new instance of SelectionsViaWhereEngine.
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
# File 'lib/action_blocks/data_engine/selections_via_where_engine.rb', line 6 def initialize(root_klass, user: nil, table_alias_prefix: nil, type: :many_to_many, selection_filter_reqs: [], selection_match_reqs: [], additional_where: nil) @root_klass = root_klass @table_alias_prefix = table_alias_prefix @tables = {} @joins = {} @wheres = [] @froms = [] @type = type @additional_where = additional_where # I named them selection_match_reqs because # the DataEngine may work with match_reqs in # different contexts. It may use them for # summary fields or it may use them for # a filtering a query to the children of some # base models 'children' @selection_match_reqs = selection_match_reqs @selection_filter_reqs = selection_filter_reqs end |
Instance Attribute Details
#joins ⇒ Object
Returns the value of attribute joins.
4 5 6 |
# File 'lib/action_blocks/data_engine/selections_via_where_engine.rb', line 4 def joins @joins end |
#root_klass ⇒ Object
Returns the value of attribute root_klass.
4 5 6 |
# File 'lib/action_blocks/data_engine/selections_via_where_engine.rb', line 4 def root_klass @root_klass end |
#selection_filter_reqs ⇒ Object
Returns the value of attribute selection_filter_reqs.
4 5 6 |
# File 'lib/action_blocks/data_engine/selections_via_where_engine.rb', line 4 def selection_filter_reqs @selection_filter_reqs end |
#selection_match_reqs ⇒ Object
Returns the value of attribute selection_match_reqs.
4 5 6 |
# File 'lib/action_blocks/data_engine/selections_via_where_engine.rb', line 4 def selection_match_reqs @selection_match_reqs end |
#selects ⇒ Object
Returns the value of attribute selects.
4 5 6 |
# File 'lib/action_blocks/data_engine/selections_via_where_engine.rb', line 4 def selects @selects end |
#tables ⇒ Object
Returns the value of attribute tables.
4 5 6 |
# File 'lib/action_blocks/data_engine/selections_via_where_engine.rb', line 4 def tables @tables end |
Instance Method Details
#froms ⇒ Object
92 93 94 95 96 97 98 |
# File 'lib/action_blocks/data_engine/selections_via_where_engine.rb', line 92 def froms if @type == :many_to_many [@root_table] else @froms end end |
#ordered_joins ⇒ Object
100 101 102 103 104 105 106 |
# File 'lib/action_blocks/data_engine/selections_via_where_engine.rb', line 100 def ordered_joins if @type == :many_to_many [] else @joins.values end end |
#process ⇒ Object
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
# File 'lib/action_blocks/data_engine/selections_via_where_engine.rb', line 27 def process @root_table = @root_klass.arel_table.alias([@table_alias_prefix, @root_klass.to_s.underscore.pluralize].compact.join('_')) root_key = [@table_alias_prefix, @root_klass.to_s.underscore.pluralize].compact.join('_').to_sym @froms << @root_table # Add base table to tables @tables[root_key.to_sym] = @root_table [@selection_match_reqs, @selection_filter_reqs].flatten.compact.each do |matchreq| node, *rest = matchreq[:base_path] # puts "base node: #{node} rest #{rest}" base_expression = walk_selection_match_path(@root_klass, node, root_key, rest) node, *rest = matchreq[:related_path] # puts "related node: #{node} rest #{rest}" = walk_selection_match_path(@root_klass, node, root_key, rest) where = if base_expression.class.ancestors.include?(Arel::Attributes::Attribute) base_expression.send(matchreq[:predicate], ) else .send(matchreq[:predicate], base_expression) end @wheres << where end end |
#query ⇒ Object
128 129 130 131 132 |
# File 'lib/action_blocks/data_engine/selections_via_where_engine.rb', line 128 def query @root_klass .joins(ordered_joins) .where(wheres) end |
#subquery_for_many_to_many_selections ⇒ Object
119 120 121 122 123 124 125 126 |
# File 'lib/action_blocks/data_engine/selections_via_where_engine.rb', line 119 def subquery_for_many_to_many_selections # Arel::Distinct.new(@rook_klasas[:id]) @root_klass .from([@froms].flatten) .select(@root_table[:id]) .joins(@joins.values) .where(@wheres.reduce(&:and)) end |
#walk_selection_match_path(klass, node, parent_key, col_path) ⇒ Object
53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 |
# File 'lib/action_blocks/data_engine/selections_via_where_engine.rb', line 53 def walk_selection_match_path(klass, node, parent_key, col_path) # puts "klass: #{klass} node: #{node} parent_key #{parent_key.inspect} col_path #{col_path.inspect}" # pp [key, rest_col_path] key = if node.class == Class [@table_alias_prefix, node.to_s.underscore.pluralize].compact.join('_').to_sym else [@table_alias_prefix, parent_key, node].compact.join('_').to_sym end return node if node.class != Symbol && node.class != Class if !col_path.empty? # Create Arel Table Alias if node.class != Class relation = klass.reflections[node.to_s] klass = relation.klass @tables[key] = klass.arel_table.alias(key) unless @tables[key] # Create Join fk = relation.join_foreign_key pk = relation.join_primary_key join_on = @tables[key].create_on(@tables[parent_key][fk].eq(@tables[key][pk])) @joins[key] = @tables[parent_key].create_join(@tables[key], join_on, Arel::Nodes::OuterJoin) else klass = node unless @tables[key] @tables[key] = klass.arel_table.alias(key) unless @tables[key] @froms << @tables[key] end end # Recurse next_node, *rest = col_path return walk_selection_match_path(klass, next_node, key, rest) else # Return expression # puts "parent_key: #{node.to_sym}" # puts "node: #{node.to_sym}" return @tables[parent_key][node.to_sym] end end |
#wheres ⇒ Object
108 109 110 111 112 113 114 115 116 117 |
# File 'lib/action_blocks/data_engine/selections_via_where_engine.rb', line 108 def wheres @wheres << @additional_where if @additional_where if @type == :many_to_many && (!@selection_match_reqs.empty? || !@selection_filter_reqs.empty?) subquery_arel = subquery_for_many_to_many_selections.arel # w = Arel::Nodes::In.new(@root_table[:id], subquery.ast) @root_table[:id].in(subquery_arel) else @wheres.reduce(&:and) end end |