brendon / ranked-model

An acts_as_sortable/acts_as_list replacement built for Rails 4+
https://github.com/mixonic/ranked-model
MIT License
1.09k stars 134 forks source link

Sort based on another column / batch re-rank #58

Closed chrisbarber closed 5 months ago

chrisbarber commented 11 years ago

Not sure if this is a very common use-case, but I thought I'd mention it in case you find it worth thinking about.

I ended up needing to re-rank all elements based on another column in the table. E.g.

idrow_orderother_column
909
1041943041
1162914562

And you want to re-rank based on other_column ASC:

idrow_orderother_column
962914569
1001
1141943042

One way to do this in ranked-model would be like

Duck.order(:other_column => :asc).all.each_with_index do |duck, index|
  duck.update_attribute :row_order_position, index
end

For my case I ended up solving this using raw SQL which isn't the most desirable, but it is definitely efficient. It uses UPDATE FROM which I don't think is very portable, and ROW_NUMBER(), to basically just flip around the row_order column according to the desired sort order:

UPDATE ducks SET row_order = src.t1_roworder FROM
  (SELECT * FROM
    (SELECT *, row_order t1_roworder, ROW_NUMBER() OVER (ORDER BY row_order ASC) t1_rownum FROM ducks) t1 JOIN
    (SELECT *, ducks.id t2_id, ROW_NUMBER() OVER (ORDER BY other_column ASC) t2_rownum FROM ducks) t2
  ON t1_rownum = t2_rownum
  ORDER BY t2_id
  ) AS src
WHERE ducks.id = src.t2_id
jaredmdobson commented 9 years ago

This was just what I needed thanks @chrisbarber! :+1:

brendon commented 5 months ago

Closing due to inactivity.