Class: ActionBlocks::FieldsEngine

Inherits:
Object
  • Object
show all
Defined in:
lib/action_blocks/data_engine/fields_engine.rb

Overview

Data Engine

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(root_klass, user: nil, table_alias_prefix:, select_reqs: []) ⇒ FieldsEngine

Returns a new instance of FieldsEngine.



7
8
9
10
11
12
13
14
15
16
# File 'lib/action_blocks/data_engine/fields_engine.rb', line 7

def initialize(root_klass, user: nil, table_alias_prefix:, select_reqs: [])
  @root_klass = root_klass
  @user = user
  @table_alias_prefix = table_alias_prefix
  @select_reqs = select_reqs
  @tables = {}
  @selects = []
  @joins = {}
  @wheres = []
end

Instance Attribute Details

#joinsObject

Returns the value of attribute joins.



4
5
6
# File 'lib/action_blocks/data_engine/fields_engine.rb', line 4

def joins
  @joins
end

#root_keyObject

Returns the value of attribute root_key.



4
5
6
# File 'lib/action_blocks/data_engine/fields_engine.rb', line 4

def root_key
  @root_key
end

#root_klassObject

Returns the value of attribute root_klass.



4
5
6
# File 'lib/action_blocks/data_engine/fields_engine.rb', line 4

def root_klass
  @root_klass
end

#select_reqsObject

Returns the value of attribute select_reqs.



4
5
6
# File 'lib/action_blocks/data_engine/fields_engine.rb', line 4

def select_reqs
  @select_reqs
end

#selectsObject

Returns the value of attribute selects.



4
5
6
# File 'lib/action_blocks/data_engine/fields_engine.rb', line 4

def selects
  @selects
end

#tablesObject

Returns the value of attribute tables.



4
5
6
# File 'lib/action_blocks/data_engine/fields_engine.rb', line 4

def tables
  @tables
end

#wheresObject

Returns the value of attribute wheres.



4
5
6
# File 'lib/action_blocks/data_engine/fields_engine.rb', line 4

def wheres
  @wheres
end

Instance Method Details

#create_table_and_joins(klass, node, key, parent_key, join_prefix = nil, associations = nil) ⇒ Object



61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/action_blocks/data_engine/fields_engine.rb', line 61

def create_table_and_joins(klass, node, key, parent_key, join_prefix = nil, associations = nil)
  # Create Arel Table Alias
  relation = klass.reflections[node.to_s] if node.is_a? Symbol
  unless @tables[key]
    @tables[key] = (relation ? relation.klass : node).arel_table.alias(key) unless @tables[key]

    # Create Join
    fk = associations ? associations[parent_key.to_s][:foreign_key] : relation.join_foreign_key
    pk = associations ? associations[parent_key.to_s][:primary_key] : relation.join_primary_key
    join_on = @tables[key].create_on(@tables[parent_key][fk].eq(@tables[key][pk]))
    @joins[join_prefix ? [join_prefix, node.to_s.underscore].compact.join('_').to_sym : key] = @tables[parent_key].create_join(@tables[key], join_on, Arel::Nodes::OuterJoin)
  end

  relation ? relation.klass : node
end

#fromsObject



85
86
87
# File 'lib/action_blocks/data_engine/fields_engine.rb', line 85

def froms
  @root_klass.arel_table.alias([@table_alias_prefix, @root_klass.to_s.underscore.pluralize].compact.join('_'))
end

#ordered_joinsObject



81
82
83
# File 'lib/action_blocks/data_engine/fields_engine.rb', line 81

def ordered_joins
  @joins.values
end

#params_to_arel(aggregate_params) ⇒ Object



57
58
59
# File 'lib/action_blocks/data_engine/fields_engine.rb', line 57

def params_to_arel(aggregate_params)
  aggregate_params.map { |param| param.is_a?(String) ? Arel::Nodes.build_quoted(param) : param } if aggregate_params
end

#processObject



18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# File 'lib/action_blocks/data_engine/fields_engine.rb', line 18

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

  # Add base table to tables
  @tables[@root_key.to_sym] = root_table

  # Add needed relations to tables
  @select_reqs.each do |selectreq|
    # binding.pry
    colname = selectreq[:field_name]
    colpath = selectreq[:path]
    function = selectreq[:function]
    node, *rest = colpath
    walk_colpath(@root_klass, node, @root_key, rest, colname, function)
  end
end

#queryObject



93
94
95
96
97
98
99
# File 'lib/action_blocks/data_engine/fields_engine.rb', line 93

def query
  @root_klass
    .from(froms)
    .select(selects)
    .joins(ordered_joins)
    .where(wheres.compact.reduce(&:and))
end

#walk_colpath(klass, node, parent_key, col_path, colname, function) ⇒ Object



36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/action_blocks/data_engine/fields_engine.rb', line 36

def walk_colpath(klass, node, parent_key, col_path, colname, function)
  key = [@table_alias_prefix, parent_key, node].compact.join('_').to_sym
  if !col_path.empty?

    next_klass = create_table_and_joins(klass, node, key, parent_key)

    # Recurse
    next_node, *rest = col_path
    walk_colpath(next_klass, next_node, key, rest, colname, function)
  else
    # Create Arel Select
    select = if function.nil?
               @tables[parent_key][node.to_sym].as(colname.to_s)
             else
               DatabaseFunctions.new.instance_exec(@tables[parent_key][node.to_sym], @user, &function).as(colname.to_s)
             end

    @selects << select
  end
end