views:

54

answers:

5

Hi,

How can I set all records to 0 in a table? -- UPDATE -- What I want to do is the following. I have a table called Pages with an attributed called position. When I delete page from the table i want som function to reorder the positions, so that there wont be any not used positions.

EX. Position 1, 2, 4, 8, 9, 12 becomes 1, 2, 3, 4, 5, 6

A: 

Model.all.map { |m| m.field = 0 }.save!

However this will create as many requests as records you have, so in case you have lots or records I'd suggest to use something like this.

fantactuka
+2  A: 
Kalyan M
This should be wrapped in a transaction or you will end up with duplicate positions when it runs in more than one process at once!
Joel Hoffman
A: 

If you're using the acts_as_list plugin, it should deal with the renumbering of positions automatically.

Andrew Vit
A: 

To answer your first question,

Pages.update_all(:position => 0)

One way to update the position array when a position is deleted is in a before_destroy callback. This is reliable only if Rails' destroy method is the only way records are deleted!

def decrement_positions
  Pages.update_all('position = position - 1', ['position > ?', position])
end

before_destroy :decrement_positions

One race-condition free way to set all positions to adjacent values at once would be to drop into SQL:

Pages.update_all('position = 1 + (select count(1) from pages p where p.position < pages.position)')
Joel Hoffman
A: 

I would think using the plugin acts_as_list, like Andrew suggested, is a good idea if you need all the features, otherwise, I would just setup an after_destroy filter.

after_destroy :fix_order
def fix_order
  Page.order('position asc').all.each_with_index do |page, index|
    page.update_attribute(:position, index + 1) unless page.position == index + 1
  end
end
danengle