I’m the maintainer of the acts_as_list and ranked-model gems and recently I’ve written a new positioning gem of my own. It’s named unimaginatively: positioning.
It takes the best of both of the aforementioned gems and adds an advisory lock to guarantee sequential list operations:
Doesn’t pollute the model namespace (inspired by ranked-model)
Uses sequential integer position values like acts_as_list.
Honours uniqueness constraints when expanding and contracting space in the list.
Promotes the use of relative positioning over explicit positioning (e.g. before: other_list_member)
Does its best to prevent gaps in the position sequence via clamping and an advisory lock.
Allows more than one list to exist per model (like ranked-model)
Scope by belongs_to relationship, model column, a combination of the two, or not at all!
Automatically handles moving list items between scopes (like acts_as_list and ranked-model).
I’m using it in production and encourage others to take a look and provide feedback.
I’ll still be maintaining acts_as_list and ranked-model so don’t fret
This looks very promising and has handy create/update helpers. Project looks neat, well done.
I’m currently an ‘Ancestry’ gem user, but will definitely look into the ‘Positioning’ gem.
I like the idea how to easily assign positions using your gem:
Thanks @Frank1, I use ancestry too! It’s a very useful gem. I’ve actually used it in conjunction with acts_as_list and ranked-model in different projects to have an ordered tree. It’s easy to scope to the ancestry column. I haven’t tried that with my gem but I assume it’d work fine. Let me know how it goes
Is it possible to add positioning conditionally?
I am trying this gem for a single model and need to set position for a particular field - conditionally
something like this
class TestModel < ApplicationRecord
positioned on: :position, if proc {|t| t.another_field == 'something'}
end
Every record will belong to a list with positioning. You can use a boolean scope and just disregard the ordering in the false scope. It’ll still happen though:
positioned on: :boolean_column
I haven’t designed for a condition evaluated in Ruby however since the SQL statements used to rearrange the list wouldn’t work in that case.
You’re most welcome! Best country in the world right?!
We actually sniff for belongs_to reflections and so if you pass positioned on: :taskable we’d translate that to taskable_id which would be incorrect here. I’ll do an update to cater for polymorphic belongs_to. Once I’ve released the change you should be able to just do positioned on: :taskable.