Skip to content

Sorting in admin sortable index miscalculates indices when using acts_as_list plus ancestry #72

Open
@armchairdj

Description

@armchairdj

I'm using Acts as List + Ancestry to create a sortable tree for my model, and I'm using this gem to generate a drag-and-drop sortable index.

Relevant code here:

# model
has_ancestry cache_depth: true, orphan_strategy: :rootify
acts_as_list scope: [:ancestry], top_of_list: 0
# active_admin
sortable tree: true, max_levels: 2

index :as => :sortable do
  label :name

  actions
end

Based on that combination, I expect that when I create a bunch of records, indices will be calculated starting at 0 in each subnode of my tree structure. So if I start with this:

{
  { id: 0, ancestry: nil, position: 0, name: "Beatles"} => {
    { id: 1, ancestry: "0", position: 0, name: "John Lennon"     } => {},
    { id: 2, ancestry: "0", position: 1, name: "Paul McCartney"  } => {},
    { id: 3, ancestry: "0", position: 2, name: "Ringo Star"      } => {},
    { id: 4, ancestry: "0", position: 3, name: "George Harrison" } => {}
  },
  { id: 5, ancestry: nil, position: 1, name: "Kate Bush" } => {
    # Empty
  },
  { id: 6, ancestry: nil, position: 2, name: "Pink Floyd" } => {
    { id: 7, ancestry: "6", position: 0, name: "Syd Barett"      } => {},
    { id: 8, ancestry: "6", position: 1, name: "Roger Waters"    } => {},
    { id: 9, ancestry: "6", position: 2, name: "David Gilmour"   } => {}
  }
}

I can then call this:

Node.find(0).move_to_bottom
Node.find(9).move_to_top

And end up with this:

{
  { id: 5, ancestry: nil, position: 1, name: "Kate Bush" } => {
    # Empty
  },
  { id: 6, ancestry: nil, position: 2, name: "Pink Floyd" } => {
    { id: 9, ancestry: "6", position: 2, name: "David Gilmour"   } => {},
    { id: 7, ancestry: "6", position: 0, name: "Syd Barett"      } => {},
    { id: 8, ancestry: "6", position: 1, name: "Roger Waters"    } => {}
  },
  { id: 0, ancestry: nil, position: 0, name: "Beatles" } => {
    { id: 1, ancestry: "0", position: 0, name: "John Lennon"     } => {},
    { id: 2, ancestry: "0", position: 1, name: "Paul McCartney"  } => {},
    { id: 3, ancestry: "0", position: 2, name: "Ringo Star"      } => {},
    { id: 4, ancestry: "0", position: 3, name: "George Harrison" } => {}
  }
}

The acts_as_list methods are correctly executing the move commands within the context of the scope, AND the positions within each level of the tree are calculated correctly, starting at 0 within each ancestry depth.

However, when I revert to the original ordering and perform the same operations within my admin panel, I end up with this:

{
  { id: 5, ancestry: nil, position: 0, name: "Kate Bush" } => {
    # Empty
  },
  { id: 6, ancestry: nil, position: 1, name: "Pink Floyd" } => {
    { id: 9, ancestry: "6", position: 2, name: "David Gilmour"   } => {},
    { id: 7, ancestry: "6", position: 3, name: "Syd Barett"      } => {},
    { id: 8, ancestry: "6", position: 4, name: "Roger Waters"    } => {}
  },
  { id: 0, ancestry: nil, position: 5, name: "Beatles" } => {
    { id: 1, ancestry: "0", position: 6, name: "John Lennon"     } => {},
    { id: 2, ancestry: "0", position: 7, name: "Paul McCartney"  } => {},
    { id: 3, ancestry: "0", position: 8, name: "Ringo Star"      } => {},
    { id: 4, ancestry: "0", position: 9, name: "George Harrison" } => {}
  }
}

As you can see, active_admin-sortable_tree is generating positions without regard to scope. This hoses the position sequence of my entire model because when I use acts_as_list methods directly in the future, it assumes the indices will be relative to scope: :ancestry.

Am I doing something wrong in configuring my admin panel? Or is this a bug? Please advise.

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions