SpeciesFileGroup/taxonworks

View on GitHub
lib/query_batch_request.rb

Summary

Maintainability
A
0 mins
Test Coverage
# Facilitate Batch updates using the pattern of
#   filter_query -> objects to update
#   stub object -> attributes/params to update
#
# !! Should say nothing about *how* to update the objects.
#
class QueryBatchRequest

  # @param object_params [Hash]
  #   update the records to these attributes
  attr_accessor :object_params

  # @param object_filter_params [Hash]
  #   The params to parameterize a Queries::*::Filter.
  #   Defines the objects to be updated
  attr_accessor :object_filter_params

  # @return Boolean
  #   true - rollback changes, can not be used with async
  attr_accessor :preview

  # @return Boolean
  #   processing is handled fully asyn if true, can not be used with preview = true
  attr_accessor :async

  # Number of records at which process is automatically made  async
  attr_accessor :async_cutoff

  # @return nil, Integer
  #   the max allowed records
  attr_accessor :cap

  # @return String, nil
  #   the reason the cap is why it is (not required)
  attr_accessor :cap_reason

  # @return String
  #   defines the Filter/Model to act on
  attr_accessor :klass

  # @return a Queries::<<klass>>::Filter instance
  attr_accessor :filter

  # Count of the records retured in filter.
  #   Not used in async
  attr_accessor :total_attempted

  def initialize(params)
    @async = params[:async]
    @async_cutoff = params[:async_cutoff]
    @cap = params[:cap]
    @cap_reason = params[:cap_reason]
    @klass = params[:klass] # || infer_class(params)
    @object_filter_params = params[:object_filter_params]
    @object_params = params[:object_params]
    @preview = params[:preview]

    @mode = params[:mode]
  end

   def infer_class(params)
     f = Queries::Query::Filter.base_filter(params)
     @klass = f.referenced_class.name.to_s
   end

  def object_filter_params
    filter.params
  end

  def unprocessable?
    object_filter_params.blank? || object_params.blank? || (run_async? && preview)
  end

  def filter
    @filter ||= "Queries::#{klass}::Filter".safe_constantize.new(
      @object_filter_params
    )
    @filter
  end

  def total_attempted
    @total_attempted ||= filter.all.count
    @total_attempted
  end

  def response_params
    {
      klass:,
      async:,
      async_cutoff:,
      preview:,
      cap:,
      cap_reason:,
      total_attempted:
    }
  end

  def stub_response
    BatchResponse.new(response_params)
  end

  def capped?
    if total_attempted > cap
      @cap_reason = "Update to more objects than allowed (#{cap}) requested." if cap_reason.blank?
      return true
    else
      false
    end
  end

  def run_async?
    if async_cutoff
      return total_attempted > async_cutoff
    end
  end

  # @return Boolean
  #   whether to run the job asyncronously
  def async
    if @async.nil? # force all not specified
      @async = run_async?
    end
    @async
  end

end