Module: Mongoid::Association::Embedded::Batchable

Includes:
Positional
Included in:
EmbedsMany::Proxy
Defined in:
lib/mongoid/association/embedded/batchable.rb

Overview

Contains behavior for executing operations in batch on embedded documents.

Instance Method Summary collapse

Methods included from Positional

#positionally

Instance Method Details

#batch_clear(docs) ⇒ Array

Clear all of the docs out of the association in a single swipe.

Examples:

Clear all docs.

batchable.batch_clear(docs)


34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/mongoid/association/embedded/batchable.rb', line 34

def batch_clear(docs)
  pre_process_batch_remove(docs, :delete)
  unless docs.empty?
    collection.find(selector).update_one(
      positionally(selector, "$unset" => { path => true }),
      session: _session
    )
    unless Mongoid.broken_updates
      # This solves the case in which a user sets, clears and resets an
      # embedded document. Previously, since the embedded document was
      # already marked not a "new_record", it wouldn't be persisted to
      # the second time. This change fixes that and allows it to be persisted.
      docs.each { |doc| doc.new_record = true }
    end
    post_process_batch_remove(docs, :delete)
  end
  _unscoped.clear
end

#batch_insert(docs) ⇒ Array<Hash>

Insert new documents as a batch push ($push with $each). This ensures that all callbacks are run at the appropriate time and only 1 request is made to the database.

Examples:

Execute the batch push.

batchable.batch_insert([ doc_one, doc_two ])


22
23
24
# File 'lib/mongoid/association/embedded/batchable.rb', line 22

def batch_insert(docs)
  execute_batch_push(docs)
end

#batch_remove(docs, method = :delete) ⇒ Object

Batch remove the provided documents as a $pullAll or $pull.

Examples:

Batch remove the documents.

batchable.batch_remove([ doc_one, doc_two ])


60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/mongoid/association/embedded/batchable.rb', line 60

def batch_remove(docs, method = :delete)
  # If the _id is nil, we cannot use $pull and delete by searching for
  # the id. Therefore we have to use pullAll with the documents'
  # attributes.
  removals = pre_process_batch_remove(docs, method)
  pulls, pull_alls = removals.partition { |o| !o["_id"].nil? }

  if !_base.persisted?
    post_process_batch_remove(docs, method) unless docs.empty?
    return reindex
  end

  if !docs.empty?
    if !pulls.empty?
      collection.find(selector).update_one(
        positionally(selector, "$pull" => { path => { "_id" => { "$in" => pulls.pluck("_id") } } }),
        session: _session
      )
    end
    if !pull_alls.empty?
      collection.find(selector).update_one(
        positionally(selector, "$pullAll" => { path => pull_alls }),
        session: _session
      )
    end
    post_process_batch_remove(docs, method)
  else
    collection.find(selector).update_one(
      positionally(selector, "$set" => { path => [] }),
      session: _session
    )
  end
  reindex
end

#batch_replace(docs) ⇒ Array<Hash>

Batch replace the provided documents as a $set.

Examples:

Batch replace the documents.

batchable.batch_replace([ doc_one, doc_two ])


103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
# File 'lib/mongoid/association/embedded/batchable.rb', line 103

def batch_replace(docs)
  if docs.blank?
    if _assigning? && !empty?
      _base.delayed_atomic_sets.delete(path)
      clear_atomic_path_cache
      _base.add_atomic_unset(first)
      target_duplicate = _target.dup
      pre_process_batch_remove(target_duplicate, :delete)
      post_process_batch_remove(target_duplicate, :delete)
    else
      batch_remove(_target.dup)
    end
  elsif _target != docs
    _base.delayed_atomic_sets.delete(path) unless _assigning?
    docs = normalize_docs(docs).compact
    _target.clear and _unscoped.clear
    _base.delayed_atomic_unsets.delete(path)
    clear_atomic_path_cache
    inserts = execute_batch_set(docs)
    add_atomic_sets(inserts)
  end
end