Introduce orphan_strategy none
Many people override apply_orphan_strategy and either leave it blank or call custom methods from there. Introducing `orphan_strategy: :none` to allows developers to skip default orphan handling. From here a developer can add `before_destroy` with what ever logic is desired. It is possible to introduce a custom orphan strategy with a mixin/concern, but it doesn't seem to save any code and is not the best interface with too many nuances. Leaving in the code for now but not promoting to a supported feature yet.
This commit is contained in:
parent
cb9635cc3a
commit
753013a1bb
|
@ -5,6 +5,7 @@ a nice looking [Changelog](http://keepachangelog.com).
|
|||
|
||||
## Version [HEAD] <sub><sup>Unreleased</sub></sup>
|
||||
|
||||
* Introduce `orphan_strategy: :none` [#658](https://github.com/stefankroes/ancestry/pull/658)
|
||||
* Introduce `rebuild_counter_cache!` to reset counter caches. [#663](https://github.com/stefankroes/ancestry/pull/663) [#668](https://github.com/stefankroes/ancestry/pull/668) (thx @RongRongTeng)
|
||||
* Documentation fixes [#664](https://github.com/stefankroes/ancestry/pull/664) [#667](https://github.com/stefankroes/ancestry/pull/667) (thx @motokikando, @onerinas)
|
||||
* Introduce `build_cache_depth_sql!`, a sql alternative to `build_cache_depth` [#654](https://github.com/stefankroes/ancestry/pull/654)
|
||||
|
@ -41,7 +42,7 @@ jobs. If you need to do this in the ui, please use `cache_depth`.
|
|||
- `ancestry_primary_key_format` (introduced 4.3.0, removed by #649)
|
||||
- `touch_ancestors` (introduced 2.1, removed by TODO)
|
||||
* These are seen as internal and may go away:
|
||||
- `apply_orphan_strategy` (TODO: use `orphan_strategy => none` and define `before_destory`)
|
||||
- `apply_orphan_strategy` Please use `orphan_strategy: :none` and a custom `before_destory` instead.
|
||||
|
||||
## Version [4.3.3] <sub><sup>2023-04-01</sub></sup>
|
||||
|
||||
|
|
|
@ -172,6 +172,7 @@ The `has_ancestry` method supports the following options:
|
|||
:restrict An AncestryException is raised if any children exist
|
||||
:adopt The orphan subtree is added to the parent of the deleted node
|
||||
If the deleted node is Root, then rootify the orphan subtree
|
||||
:none skip this logic. (add your own `before_destroy`)
|
||||
:cache_depth Cache the depth of each node: (See Depth Cache section)
|
||||
false Do not cache depth (default)
|
||||
true Cache depth in 'ancestry_depth'
|
||||
|
|
|
@ -60,19 +60,13 @@ module Ancestry
|
|||
after_update :update_descendants_with_new_ancestry, if: :ancestry_changed?
|
||||
|
||||
# Apply orphan strategy before destroy
|
||||
case orphan_strategy
|
||||
when :rootify
|
||||
alias_method :apply_orphan_strategy, :apply_orphan_strategy_rootify
|
||||
when :destroy
|
||||
alias_method :apply_orphan_strategy, :apply_orphan_strategy_destroy
|
||||
when :adopt
|
||||
alias_method :apply_orphan_strategy, :apply_orphan_strategy_adopt
|
||||
when :restrict
|
||||
alias_method :apply_orphan_strategy, :apply_orphan_strategy_restrict
|
||||
else
|
||||
orphan_strategy_helper = "apply_orphan_strategy_#{orphan_strategy}"
|
||||
if method_defined?(orphan_strategy_helper)
|
||||
alias_method :apply_orphan_strategy, orphan_strategy_helper
|
||||
before_destroy :apply_orphan_strategy
|
||||
elsif orphan_strategy.to_s != "none"
|
||||
raise Ancestry::AncestryException.new(I18n.t("ancestry.invalid_orphan_strategy"))
|
||||
end
|
||||
before_destroy :apply_orphan_strategy
|
||||
|
||||
# Create ancestry column accessor and set to option or default
|
||||
if options[:cache_depth]
|
||||
|
|
|
@ -85,6 +85,62 @@ class OphanStrategiesTest < ActiveSupport::TestCase
|
|||
end
|
||||
end
|
||||
|
||||
def test_apply_orphan_strategy_none
|
||||
AncestryTestDatabase.with_model orphan_strategy: :none do |model, roots|
|
||||
root = model.create!
|
||||
child = model.create!(:parent => root)
|
||||
model.class_eval do
|
||||
def apply_orphan_strategy
|
||||
raise "this should not be called"
|
||||
end
|
||||
end
|
||||
assert_difference 'model.count', -1 do
|
||||
root.destroy
|
||||
end
|
||||
# this record should still exist
|
||||
assert child.reload.root_id == root.id
|
||||
end
|
||||
end
|
||||
|
||||
def test_apply_orphan_strategy_custom
|
||||
AncestryTestDatabase.with_model orphan_strategy: :none do |model|
|
||||
model.class_eval do
|
||||
before_destroy :apply_orphan_strategy_abc
|
||||
|
||||
def apply_orphan_strategy_abc
|
||||
apply_orphan_strategy_destroy
|
||||
end
|
||||
end
|
||||
|
||||
root = model.create!
|
||||
3.times { root.children.create! }
|
||||
model.create! # a node that is not affected
|
||||
assert_difference 'model.count', -4 do
|
||||
root.destroy
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Not supported. Keeping around to explore for future uses.
|
||||
def test_apply_orphan_strategy_custom_unsupported
|
||||
AncestryTestDatabase.with_model skip_ancestry: true do |model|
|
||||
model.class_eval do
|
||||
# needs to be defined before calling has_ancestry
|
||||
def apply_orphan_strategy_abc
|
||||
apply_orphan_strategy_destroy
|
||||
end
|
||||
|
||||
has_ancestry orphan_strategy: :abc, ancestry_column: AncestryTestDatabase.ancestry_column
|
||||
end
|
||||
root = model.create!
|
||||
3.times { root.children.create! }
|
||||
model.create! # a node that is not affected
|
||||
assert_difference 'model.count', -4 do
|
||||
root.destroy
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def test_basic_delete
|
||||
AncestryTestDatabase.with_model do |model|
|
||||
n1 = model.create! #create a root node
|
||||
|
|
Loading…
Reference in New Issue