Class: ActiveRecord::Duplicator
- Inherits:
-
Object
- Object
- ActiveRecord::Duplicator
- Defined in:
- lib/active_record/duplicator.rb,
lib/active_record/duplicator/errors.rb,
lib/active_record/duplicator/session.rb,
lib/active_record/duplicator/version.rb,
lib/active_record/duplicator/handler_api.rb,
lib/active_record/duplicator/association_traversal.rb,
sig/generated/active_record/duplicator.rbs,
sig/generated/active_record/duplicator/errors.rbs,
sig/generated/active_record/duplicator/session.rbs,
sig/generated/active_record/duplicator/version.rbs,
sig/generated/active_record/duplicator/handler_api.rbs,
sig/generated/active_record/duplicator/association_traversal.rbs
Overview
Reusable duplication configuration and entrypoint.
A Duplicator holds only per-model handler registrations; it does not hold any per-run state (the id map lives on Session). Freeze after registering handlers to enforce immutability across many duplication runs.
Example:
duplicator = ActiveRecord::Duplicator.new
duplicator.on(Attachment) { |api, klass, records| ... }
duplicator.freeze
new_root = duplicator.duplicate(old_root, associations: [...]) do |session|
session.mark_skip(tenant)
end
Defined Under Namespace
Classes: AssociationTraversal, DuplicateHandlerError, Error, HandlerApi, InvalidRecordIdError, MissingNewIdError, Session
Constant Summary collapse
- VERSION =
"0.5.0"
Instance Method Summary collapse
-
#duplicate(root_record, associations: [], transaction_options: {}, &block) ⇒ void
Run one duplication.
-
#freeze ⇒ self
Prevent further registrations.
-
#initialize ⇒ Duplicator
constructor
: () -> void.
-
#mark_skip_class(*klasses) ⇒ void
Declare that every record of the given classes must not be duplicated in any subsequent run.
-
#on(klass) {|arg0, arg1, arg2| ... } ⇒ void
Register a custom handler for the given model class.
Constructor Details
#initialize ⇒ Duplicator
: () -> void
25 26 27 28 |
# File 'lib/active_record/duplicator.rb', line 25 def initialize @handlers = {} @skipped_classes = Set.new end |
Instance Method Details
#duplicate(root_record, associations: [], transaction_options: {}, &block) ⇒ void
This method returns an undefined value.
Run one duplication. A fresh Session (with a fresh record id map) is created for every invocation, so state does not leak between runs.
If a block is given it is called with the new Session before duplication starts, letting the caller mark_skip or store_new_id for records that were duplicated elsewhere.
transaction_options is forwarded verbatim to Session#run, which forwards
it to root_record.transaction. Default is {} (plain
transaction do ... end).
: (ActiveRecord::Base, ?associations: untyped, ?transaction_options: Hash[Symbol, untyped]) ?{ (Session) -> void } -> ActiveRecord::Base
71 72 73 74 75 |
# File 'lib/active_record/duplicator.rb', line 71 def duplicate(root_record, associations: [], transaction_options: {}, &block) session = Session.new(handlers: @handlers, skipped_classes: @skipped_classes) block&.call(session) session.run(root_record, associations:, transaction_options:) end |
#freeze ⇒ self
Prevent further registrations. Also freezes the internal handler map so accidental mutation later fails loudly. : () -> self
54 55 56 57 58 |
# File 'lib/active_record/duplicator.rb', line 54 def freeze @handlers.freeze @skipped_classes.freeze super end |
#mark_skip_class(*klasses) ⇒ void
This method returns an undefined value.
Declare that every record of the given classes must not be duplicated in any subsequent run. See Session#mark_skip_class for the semantics; the Duplicator-level registration is applied to every fresh Session as its baseline, and Session#mark_skip_class can extend it for a single run. Repeated calls with the same class are idempotent. : (*Class) -> void
47 48 49 |
# File 'lib/active_record/duplicator.rb', line 47 def mark_skip_class(*klasses) @skipped_classes.merge(klasses) end |
#on(klass) {|arg0, arg1, arg2| ... } ⇒ void
This method returns an undefined value.
Register a custom handler for the given model class. See HandlerApi for the API the block receives.
Raises DuplicateHandlerError when the same class is registered twice. : (Class) { (HandlerApi, Class, untyped) -> void } -> void
35 36 37 38 39 |
# File 'lib/active_record/duplicator.rb', line 35 def on(klass, &block) raise DuplicateHandlerError, "handler for #{klass} is already registered" if @handlers.key?(klass) @handlers[klass] = block end |