Module: Esse::Repository::ClassMethods

Included in:
Esse::Repository
Defined in:
lib/esse/repository/actions.rb,
lib/esse/repository/documents.rb,
lib/esse/repository/object_document_mapper.rb

Instance Method Summary collapse

Instance Method Details

#action(name, options = {}, &block) ⇒ Object



6
7
# File 'lib/esse/repository/actions.rb', line 6

def action(name, options = {}, &block)
end

#coerce_to_document(value) ⇒ Object



41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/esse/repository/object_document_mapper.rb', line 41

def coerce_to_document(value)
  case value
  when Esse::Document
    value
  when Hash
    Esse::HashDocument.new(value)
  when NilClass, FalseClass
    Esse::NullDocument.new
  else
    raise ArgumentError, format('%<arg>p is not a valid document. The document should be a hash or an instance of Esse::Document', arg: value)
  end
end

#collection(collection_klass = nil, **_, &block) ⇒ void

This method returns an undefined value.

Used to define the source of data. A block is required. And its content should yield an array of each object that should be serialized. The list of arguments will be passed throught the document method.

Example:

collection AdminStore
collection do |**conditions, &block|
  User.where(conditions).find_in_batches(batch_size: 5000) do |batch|
    block.call(batch, conditions)
  end
end

Parameters:

  • name (String)

    The identification of the collection.

  • klass (Class)

    The class of the collection. (Optional when block is passed)

  • block (Proc)

    The block that will be used to iterate over the collection. (Optional when using a class)



82
83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/esse/repository/object_document_mapper.rb', line 82

def collection(collection_klass = nil, **_, &block)
  if collection_klass.nil? && block.nil?
    raise ArgumentError, 'a document type, followed by a collection class or block that stream the data ' \
                        'is required to define the collection'
  end

  if block.nil? && collection_klass.is_a?(Class) && !collection_klass.include?(Enumerable)
    msg = '%<arg>p is not a valid collection class.' \
          ' Collections should implement the Enumerable interface.'
    raise ArgumentError, format(msg, arg: collection_klass)
  end

  @collection_proc = collection_klass || block
end

#document(klass = nil, &block) ⇒ Object

Convert ruby object to json. Arguments will be same of passed through the collection. It’s allowed a block or a class with the to_h instance method. Example with block

document do |model, **context|
  {
    id: model.id,
    admin: context[:is_admin],
  }
end

Example with document class

document UserDocument


20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/esse/repository/object_document_mapper.rb', line 20

def document(klass = nil, &block)
  if @document_proc
    raise ArgumentError, format('Document for %p already defined', repo_name)
  end

  if block
    @document_proc = ->(model, **kwargs) { coerce_to_document(block.call(model, **kwargs)) }
  elsif klass.is_a?(Class) && klass <= Esse::Document
    @document_proc = ->(model, **kwargs) { klass.new(model, **kwargs) }
  elsif klass.is_a?(Class) && klass.instance_methods.include?(:to_h)
    @document_proc = ->(model, **kwargs) { coerce_to_document(klass.new(model, **kwargs).to_h) }
  elsif klass.is_a?(Class) && klass.instance_methods.include?(:as_json) # backward compatibility
    @document_proc = ->(model, **kwargs) { coerce_to_document(klass.new(model, **kwargs).as_json) }
  elsif klass.is_a?(Class) && klass.instance_methods.include?(:call)
    @document_proc = ->(model, **kwargs) { coerce_to_document(klass.new(model, **kwargs).call) }
  else
    msg = format("%<arg>p is not a valid document. The document should inherit from Esse::Document or respond to `to_h'", arg: klass)
    raise ArgumentError, msg
  end
end

#documents(**kwargs) ⇒ Enumerator

Wrap collection data into serialized documents

Example:

GeosIndex.documents(id: 1).first

Returns:

  • (Enumerator)

    All serialized entries



146
147
148
149
150
151
152
# File 'lib/esse/repository/object_document_mapper.rb', line 146

def documents(**kwargs)
  Enumerator.new do |yielder|
    each_serialized_batch(**kwargs) do |docs, **_collection_kargs|
      docs.each { |document| yielder.yield(document) }
    end
  end
end

#each_batch(*args, **kwargs, &block) ⇒ void

TODO:

Remove *args. It should only support keyword arguments

This method returns an undefined value.

Used to fetch all batch of data defined on the collection model. Arguments can be anything. They will just be passed through the block. Useful when the collection depends on scope or any other conditions

Example:

each_batch(active: true) do |data, **_collection_opts|
  puts data.size
end

Parameters:

  • kwargs (Hash)

    The context

  • block (Proc)

    The block that will be used to iterate over the collection.



111
112
113
114
115
116
117
118
119
120
121
122
123
124
# File 'lib/esse/repository/object_document_mapper.rb', line 111

def each_batch(*args, **kwargs, &block)
  if @collection_proc.nil?
    raise NotImplementedError, format('there is no %<t>p collection defined for the %<k>p index', t: repo_name, k: index.to_s)
  end

  case @collection_proc
  when Class
    @collection_proc.new(*args, **kwargs).each(&block)
  else
    @collection_proc.call(*args, **kwargs, &block)
  end
rescue LocalJumpError
  raise(SyntaxError, 'block must be explicitly declared in the collection definition')
end

#each_serialized_batch(**kwargs) {|Array, **context| ... } ⇒ Enumerator

Wrap collection data into serialized batches

Parameters:

  • kwargs (Hash)

    The context

Yields:

  • (Array, **context)

    serialized collection and the optional context from the collection

Returns:

  • (Enumerator)

    The enumerator



131
132
133
134
135
136
137
138
# File 'lib/esse/repository/object_document_mapper.rb', line 131

def each_serialized_batch(**kwargs, &block)
  each_batch(**kwargs) do |*args|
    batch, collection_context = args
    collection_context ||= {}
    entries = [*batch].map { |entry| serialize(entry, **collection_context) }.compact
    block.call(entries, **kwargs)
  end
end

#import(**kwargs) ⇒ Object



6
7
8
# File 'lib/esse/repository/documents.rb', line 6

def import(**kwargs)
  index.import(repo_name, **kwargs)
end

#serialize(model, **kwargs) ⇒ Esse::Document

Convert ruby object to json by using the document of the given document type.

Parameters:

  • model (Object)

    The ruby object

  • kwargs (Hash)

    The context

Returns:



58
59
60
61
62
63
64
# File 'lib/esse/repository/object_document_mapper.rb', line 58

def serialize(model, **kwargs)
  if @document_proc.nil?
    raise NotImplementedError, format('there is no %<t>p document defined for the %<k>p index', t: repo_name, k: index.to_s)
  end

  @document_proc.call(model, **kwargs)
end