Module: BulkInsertableAssociations

Extended by:
ActiveSupport::Concern
Included in:
CommitStatus, MergeRequestDiff
Defined in:
app/models/concerns/bulk_insertable_associations.rb

Overview

ActiveRecord model classes can mix in this concern if they own associations who declare themselves to be eligible for bulk-insertion via [BulkInsertSafe]. This allows the caller to write items from [has_many] associations en-bloc when the owner is first created.

This implementation currently has a few limitations:

  • only works for [has_many] relations

  • does not support the [:through] option

  • it cannot bulk-insert items that had previously been saved, nor can the owner of the association have previously been saved; if you attempt to so, an error will be raised

Note that just like [BulkInsertSafe.bulk_insert!], validations will run for all items that are scheduled for bulk-insertions.

Examples:


class MergeRequestDiff < ApplicationRecord
  include BulkInsertableAssociations

  # target association class must `include BulkInsertSafe`
  has_many :merge_request_diff_commits
end

diff = MergeRequestDiff.new(...)
diff.diff_commits << MergeRequestDiffCommit.build(...)
BulkInsertableAssociations.with_bulk_insert do
  diff.save! # this will also write all `diff_commits` in bulk
end

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.bulk_inserts_enabled?Boolean

Returns:

  • (Boolean)

38
39
40
# File 'app/models/concerns/bulk_insertable_associations.rb', line 38

def bulk_inserts_enabled?
  Thread.current['bulk_inserts_enabled']
end

.with_bulk_insert(enabled: true) ⇒ Object

All associations that are [BulkInsertSafe] and that as a result of calls to

save

or [save!] would be written to the database, will be inserted using

bulk_insert!

instead.

Note that this will only work for entities that have not been persisted yet.

Parameters:

  • enabled (Boolean) (defaults to: true)

    When [true], bulk-inserts will be attempted within the given block. If [false], bulk-inserts will be disabled. This behavior can be nested.


51
52
53
54
55
56
57
# File 'app/models/concerns/bulk_insertable_associations.rb', line 51

def with_bulk_insert(enabled: true)
  previous = bulk_inserts_enabled?
  Thread.current['bulk_inserts_enabled'] = enabled
  yield
ensure
  Thread.current['bulk_inserts_enabled'] = previous
end

Instance Method Details

#bulk_insert_associations!Object


60
61
62
63
64
# File 'app/models/concerns/bulk_insertable_associations.rb', line 60

def bulk_insert_associations!
  self.class.reflections.each do |_, reflection|
    _bulk_insert_association!(reflection)
  end
end