Search code examples
ruby-on-railsrubyruby-on-rails-3acts-as-list

Ordering position on Model during update


I am using acts_as_list on my Product model, and trying to make it so you can manually edit the position. Currently if I edit Product 3 from position 3 to position 1, it won't adjust the other products

Example: Move Product from Position 3 to Position 1

ID Name Position
1 Product 1
2 Product 2
3 Product 3

Will result to

ID Name Position
1 Product 1
2 Product 2
3 Product 1

But I need it to result to

ID Name Position
1 Product 2
2 Product 3
3 Product 1

I've come to the conclusion I should add the code to my products update class. Here is what I have so far:

def update
#To edit acts_as_list manually, just get all items with a position higher 
#than the current item and increment each one.

#Find the product to be changed
@product = Product.find(params[:id])

#Find if there is a product already in the requested position
old_product = Product.find_by_position_and_category_id(params[:position], params[:category_id])



  #If the old product has a position less then the current product, return the products in between minus 1
  if @product.position > old_product.position
    products = Product.where(:product < @product.position, :product > @old_product.position)
    products.each do |product|
      product.position + 1
    end
  #If old product position is greater then current product position, return the products in between and decrement all position
  elsif old_product.position < @product.position
    products = Product.all
    products.each do |product|
      product.position = product.position - 1
    end
 end

In this code i'm trying to grab all the products withing the range of the old product and new product, then increment the position of all of them, but my code isn't working, It seems like the call old_product = Product.find_by_position_and_category_id(params[:position], params[:category_id]) keeps returning nil, when it should return the product with the position of the old product.

Thanks for any help, and let me know if i'm on the right track or if there is a easier way of doing this.


Solution

  • acts_as_list provides helper methods to do this sort of thing without needing to add your own code. If you want to move your product from position 3 to position 1 and automatically reorder everything else, do this:

    @product.insert_at(1)
    

    Try that instead of manually changing the position and see if that doesn't simplify your code.