stefankroes / ancestry

Organise ActiveRecord model into a tree structure
MIT License
3.72k stars 458 forks source link

How can I move a node? #182

Open burtondav opened 10 years ago

burtondav commented 10 years ago

I have a model called Locations that has_ancestry. I would like a way to move a node - (edit the ancestry field). If I use <%= f.input :ancestry, :label => 'Parents’ %> in the Locations form, I get is invalid if the ancestry field is blank (root).

Is there a way to get a dropdown to select the new parent? <%= f.association :parent, :label_method => :name, :label => 'Parents' %> doesn't work.

wvengen commented 10 years ago

What I use is the following

= simple_form_for @location,
  = f.input :parent_id do
    = f.select :parent_id,
        nested_options(collection.where.not(id: f.object.id), selected: f.object.parent, title: :name),
        {}, {class: 'nested_options'}
rob-murray commented 10 years ago

Yes, simplest thing is to select/update the :parent_id on the object you are creating or editing. E.g.

= f.select :parent_id, 
  options_from_collection_for_select(ancestry_collection, :id, :a_pretty_name, the_object.parent_id), 
    { include_blank: 'Blank means no parent -  root object' }, 
    { class: 'form-control chosen-select' }

And then the controller (if Rails 4) should permit the :parent_id parameter to create the new object.

This also works for editing objects and changing the tree structure, i.e. moving them to a new parent, all descendants are updated.

bglusman commented 8 years ago

When I saw this issue, I thought I'd done a bunch of work unnecessarily on a project using ancestry, but maybe I'm misunderstanding... we need to move nodes around in our tree, including moving nodes from deep beneath one node to, still under that node but further up the tree, and these may have children who need to be updated accordingly. I build #make_parent_of and #make_root (and for convenience #make_child_of, which just calls make_parent_of on the argument with the receiver) methods to do this hierarchy manipulation, and was going to open a PR to offer them back to ancestry when I saw this issue. So I tested tried out replacing the guts of my make_child_of method with parent = and it didn't pass my tests, didn't seem to update the ancestry column of the nodes below the target with their new history, and the code seemed to just be doing a write attribute, not walking down the tree recursively to keep the ancestry values consistent.

So, confused what this is doing/how it can be useful without that, and also wondering if @stefankroes would be open to a PR adding these methods to ancestry?

bglusman commented 8 years ago

@stefankroes just was reminded of this from HN article, and wondered if my question was answered... not sure if any of the above in discussion are maintainers so thought I'd ping you :-)

stefankroes commented 8 years ago

When updating the parent of a node, Ancestry should move the entire subtree automatically. If it doesn't something is wrong.

burtondav commented 8 years ago

Ok - thanks!

tilo commented 7 years ago

When updating the parent of a node, Ancestry should move the entire subtree automatically. If it doesn't something is wrong.

@stefankroes thank you for your answer, but can you elaborate on typical scenarios where this can heppen?

devonpmack commented 2 years ago

We're seeing the children not getting updated when parent_id changes, @stefankroes could you elaborate on what could be wrong?

kbrock commented 2 years ago

hello @devonpmack

I think the majority of issues come when a node updated with a parent that is not updated yet.

So when the child saves, it gets the wrong ancestry string. As long as you are updating the values from the base to the children, everything tends to work fine