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..
精彩评论