class Polo::Collector

Public Class Methods

new(base_class, id, dependency_tree={}) click to toggle source
# File lib/polo/collector.rb, line 4
def initialize(base_class, id, dependency_tree={})
  @base_class = base_class
  @id = id
  @dependency_tree = dependency_tree
  @selects = []
end

Public Instance Methods

collect() click to toggle source

Public: Traverses the dependency tree and collects every SQL query.

This is done by wrapping a top level call to includes(…) with a ActiveSupport::Notifications block and collecting every generate SQL query.

# File lib/polo/collector.rb, line 16
def collect
  unprepared_statement do
    ActiveSupport::Notifications.subscribed(collector, 'sql.active_record') do
      base_finder = @base_class.includes(@dependency_tree).where(@base_class.primary_key => @id)
      collect_sql(@base_class, base_finder.to_sql)
      base_finder.to_a
    end
  end

  @selects.compact.uniq
end

Private Instance Methods

collect_sql(klass, sql) click to toggle source
# File lib/polo/collector.rb, line 49
def collect_sql(klass, sql)
  @selects << {
    klass: klass,
    sql: sql
  }
end
collector() click to toggle source

Internal: Store ActiveRecord queries in @selects

Collector will intersect every ActiveRecord query performed within the ActiveSupport::Notifications.subscribed block defined in run and store the resulting SQL query in @selects

# File lib/polo/collector.rb, line 36
def collector
  lambda do |name, start, finish, id, payload|
    return unless payload[:name] =~ /^(.*) Load$/
    begin
      class_name = $1.constantize
      sql = payload[:sql]
      collect_sql(class_name, sql)
    rescue ActiveRecord::StatementInvalid, NameError
      # invalid table name (common when prefetching schemas)
    end
  end
end
unprepared_statement() { || ... } click to toggle source
# File lib/polo/collector.rb, line 56
def unprepared_statement
  if ActiveRecord::Base.connection.respond_to?(:unprepared_statement)
    ActiveRecord::Base.connection.unprepared_statement do
      yield
    end
  else
    yield
  end
end