module Remont class Schema MISSING_PROCESSING_STATUS_ATTR = "Processing status attribute isn't configured".freeze # @return [Array] attr_reader :attributes # @return [Nil, String, Symbol] attr_reader :process_timestamp_attribute # @param [Hash] opts # @option [Class] :model # @option [Proc] :scope # @option [String, Symbol] :process_timestamp_attribute # @param [Proc] block def initialize(opts = {}, &block) @model = opts.fetch(:model) @model_scope = opts.fetch(:scope, default_scope) @without_processed_scope = default_scope @process_timestamp_attribute = opts.fetch(:process_timestamp_attribute, Remont.config.process_timestamp_attribute) @before_cb = nil @after_cb = nil @attributes = [] instance_eval(&block) end # @return [Remont::Schema] def without_processed raise MISSING_PROCESSING_STATUS_ATTR if @process_timestamp_attribute.nil? @without_processed_scope = proc { |scope| scope.where(process_timestamp_attribute => nil) } self end # @param [String, Symbol] attr_name # @return [Remont::Schema] def with_process_timestamp_attribute(attr_name) @process_timestamp_attribute = attr_name self end # @param [Proc] scope # @return [Remont::Schema] def scope(&scope) @model_scope = scope self end # @param [Symbol] name # @param [Hash] opts # @option [#call] :using # @param [Proc] processor # @return [Remont::Schema] def attribute(...) @attributes << Attribute.new(...) self end # @param [Proc] block # @return [Remont::Schema] def before(&block) @before_cb = block self end # @param [Proc] block # @return [Remont::Schema] def after(&block) @after_cb = block self end # @return [Any] def process! records_for_processing.find_each { |record| processor.process!(record) } end private attr_reader :model attr_reader :without_processed_scope attr_reader :model_scope attr_reader :before_cb attr_reader :after_cb def processor @processor ||= RecordProcessor.new(self, before_cb, after_cb) end def records_for_processing model_scope.call( without_processed_scope.call(model.all) ) end def default_scope proc { |scope| scope } end end end