Sha256: 76adc48d75ec7fff83d7f16ea7d29c9dd63b356d2dab7ad5babd558a5461c97d

Contents?: true

Size: 1.96 KB

Versions: 17

Compression:

Stored size: 1.96 KB

Contents

# frozen_string_literal: true

module Praxis
  module Extensions
    module FieldSelection
      class ActiveRecordQuerySelector
        attr_reader :selector, :query

        # Gets a dataset, a selector...and should return a dataset with the selector definition applied.
        def initialize(query:, selectors:, debug: false)
          @selector = selectors
          @query = query
          @logger = debug ? Logger.new($stdout) : nil
        end

        def generate
          # TODO: unfortunately, I think we can only control the select clauses for the top model
          # (as I'm not sure ActiveRecord supports expressing it in the join...)
          @query = add_select(query: query, selector_node: selector)
          eager_hash = _eager(selector)

          @query = @query.includes(eager_hash)
          explain_query(query, eager_hash) if @logger

          @query
        end

        def add_select(query:, selector_node:)
          # We're gonna always require the PK of the model, as it is a special case for AR, and the app itself
          # might assume it is always there and not be surprised by the fact that if it isn't, it won't blow up
          # in the same way as any other attribute not being loaded...i.e., ActiveModel::MissingAttributeError: missing attribute: xyz
          select_fields = selector_node.select + [selector_node.resource.model.primary_key.to_sym]
          select_fields.empty? ? query : query.select(*select_fields)
        end

        def _eager(selector_node)
          selector_node.tracks.transform_values do |track_node|
            _eager(track_node)
          end
        end

        def explain_query(query, eager_hash)
          @logger.debug("Query plan for ...#{selector.resource.model} with selectors: #{JSON.generate(selector.dump)}")
          @logger.debug(" ActiveRecord query: #{selector.resource.model}.includes(#{eager_hash})")
          query.explain
          @logger.debug('Query plan end')
        end
      end
    end
  end
end

Version data entries

17 entries across 17 versions & 1 rubygems

Version Path
praxis-2.0.pre.35 lib/praxis/extensions/field_selection/active_record_query_selector.rb
praxis-2.0.pre.34 lib/praxis/extensions/field_selection/active_record_query_selector.rb
praxis-2.0.pre.33 lib/praxis/extensions/field_selection/active_record_query_selector.rb
praxis-2.0.pre.32 lib/praxis/extensions/field_selection/active_record_query_selector.rb
praxis-2.0.pre.31 lib/praxis/extensions/field_selection/active_record_query_selector.rb
praxis-2.0.pre.30 lib/praxis/extensions/field_selection/active_record_query_selector.rb
praxis-2.0.pre.29 lib/praxis/extensions/field_selection/active_record_query_selector.rb
praxis-2.0.pre.28 lib/praxis/extensions/field_selection/active_record_query_selector.rb
praxis-2.0.pre.27 lib/praxis/extensions/field_selection/active_record_query_selector.rb
praxis-2.0.pre.26 lib/praxis/extensions/field_selection/active_record_query_selector.rb
praxis-2.0.pre.25 lib/praxis/extensions/field_selection/active_record_query_selector.rb
praxis-2.0.pre.24 lib/praxis/extensions/field_selection/active_record_query_selector.rb
praxis-2.0.pre.23 lib/praxis/extensions/field_selection/active_record_query_selector.rb
praxis-2.0.pre.22 lib/praxis/extensions/field_selection/active_record_query_selector.rb
praxis-2.0.pre.21 lib/praxis/extensions/field_selection/active_record_query_selector.rb
praxis-2.0.pre.20 lib/praxis/extensions/field_selection/active_record_query_selector.rb
praxis-2.0.pre.19 lib/praxis/extensions/field_selection/active_record_query_selector.rb