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



80
81
82
83
84
85
# File 'lib/esse/active_record/collection.rb', line 80

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.



73
74
75
# File 'lib/esse/active_record/collection.rb', line 73

def finish
  @finish
end

#paramsObject (readonly)

Returns the value of attribute params.



73
74
75
# File 'lib/esse/active_record/collection.rb', line 73

def params
  @params
end

#startObject (readonly)

Returns the value of attribute start.



73
74
75
# File 'lib/esse/active_record/collection.rb', line 73

def start
  @start
end

Class Method Details

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

Raises:

  • (ArgumentError)


60
61
62
63
64
65
66
# File 'lib/esse/active_record/collection.rb', line 60

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

.connected_to(**kwargs) ⇒ Object



68
69
70
# File 'lib/esse/active_record/collection.rb', line 68

def connected_to(**kwargs)
  self.connect_with = kwargs
end

.inherited(subclass) ⇒ Object



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

def inherited(subclass)
  super

  subclass.scopes = scopes.dup
  subclass.batch_contexts = batch_contexts.dup
  subclass.connect_with = connect_with&.dup
end

.inspectObject



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

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

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

.modelObject

Raises:

  • (NotImplementedError)


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

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)


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

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



107
108
109
110
111
# File 'lib/esse/active_record/collection.rb', line 107

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

#dataset(**kwargs) ⇒ Object



114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
# File 'lib/esse/active_record/collection.rb', line 114

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



87
88
89
90
91
92
93
94
95
96
97
# File 'lib/esse/active_record/collection.rb', line 87

def each
  with_connection do
    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
end

#each_batch_idsObject



99
100
101
102
103
104
105
# File 'lib/esse/active_record/collection.rb', line 99

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

#inspectObject



135
136
137
138
139
140
141
142
143
# File 'lib/esse/active_record/collection.rb', line 135

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