brendon/positioning

Can't update other model attributes

bassemawhoob opened this issue · 3 comments

I have a self-referencing class Tag:

class Tag < ApplicationRecord
  positioned on: :parent_id
end

Where the parent_id could be null. I'm facing a weird behavior when I try to update other attributes than the position by calling Tag.find(2).update!(name: "japan"), I get the error:

ERROR:  duplicate key value violates unique constraint "index_tags_on_parent_id_and_position" (PG::UniqueViolation)
DETAIL:  Key (parent_id, "position")=(15, 0) already exists.

The current position of this tag is 1, given that I didn't change the position of the tag, I'm surprised it's trying to move the tag to position 0, let alone raise an error. Any ideas on what could possible be wrong? During my look into the codebase I found out that Positioning::Mechanisms#update_position runs the contract logic if position_changed? is true which will return true even if solidify_position returned the exact same old position

Update 1:
I'm also noticing that Tag.create!(name: "test") will always create with the position set to 0 which as far as I understand, should default to 1, but isn't happening.

Update 2:
For anyone coming facing this weird behavior, this is a conflict with closure_tree gem
I had has_closure_tree order: :position, numeric_order: true on the same model which apparently interferes with positioning

Haha! I Love these self-closing issues! :D

If you have an extra information for people using has_closure_tree and how you worked around the issue please post it here :)

This whole chaos is caused by numeric_order: true because closure_tree attempts to roll out its own positioning system if the order column is a number. Which in this case, we don't need if we're using positioning.

Fix: Removing numeric_order: true from the statement did the trick of keeping my sanity. I could still keep order: :position and everything works perfectly
Thanks @brendon for your work!

So great to hear! Thanks for using the library! :D