Read more

Working around the ancestry gem's way of object destruction

Martin Straub
October 15, 2010Software engineer at makandra GmbH

The ancestry gem Show archive.org snapshot allows you to easily use tree structures in your Rails application.

Illustration online protection

Rails Long Term Support

Rails LTS provides security patches for old versions of Ruby on Rails (2.3, 3.2, 4.2 and 5.2)

  • Prevents you from data breaches and liability risks
  • Upgrade at your own pace
  • Works with modern Rubies
Read more Show archive.org snapshot

There is one somewhat unobvious pitfall to it: its way of applying the orphan_strategy which defines how it handles children of an object going to be destroyed.

What's this all about?

In many cases you might want to disallow destruction if there are any child nodes present. The restrict strategy does the trick but raises an exception when destroy is called:
has_ancestry :orphan_strategy => :restrict

One solution seems to be to prevent destruction by adding a check to the callback chain of destroy, either by a custom method or like that:
before_destroy :is_childless?

Unfortunately, this does not work as the gem has already put its method apply_orphan_strategy into the callback chain.

The problem of apply_orphan_strategy

The current implementation Show archive.org snapshot of this method does not add any errors or return false to prevent destruction -- it either raises an exception (for restrict) or destroys or moves all children, depending on your strategy.

If you tried to apply your own way you might not have set one which means the default: deletion of all child nodes before your method is even called.

Solution

Disable the gem's method by overwriting it:

def apply_orphan_strategy
  # Destruction will be handled separately.
end

You might package that (including a method adding errors) it into a neat trait Show archive.org snapshot which will keep this away from your model code.

Posted by Martin Straub to makandra dev (2010-10-15 14:37)