Trying to delete all but most recent 10

I have a table where I am trying to delete all but the 10 most recent
records. My code is as follows:

cnotes = Channelnote.find(:all, :order => 'tstamp DESC', :limit =>
10, :conditions => ["deleted=0"])
  Channelnote.delete_all;
  for cnote in cnotes do
    g=cnote.save
  end

However, it deletes ALL records in the table, seeming to NOT write
cnotes back. Can anyone please explain to me why/ Myu log for this is
enclosed below:

Processing AssociateSessionsController#destroy (for 127.0.0.1 at
2009-09-06 17:11:07) [GET]
  Parameters: {"action"=>"destroy",
"controller"=>"associate_sessions"}
  e[4;35;1mAssociate Columns (16.0ms)e[0m e[0mSHOW FIELDS FROM
`associates`e[0m
  e[4;36;1mAssociate Load (0.0ms)e[0m e[0;1mSELECT * FROM
`associates` WHERE (`associates`.`id` = '1') LIMIT 1e[0m
  e[4;35;1mSQL (0.0ms)e[0m e[0mBEGINe[0m
  e[4;36;1mAssociate Update (0.0ms)e[0m e[0;1mUPDATE `associates`
SET `perishable_token` = 'Tz-demkWdZreygqeTVrd', `updated_at` =
'2009-09-06 21:11:07', `last_request_at` = '2009-09-06 21:11:07' WHERE
`id` = 1e[0m
  e[4;35;1mSQL (16.0ms)e[0m e[0mCOMMITe[0m
  e[4;36;1mChannelnote Load (0.0ms)e[0m e[0;1mSELECT * FROM
`channelnotes` WHERE (deleted=0) ORDER BY tstamp DESC LIMIT 10e[0m
  e[4;35;1mChannelnote Delete all (16.0ms)e[0m e[0mDELETE FROM
`channelnotes` e[0m
  e[4;36;1mChannelnote Columns (0.0ms)e[0m e[0;1mSHOW FIELDS FROM
`channelnotes`e[0m
  e[4;35;1mSQL (0.0ms)e[0m e[0mBEGINe[0m
  e[4;36;1mSQL (0.0ms)e[0m e[0;1mCOMMITe[0m
  e[4;35;1mSQL (0.0ms)e[0m e[0mBEGINe[0m
  e[4;36;1mSQL (0.0ms)e[0m e[0;1mCOMMITe[0m
  e[4;35;1mSQL (0.0ms)e[0m e[0mBEGINe[0m
  e[4;36;1mSQL (0.0ms)e[0m e[0;1mCOMMITe[0m
  e[4;35;1mSQL (15.0ms)e[0m e[0mBEGINe[0m
  e[4;36;1mSQL (0.0ms)e[0m e[0;1mCOMMITe[0m
  e[4;35;1mSQL (0.0ms)e[0m e[0mBEGINe[0m
  e[4;36;1mSQL (0.0ms)e[0m e[0;1mCOMMITe[0m
  e[4;35;1mSQL (0.0ms)e[0m e[0mBEGINe[0m
  e[4;36;1mSQL (0.0ms)e[0m e[0;1mCOMMITe[0m
  e[4;35;1mSQL (0.0ms)e[0m e[0mBEGINe[0m
  e[4;36;1mSQL (0.0ms)e[0m e[0;1mCOMMITe[0m
  e[4;35;1mSQL (0.0ms)e[0m e[0mBEGINe[0m
  e[4;36;1mSQL (0.0ms)e[0m e[0;1mCOMMITe[0m
  e[4;35;1mSQL (0.0ms)e[0m e[0mBEGINe[0m
  e[4;36;1mSQL (0.0ms)e[0m e[0;1mCOMMITe[0m
  e[4;35;1mSQL (0.0ms)e[0m e[0mBEGINe[0m
  e[4;36;1mSQL (0.0ms)e[0m e[0;1mCOMMITe[0m
Redirected to http://localhost:3000/
Completed in 406ms (DB: 63) | 302 Found [http://localhost/logout]
  e[4;35;1mSQL (0.0ms)e[0m e[0mSET SQL_AUTO_IS_NULL=0e[0m

More idiomatically --

@cnotes = Channelnote.find(:all, :order => 'tstamp DESC',
      :limit => 10, :conditions => ["deleted=0"])
Channelnote.delete_all;
@cnotes.each { |cnote| cnote.save! }

The save! will let you know why the save failed (failing validation, or...)

Hassan,

Same problem though -- it doesn;t save them back. They just all get
deleted, nothing saved back. Here is my code (all the saves evaluate
to true, btw) and the log:

puts "deleting all but 10 channelnotes"
  @cnotes = Channelnote.find(:all, :order => 'tstamp DESC', :limit =>
10, :conditions => ["deleted=0"])
  Channelnote.delete_all;
  @cnotes.each { |cnote|
  s = cnote.save!
  puts s
  }

Processing AssociateSessionsController#destroy (for 127.0.0.1 at
2009-09-06 20:08:09) [GET]
  Parameters: {"action"=>"destroy",
"controller"=>"associate_sessions"}
  e[4;36;1mAssociate Columns (16.0ms)e[0m e[0;1mSHOW FIELDS FROM
`associates`e[0m
  e[4;35;1mAssociate Load (0.0ms)e[0m e[0mSELECT * FROM `associates`
WHERE (`associates`.`id` = '1') LIMIT 1e[0m
  e[4;36;1mSQL (0.0ms)e[0m e[0;1mBEGINe[0m
  e[4;35;1mAssociate Update (0.0ms)e[0m e[0mUPDATE `associates` SET
`perishable_token` = 'WF_FpyItpFvRCghqAd5W', `updated_at` =
'2009-09-07 00:08:09', `last_request_at` = '2009-09-07 00:08:09' WHERE
`id` = 1e[0m
  e[4;36;1mSQL (0.0ms)e[0m e[0;1mCOMMITe[0m
  e[4;35;1mChannelnote Load (0.0ms)e[0m e[0mSELECT * FROM
`channelnotes` WHERE (deleted=0) ORDER BY tstamp DESC LIMIT 10e[0m
  e[4;36;1mChannelnote Delete all (0.0ms)e[0m e[0;1mDELETE FROM
`channelnotes` e[0m
  e[4;35;1mChannelnote Columns (0.0ms)e[0m e[0mSHOW FIELDS FROM
`channelnotes`e[0m
  e[4;36;1mSQL (0.0ms)e[0m e[0;1mBEGINe[0m
  e[4;35;1mSQL (0.0ms)e[0m e[0mCOMMITe[0m
  e[4;36;1mSQL (0.0ms)e[0m e[0;1mBEGINe[0m
  e[4;35;1mSQL (0.0ms)e[0m e[0mCOMMITe[0m
  e[4;36;1mSQL (0.0ms)e[0m e[0;1mBEGINe[0m
  e[4;35;1mSQL (0.0ms)e[0m e[0mCOMMITe[0m
  e[4;36;1mSQL (0.0ms)e[0m e[0;1mBEGINe[0m
  e[4;35;1mSQL (0.0ms)e[0m e[0mCOMMITe[0m
  e[4;36;1mSQL (0.0ms)e[0m e[0;1mBEGINe[0m
  e[4;35;1mSQL (0.0ms)e[0m e[0mCOMMITe[0m
  e[4;36;1mSQL (0.0ms)e[0m e[0;1mBEGINe[0m
  e[4;35;1mSQL (0.0ms)e[0m e[0mCOMMITe[0m
  e[4;36;1mSQL (16.0ms)e[0m e[0;1mBEGINe[0m
  e[4;35;1mSQL (0.0ms)e[0m e[0mCOMMITe[0m
  e[4;36;1mSQL (0.0ms)e[0m e[0;1mBEGINe[0m
  e[4;35;1mSQL (0.0ms)e[0m e[0mCOMMITe[0m
  e[4;36;1mSQL (0.0ms)e[0m e[0;1mBEGINe[0m
  e[4;35;1mSQL (0.0ms)e[0m e[0mCOMMITe[0m
  e[4;36;1mSQL (0.0ms)e[0m e[0;1mBEGINe[0m
  e[4;35;1mSQL (0.0ms)e[0m e[0mCOMMITe[0m
Redirected to http://localhost:3000/
Completed in 282ms (DB: 32) | 302 Found [http://localhost/logout]

If the save! returns true, it should be good -- what DB are using?
and what version of Rails and db adapter?

Not sure why (or if) save is returning true, but looking at the
program flow, wouldn't Rails try to do an update of each cnote since
they are not new records when they are retrieved? (Rather than an
insert as the OP intends.)

In that case, trying to update a record that no longer exists in the
database should return false but perhaps it doesn't in this case.

Using MySQL 5.0.27 Community Edition, Rails 2.3.2 and MySQL adapter.

Hassan,

Same problem though -- it doesn;t save them back. They just all get
deleted, nothing saved back. Here is my code (all the saves evaluate
to true, btw) and the log:

As of 2.1 rails has support for partial updates - when you do a save
only changed columns are written back. If there were no changes at all
(as in your case) then the save is a no-op. The change tracking
mechanism doesn't know that you've deleted a bunch of rows. There are
methods for saying 'i've changed this attribute' (foo_will_change!)
but there doesn't seem to be one for "I've changed all the attributes,
just save the whole record", although it shouldn't be hard to write
one. You could also play around with turning off partial updates
(perhaps only for the duration of the relevant bit of code)

Fred

Ah, thanks Fred,

Yes, this explains then why my other records are not being saved back
-- I get it (though, this has nothing to do with the partials --
that's a different issue. In this particular issue, I am merely
pruning the table when the user logs off). Thanks! -RVince

RVince wrote:

I have a table where I am trying to delete all but the 10 most recent
records. My code is as follows:

cnotes = Channelnote.find(:all, :order => 'tstamp DESC', :limit =>
10, :conditions => ["deleted=0"])
  Channelnote.delete_all;
  for cnote in cnotes do
    g=cnote.save
  end

This is terrible logic. In another thread, I gave you a sample SQL
query for only deleting the records you actually want deleted. I
strongly suggest that you do it that way instead of deleting everything
and then writing stuff back in.

Best,