In one of the projects that I worked in I had to make it possible for users to easily change the order in which the records of a table would appear in their index page. I knew that there were a few gems out there that could handle this for me, but I thought that it was such a simple functionality that it was probably not a strong enough reason to add another dependency to the project; so I went about building it.
In this example I've added this functionality to a Product model. I started by creating a migration to add the column that would keep the order between products, I decided to call this column sort_index.
Then I added a few methods to the Product model. Some methods to check the position of a product, others to move the product up and down in the 'ranking' of products, and a before_create callback to set the initial sort_index of each new product. Note that the upper position in my implementation is the position with sort_index equal to 0, so moving a product up is actually reducing its sort_index by 1.
These methods were tested with RSpec (might not be 100% coverage, let me know if that is the case). I've moved the RSpec file to the end of the post because is quite a long file.
Having these methods working I implemented the functionality and the interface to allow the users to actually change the ordering of the products.
Created the necessary routes.
Created the controller methods.
Followed by the views. The index page.
Which calls the _ordering partial
And then the js views to process the result of the requests. To move down.
And to move up.
If you need to use this in more than one model you can move some bits into a Module and then include the Module where necessary. I haven't had the need to do it. But if I do, I'll probably do a post about it.
Hope these bits of code are useful for you some day, I've already used in two projects. If you find any issues or have any suggestions to improve this code please let me know.
And now for the RSpec file: