Ruby on Rails - Does ActsAsList have known problem when working with nested_attributes?

243 views Asked by At

I am having a problem when updating acts_as_list positions with nested_attributes, I have worked my way down and noticed the issue is still happening on the model level (as shown below). The problem is occurring when building a nested_attribute object and replacing another object at it's position. Has anyone experienced similar problems or point me in the right direction please ?

The setup:

class List < ActiveRecord
  has_many :list_items, -> { order(position: :asc) }, dependent: :destroy, inverse_of: :list
  accepts_nested_attributes_for :list_items, reject_if: :all_blank, allow_destroy: true
end

class ListItem < ActiveRecord
  acts_as_list scope: [:list_id, { deleted_at: nil }]
  belongs_to :list, inverse_of: :list_items
end

The Problem: The issue Im having is when building a new list_item in place of an existing one.

Example:

list = ListItem.create
list.list_items.create(name: 'Item 1')
list.list_items.create(name: 'Item 2')

#ListItems output
list.list_items.first.position #=> 1
list.list_items.last.position #=> 2

# Re-Order
new_item = list.list_items.build(name: 'New Item 2', position: 2)
list.list_items.second.position = 3

#Output 
list.list_items.first.position #=> 1
list.list_items.second.position #=> 3
list.list_items.last.position #=> 2

list.save

#Output 
list.list_items.first.position #=> 1
list.list_items.second.position #=> 3
list.list_items.last.position #=> 2

At this point all seems to work fine, however when I reload the 'list' from the database I get a weird issue ... (the list items are being ordered on 'id' as default for this example)

list.reload

#Output 
list.list_items.first.position #=> 1
list.list_items.second.position #=> 4
list.list_items.last.position #=> 2

After testing it seems that the items positions below the newly inserted item(s) is off by the number of newly inserted items.

Has anyone experienced the same issue and found the problem either in the code of acts_as_list itself ?

Thank you in advance for any help

1

There are 1 answers

2
Brendon Muir On

Just looking at your code you have a double comma in your has_many definition:

has_many :list_items, , -> { order(position: :asc) }, dependent: :destroy, inverse_of: :list

Remove the extra comma and see what happens. My guess is that the order is not being applied because it's not being provided and Rails is silently ignoring the proc.