module PaperTrailAssociationTracking::Reifiers::HasOne
Reify a single `has_one` association of `model`. @api private
Public Class Methods
reify(assoc, model, options, transaction_id)
click to toggle source
@api private
# File lib/paper_trail_association_tracking/reifiers/has_one.rb, line 42 def reify(assoc, model, options, transaction_id) version = load_version(assoc, model, transaction_id, options[:version_at]) return unless version if version.event == "create" create_event(assoc, model, options) else noncreate_event(assoc, model, options, version) end end
Private Class Methods
create_event(assoc, model, options)
click to toggle source
@api private
# File lib/paper_trail_association_tracking/reifiers/has_one.rb, line 55 def create_event(assoc, model, options) if options[:mark_for_destruction] model.send(assoc.name).mark_for_destruction if model.send(assoc.name, true) else model.paper_trail.appear_as_new_record do model.send "#{assoc.name}=", nil end end end
load_version(assoc, model, transaction_id, version_at)
click to toggle source
Given a has-one association `assoc` on `model`, return the version record from the point in time identified by `transaction_id` or `version_at`. @api private
# File lib/paper_trail_association_tracking/reifiers/has_one.rb, line 68 def load_version(assoc, model, transaction_id, version_at) base_class_name = assoc.klass.base_class.name versions = load_versions(assoc, model, transaction_id, version_at, base_class_name) case versions.length when 0 nil when 1 versions.first else case ::PaperTrail.config.association_reify_error_behaviour when "warn" version = versions.first version.logger&.warn( FoundMoreThanOne.new(base_class_name, versions.length).message ) version when "ignore" versions.first else # "error" raise FoundMoreThanOne.new(base_class_name, versions.length) end end end
load_versions(assoc, model, transaction_id, version_at, base_class_name)
click to toggle source
@api private
# File lib/paper_trail_association_tracking/reifiers/has_one.rb, line 93 def load_versions(assoc, model, transaction_id, version_at, base_class_name) version_table_name = model.class.paper_trail.version_class.table_name model.class.paper_trail.version_class.joins(:version_associations). where("version_associations.foreign_key_name = ?", assoc.foreign_key). where("version_associations.foreign_key_id = ?", model.id). where("#{version_table_name}.item_type = ?", base_class_name). where("created_at >= ? OR transaction_id = ?", version_at, transaction_id). order("#{version_table_name}.id ASC"). load end
noncreate_event(assoc, model, options, version)
click to toggle source
@api private
# File lib/paper_trail_association_tracking/reifiers/has_one.rb, line 105 def noncreate_event(assoc, model, options, version) child = version.reify( options.merge( has_many: false, has_one: false, belongs_to: false, has_and_belongs_to_many: false ) ) model.paper_trail.appear_as_new_record do without_persisting(child) do model.send "#{assoc.name}=", child end end end
without_persisting(record) { || ... }
click to toggle source
Temporarily suppress save so we can reassociate with the reified master of a has_one relationship. Since ActiveRecord 5 the related object is saved when it is assigned to the association. ActiveRecord 5 also happens to be the first version that provides suppress.
# File lib/paper_trail_association_tracking/reifiers/has_one.rb, line 125 def without_persisting(record) if record.class.respond_to? :suppress record.class.suppress { yield } else yield end end