2010-10-16 15 views

cevap

25

geçerli:

# Fetch your latest N records 
newest_n_records = Foo.find(:all, :order => 'created_at DESC', :limit => n) 

# Then do: 
Foo.destroy_all(['id NOT IN (?)', newest_n_records.collect(&:id)]) 

# Or: 
Foo.destroy_all('created_at < ?', newest_n_records.last.created_at) 
+0

Rails 4.2.0'da AR nesnesine doğru mesajı göndermeniz gerekir: 'Foo.all.order ('created_at DESC'). Limit (n)' – borjagvo

+0

Bunun bir [ActiveRecord :: Relation] üzerinde çalışacağını unutmayın (http: //apidock.com/rails/ActiveRecord/Relation/destroy_all) çünkü koşulları kabul ediyor. Bir ActiveRecord :: CollectionProxy üzerinde çalışmaz, çünkü 'destroy_all' yöntemi argümanlar olmadan sadece 'association.destroy_all 'çalışır. (https://github.com/rails/rails/rails/blob/58772397e9b790e80bcd4d8e51937dc82ecb719e/activerecord/lib/active_record/associations/collection_proxy.rb#L504-L506) CollectionProxy için 'destroy_all' argümanlarını kullanmaya çalışmak bir 'ArgumentError' artacaktır. istisna. – anothermh

4

Person.destroy_all("last_login < '2004-04-04'")

Bu şartı yerine herkesi yok edecek. Yani tek ihtiyacınız bu yöntemlerin Ya yapacağını ters koşulları ve destroy_all

+1

ve size modeli çalıştıran geri aramaları ve dernekler hakkında endişeli değilseniz, bunun yerine delete_all' 'çağırabilir tek bir SQL DELETE durumunda bunu yok destroy_all Her kayıt için bir model nesnesinin oluşturulmasını kaydetmek için ment. –

6
Foo.destroy_all(['id NOT IN (?)', Foo.last(1000).collect(&:id)]) 
0

Önceki cevaplar find veya last ekstra hesaplama zaman ayırın ActiveModel oluşturulmasını gerektirir kullanın.

pluck kullanmak daha iyidir, çünkü yalnızca bir Dizi dizisi oluşturur.

ids = Foo.limit(n).order('id DESC').pluck(:id) 
Foo.where('id NOT IN (?)', ids).destroy_all 
13

Ben, bunu varsayarak iki yöntem vardır n = 5:

Foo.order('id desc').offset(5).destroy_all 

bu ilk en son kayıtları sıralar ve 5 kayıtların geçmiş her şeyi yok eder. Ya

Foo.destroy_all(['id <= ?', Foo.order('id desc').limit(1).offset(5).first.id]) 

Bu 6 son rekor id bulur ve kimliği < = 6, en son kayıt kimliği ile tüm kayıtları siler.

Ayrıca, bu SO question'a bakmak isteyebilirsiniz.

+0

'.offset' kullanarak güzel bir fikir. Teşekkürler! – dgilperez

+0

En Rails'y çözümü burada, teşekkürler! – Dan

0

[Raylar 5/ActiveRecord :: İlişkisi]

destroy_all artık parametre alır ... Aslında ActiveRecord :: İlişkisi asla izin parametreleri ben neyse ... sanmıyorum, sadece gerektiği ondan önce koşulunu koydu ama destroy_all sonra sorguyu kullanın, örneğin: benim için çalıştı

Person.destroy_all("last_login < '2004-04-04'") 
Person.destroy_all(status: "inactive") 
Person.where(age: 0..18).destroy_all 
İlgili konular