开发者

Update all record matching some conditions but keeping "position-indexed" values in a database table column

开发者 https://www.devze.com 2023-03-20 08:49 出处:网络
I am using Ruby on Rails 3.0.7 and I have a position database table column in order to handle a sortable list of records. I would like to update that column for all records matching some conditions on

I am using Ruby on Rails 3.0.7 and I have a position database table column in order to handle a sortable list of records. I would like to update that column for all records matching some conditions on destroying a record which position value is "in the middle of all position values", but keeping the order (numerically) in the position column.

That is, for example, if in the following list of class objects I destroy the record with position 3 and user_id 1

#<Article id: 1, position: 1, user_id: 1>,
#<Article id: 2, position: 1, user_id: 2>,
#<Article id: 3, position: 2, user_id: 1>,
#<Article id: 4, position: 3, user_id: 1>,
#<Article id: 5, position: 1, user_id: 3>,
#<Article id: 6, position: 4, user_id: 1>,
#<Article id: 7, position: 5, user_id: 1>,
#<...> # A lot of others records having 'user_id' = 1

I would like to update all other records related to user_id 1 so to have

#<Article id: 1, position: 1, user_id: 1>,
#<Article id: 2, position: 1, user_id: 2>,
#<Article id: 3, po开发者_如何学运维sition: 2, user_id: 1>,
#<Article id: 5, position: 1, user_id: 3>,
#<Article id: 6, position: 3, user_id: 1>,
#<Article id: 7, position: 4, user_id: 1>,
#<...> # A lot of others records having 'user_id' = 1

Of course, all that being careful to performance.

How can I do that (maybe in a single clause\statement)?


I know that the update_all method can help someway, but I don't know how to auto-increment position values using that.


I guess what you are looking for in SQL is this?

update articles set position = position - 1 
       where position > pos_of_deleted and user_id = uid_of_deleted

With update_all it should convert to something like this:

Article.update_all("position = position - 1", 
                   ["position > ? and user_id = ?", 
                    pos_of_deleted, uid_of_deleted])

That will pull all positions above the deleted position down one notch..

0

精彩评论

暂无评论...
验证码 换一张
取 消