0

I have objects with a 'position' defined. I 'm moving one object (using jQuery Sortable), then I need to reindex the position of each object in that list (I want to keep them in order 0,1,2...n)

Basically we have a ProductLine model that contains Products (using act_as_list for convinience).

First, swap the position of the previous object and the new object (the one we just dropped here):

def sort
  @product = Product.find(params[:id])
  if(params.has_key?(:next_id))
    @next_product = Product.find(params[:next_id])
  end
  if(params.has_key?(:prev_id))
    @prev_product = Product.find(params[:prev_id])
  end

  if @prev_product.blank?
    @product.move_to_top
  elsif @next_product.blank?
    @product.move_to_bottom
  else
    @product.insert_at(@prev_product.position)
  end

  @product.save

  reindex @product.product_line_id

  render json: @products
end

This is the reindex function that ensures they are sequential:

def reindex(product_line_id)
  @products = Product.where(product_line_id: product_line_id).order(position: :asc)
  @products.each_with_index { |p, index|
    p.position = index
    p.save
  }
end

I'm quite new to the Ruby language and I'm sure there are several cleaner, more efficent ways of doing this?

Ian
  • 63
  • 6
  • Why do you need to "reindex" the list at all? Why not retrieve it with an order clause? – zetetic Jul 29 '15 at 00:00
  • From a technical perspective I don't have to reindex it. In the views I am retriving it with an order clause. However, the user is able to see and edit the order numbers, so if the first item has order 1 and the second has order 23 and the third has number 55, then that might be confusing to some users. – Ian Jul 29 '15 at 16:03
  • Sorry I misunderstood. It seems to me that you don't actually need to display the actual position of an item, only its *relative* position. Perhaps you could have the view generate the sequence itself using `each_with_index`? – zetetic Jul 29 '15 at 18:12

0 Answers0