2010-10-16 11 views
19

मैं Rails ActiveRecord का उपयोग कर नवीनतम एन रिकॉर्ड के अलावा सभी को कैसे नष्ट कर सकता हूं?रेल सभी नए एन रिकॉर्ड्स को नष्ट कर देते हैं

मैं आदेश और सीमा का उपयोग कर नवीनतम एन रिकॉर्ड प्राप्त कर सकता हूं लेकिन मैं उलटा कैसे नष्ट करूं?

उत्तर

25

इन तरीकों में से या तो यह करना होगा है:

# 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

रेल 4.2.0 में आपको एआर ऑब्जेक्ट को सही संदेश भेजना होगा: 'Foo.all.order (' create_at DESC ')। सीमा (एन) ' – borjagvo

+0

ध्यान दें कि यह एक [ActiveRecord :: Relation] (http: //apidock.com/rails/ActiveRecord/Relation/destroy_all) क्योंकि यह 'शर्तों' स्वीकार करता है। यह ActiveRecord :: CollectionProxy पर काम नहीं करेगा क्योंकि 'destruction_all' विधि केवल तर्क के बिना' @ association.destroy_all' चलाती है। (https://github.com/rails/rails/blob/58772397e9b790e80bcd4d8e51937dc82ecb719e/activerecord/lib/active_record/associations/collection_proxy.rb#L504-L506) संग्रहप्रॉक्सी के लिए 'destruction_all' में तर्कों का उपयोग करने का प्रयास करने से 'ArgumentError' अपवाद। – anothermh

4

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

यह सभी व्यक्तियों को जो शर्त को पूरा नष्ट कर देगा। तो आप सभी की जरूरत उल्टे स्थिति और destroy_all

+1

मेरे लिए काम किया है, और अगर आप अपने मॉडल चल कॉलबैक और संगठनों के बारे में चिंतित नहीं हैं, तो आप 'delete_all' कॉल कर सकते हैं बजाय एक ही SQL DELETE स्थिति में ऐसा करने के लिए 'destruction_all' का प्रत्येक रिकॉर्ड के लिए एक मॉडल ऑब्जेक्ट को तुरंत चालू करने के लिए ment। –

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

पिछला जवाब का उपयोग find या last ActiveModel के निर्माण, जो अतिरिक्त गणना समय लेने की आवश्यकता है।

मुझे लगता है कि pluck का उपयोग करना बेहतर है, क्योंकि यह केवल आईडी के ऐरे बनाता है।

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

मैं यह कर रहा, यह मानते हुए के दो तरीके है एन = 5:

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

यह पहली नवीनतम के साथ रिकॉर्ड सॉर्ट करता, और पिछले 5 वीं रिकॉर्ड सब कुछ नष्ट कर देता है। या

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

यह 6 नवीनतम रिकॉर्ड आईडी पाता है और आईडी < = 6 नवीनतम रिकॉर्ड आईडी के साथ सभी रिकॉर्ड को हटाता है।

इसके अलावा, आप इस SO question को देखना चाहेंगे।

+0

'.offset' का उपयोग करके अच्छा विचार। धन्यवाद! – dgilperez

+0

यहां अधिकांश रेल का समाधान, धन्यवाद! – Dan

0

[रेल 5/ActiveRecord :: रिलेशन]

destroy_all नहीं रह गया है पैरामीटर लेता है ... वास्तव में, ActiveRecord :: रिलेशन की अनुमति कभी नहीं मानकों मुझे लगता है कि नहीं है ... वैसे भी, तुम सिर्फ चाहिए यह पहले शर्त रख दिया है, लेकिन destroy_all के बाद क्वेरी का उपयोग, इस तरह:

Person.destroy_all("last_login < '2004-04-04'") 
Person.destroy_all(status: "inactive") 
Person.where(age: 0..18).destroy_all 
संबंधित मुद्दे