Class: Esse::ActiveRecord::Collection

Inherits:
Object
  • Object
show all
Includes:
Enumerable
Defined in:
lib/esse/active_record/collection.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(start: nil, finish: nil, batch_size: nil, **params) ⇒ Esse::ActiveRecord::Collection

Parameters:

  • start (Integer) (defaults to: nil)

    Specifies the primary key value to start from, inclusive of the value.

  • finish (Integer) (defaults to: nil)

    Specifies the primary key value to end at, inclusive of the value.

  • batch_size (Integer) (defaults to: nil)

    The number of records to be returned in each batch. Defaults to 1000.

  • params (Hash)

    The query criteria



69
70
71
72
73
74
# File 'lib/esse/active_record/collection.rb', line 69

def initialize(start: nil, finish: nil, batch_size: nil, **params)
  @start = start
  @finish = finish
  @batch_size = batch_size || self.class.batch_size || 1000
  @params = params
end

Instance Attribute Details

#batch_sizeInteger (readonly)

The number of records to be returned in each batch

Returns:

  • (Integer)


12
# File 'lib/esse/active_record/collection.rb', line 12

class_attribute :batch_size

#finishObject (readonly)

Returns the value of attribute finish.



62
63
64
# File 'lib/esse/active_record/collection.rb', line 62

def finish
  @finish
end

#paramsObject (readonly)

Returns the value of attribute params.



62
63
64
# File 'lib/esse/active_record/collection.rb', line 62

def params
  @params
end

#startObject (readonly)

Returns the value of attribute start.



62
63
64
# File 'lib/esse/active_record/collection.rb', line 62

def start
  @start
end

Class Method Details

.batch_context(name, proc = nil, override: false, &block) ⇒ Object

Raises:

  • (ArgumentError)


53
54
55
56
57
58
59
# File 'lib/esse/active_record/collection.rb', line 53

def batch_context(name, proc = nil, override: false, &block)
  proc = proc&.to_proc || block
  raise ArgumentError, 'proc or block required' unless proc
  raise ArgumentError, "batch_context `#{name}' already defined" if !override && batch_contexts.key?(name.to_sym)

  batch_contexts[name.to_sym] = proc
end

.inherited(subclass) ⇒ Object



38
39
40
41
42
43
# File 'lib/esse/active_record/collection.rb', line 38

def inherited(subclass)
  super

  subclass.scopes = scopes.dup
  subclass.batch_contexts = batch_contexts.dup
end

.inspectObject



25
26
27
28
29
30
# File 'lib/esse/active_record/collection.rb', line 25

def inspect
  return super unless self < Esse::ActiveRecord::Collection
  return super unless base_scope

  format('#<Esse::ActiveRecord::Collection__%s>', model)
end

.modelObject

Raises:

  • (NotImplementedError)


32
33
34
35
36
# File 'lib/esse/active_record/collection.rb', line 32

def model
  raise(NotImplementedError, "No model defined for #{self}") unless base_scope

  base_scope.call.all.model
end

.scope(name, proc = nil, override: false, &block) ⇒ Object

Raises:

  • (ArgumentError)


45
46
47
48
49
50
51
# File 'lib/esse/active_record/collection.rb', line 45

def scope(name, proc = nil, override: false, &block)
  proc = proc&.to_proc || block
  raise ArgumentError, 'proc or block required' unless proc
  raise ArgumentError, "scope `#{name}' already defined" if !override && scopes.key?(name.to_sym)

  scopes[name.to_sym] = proc
end

Instance Method Details

#base_scopeProc

The model class or the relation to be used as the scope

Returns:

  • (Proc)


8
# File 'lib/esse/active_record/collection.rb', line 8

class_attribute :base_scope

#batch_contextsHash

The hash with the contexts as key and the transformer proc as value

Returns:

  • (Hash)


21
# File 'lib/esse/active_record/collection.rb', line 21

class_attribute :batch_contexts

#countObject Also known as: size



92
93
94
# File 'lib/esse/active_record/collection.rb', line 92

def count
  dataset.except(:includes, :preload, :eager_load, :group, :order, :limit, :offset).count
end

#dataset(**kwargs) ⇒ Object



97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# File 'lib/esse/active_record/collection.rb', line 97

def dataset(**kwargs)
  query = self.class.base_scope&.call || raise(NotImplementedError, "No scope defined for #{self.class}")
  query = query.except(:order, :limit, :offset)
  params.merge(kwargs).each do |key, value|
    if self.class.scopes.key?(key)
      scope_proc = self.class.scopes[key]
      query = if scope_proc.arity == 0
        query.instance_exec(&scope_proc)
      else
        query.instance_exec(value, &scope_proc)
      end
    elsif query.model.columns_hash.key?(key.to_s)
      query = query.where(key => value)
    else
      raise ArgumentError, "Unknown scope `#{key}'"
    end
  end

  query
end

#eachObject



76
77
78
79
80
81
82
83
84
# File 'lib/esse/active_record/collection.rb', line 76

def each
  dataset.find_in_batches(**batch_options) do |rows|
    kwargs = params.dup
    self.class.batch_contexts.each do |name, proc|
      kwargs[name] = proc.call(rows, **params)
    end
    yield(rows, **kwargs)
  end
end

#each_batch_idsObject



86
87
88
89
90
# File 'lib/esse/active_record/collection.rb', line 86

def each_batch_ids
  dataset.select(:id).except(:includes, :preload, :eager_load).find_in_batches(**batch_options) do |rows|
    yield(rows.map(&:id))
  end
end

#inspectObject



118
119
120
121
122
123
124
125
126
# File 'lib/esse/active_record/collection.rb', line 118

def inspect
  return super unless self.class < Esse::ActiveRecord::Collection
  return super unless self.class.base_scope

  vars = instance_variables.map do |n|
    "#{n}=#{instance_variable_get(n).inspect}"
  end
  format('#<Esse::ActiveRecord::Collection__%s:0x%x %s>', self.class.model, object_id, vars.join(', '))
end

#scopesHash

Hash with the custom scopes defined on the model

Returns:

  • (Hash)


16
# File 'lib/esse/active_record/collection.rb', line 16

class_attribute :scopes