lib/active_archive/base.rb in active_archive-2.3.0 vs lib/active_archive/base.rb in active_archive-2.4.0
- old
+ new
@@ -3,15 +3,11 @@
def self.included(base)
base.extend Methods
base.extend Scopes
- base.instance_eval do
- define_model_callbacks :unarchive
-
- before_unarchive :unarchive_destroyed_dependent_records
- end
+ base.instance_eval { define_model_callbacks(:unarchive) }
end
def archived?
archivable? ? !!archived_at : destroyed?
end
@@ -23,11 +19,11 @@
def destroy(force=nil)
with_transaction_returning_status do
if unarchivable? || should_force_destroy?(force)
permanently_delete_records_after { super() }
else
- destroy_with_permanent_records(force)
+ destroy_with_active_archive(force)
end
end
end
alias_method(:archive, :destroy)
@@ -35,13 +31,13 @@
def to_archival
I18n.t("active_archive.archival.#{archived? ? :archived : :unarchived}")
end
- def unarchive(validate=nil)
+ def unarchive(options=nil)
with_transaction_returning_status do
- run_callbacks(:unarchive) { set_archived_at(nil, validate) }
+ (should_unarchive_parent_first?(options) ? unarchival.reverse : unarchival).lazy.each { |r| r.call(options) }
self
end
end
alias_method(:unarchive!, :unarchive)
@@ -62,15 +58,24 @@
rescue NoMethodError => e
# RETURN
end
end
- def destroy_with_permanent_records(force=nil)
- run_callbacks(:destroy) { archived? || (new_record? ? save : set_archived_at(Time.now, force)) }
+ def destroy_with_active_archive(force=nil)
+ run_callbacks(:destroy) do
+ (archived? || new_record?) ? save : set_archived_at(Time.now, force)
+ true
+ end
+
archived? ? self : false
end
+ def get_archived_record
+ record_id = (self.respond_to?(:parent_id) && self.parent_id.present?) ? parent_id : id
+ self.class.unscoped.find(record_id)
+ end
+
def get_dependent_records
dependent_records = {}
self.class.reflections.lazy.each do |key, reflection|
if reflection.options[:dependent] == :destroy
next unless records = self.send(key)
@@ -87,11 +92,11 @@
return(dependent_records)
end
def permanently_delete_records(dependent_records)
dependent_records.lazy.each do |klass, ids|
- ids.each do |id|
+ ids.lazy.each do |id|
record = begin
klass.unscoped.find(id)
rescue ::ActiveRecord::RecordNotFound
next
end
@@ -106,68 +111,66 @@
dependent_results = block.call
permanently_delete_records(dependent_records) if dependent_results
return(dependent_results)
end
- def unarchive_destroyed_dependent_records
- self.class.reflections
- .lazy
- .select { |name, reflection| (reflection.options[:dependent].to_s == 'destroy'.freeze) && reflection.klass.archivable? }
- .each do |name, reflection|
- cardinality = reflection.macro.to_s.gsub('has_'.freeze, ''.freeze)
+ def unarchival
+ [
+ ->(_validate) { unarchive_destroyed_dependent_records(_validate) },
+ ->(_validate) { run_callbacks(:unarchive) { set_archived_at(nil, _validate) } }
+ ]
+ end
- if cardinality == 'many'.freeze
- records = archived_at.nil? ? send(name).unscoped : send(name).unscoped.where(
- [
- "#{reflection.quoted_table_name}.archived_at > ? AND #{reflection.quoted_table_name}.archived_at < ?",
- archived_at - ActiveArchive.configuration.dependent_record_window,
- archived_at + ActiveArchive.configuration.dependent_record_window
- ]
- )
- elsif cardinality == 'one'.freeze or cardinality == 'belongs_to'.freeze
- self.class.unscoped do
- records = [] << send(name)
- end
- end
+ def unarchive_destroyed_dependent_records(force = nil)
+ self.class.reflections.select do |name, reflection|
+ 'destroy'.freeze == reflection.options[:dependent].to_s && reflection.klass.archivable?
+ end.each do |name, reflection|
+ cardinality = reflection.macro.to_s.gsub('has_'.freeze, ''.freeze).to_sym
+ case cardinality
+ when :many
+ records = (archived_at ? set_record_window(send(name), name, reflection) : send(name))
+ when :one, :belongs_to
+ self.class.unscoped { records = [] << send(name) }
+ end
- [records].flatten.compact.lazy.each { |d| d.unarchive }
- send(name, :reload)
- end
+ [records].flatten.compact.lazy.each { |d| d.unarchive(force) }
+ send(name, :reload)
+ end
end
def set_archived_at(value, force=nil)
return self unless archivable?
- record = self.class.unscoped.find(id)
+ record = get_archived_record
record.archived_at = value
begin
should_ignore_validations?(force) ? record.save(validate: false) : record.save!
-
- if ::Gem::Version.new(::ActiveRecord::VERSION::STRING) < ::Gem::Version.new('4.2.0'.freeze)
- @attributes = record.attributes
- @attributes_cache = record.attributes.except(record.class.serialized_attributes.keys)
-
- if defined?(::ActiveRecord::AttributeMethods::Serialization::Attribute)
- serialized_attribute_class = ::ActiveRecord::AttributeMethods::Serialization::Attribute
- self.class.serialized_attributes.lazy.each do |key, coder|
- @attributes[key] = serialized_attribute_class.new(coder, @attributes[key], :unserialized) if @attributes.key?(key)
- end
- end
- else
- @attributes = record.instance_variable_get('@attributes'.freeze)
- end
+ @attributes = record.instance_variable_get('@attributes'.freeze)
rescue Exception => e
record.destroy
raise(e)
end
end
+ def set_record_window(request, name, reflection)
+ send(name).unscope(where: :archived_at)
+ .where([
+ "#{reflection.quoted_table_name}.archived_at > ? AND #{reflection.quoted_table_name}.archived_at < ?",
+ archived_at - ActiveArchive.configuration.dependent_record_window,
+ archived_at + ActiveArchive.configuration.dependent_record_window
+ ])
+ end
+
def should_force_destroy?(force)
(Hash === force) ? force[:force] : (:force == force)
end
def should_ignore_validations?(force)
(Hash === force) && (false == force[:validate])
+ end
+
+ def should_unarchive_parent_first?(order)
+ (Hash === order) && (true == order[:reverse])
end
end
end
\ No newline at end of file