मैं अपने मॉडल में एक डिफ़ॉल्ट सॉर्ट क्रम निर्दिष्ट करना चाहूंगा।
ताकि जब मैं इसे .where()
निर्दिष्ट किए बिना करूं तो .order()
यह डिफ़ॉल्ट प्रकार का उपयोग करता है। लेकिन अगर मैं एक निर्दिष्ट करता हूं .order()
, तो यह डिफ़ॉल्ट को ओवरराइड करता है।
मैं अपने मॉडल में एक डिफ़ॉल्ट सॉर्ट क्रम निर्दिष्ट करना चाहूंगा।
ताकि जब मैं इसे .where()
निर्दिष्ट किए बिना करूं तो .order()
यह डिफ़ॉल्ट प्रकार का उपयोग करता है। लेकिन अगर मैं एक निर्दिष्ट करता हूं .order()
, तो यह डिफ़ॉल्ट को ओवरराइड करता है।
जवाबों:
default_scope
यह रेल 4+ के लिए काम करता है:
class Book < ActiveRecord::Base
default_scope { order(created_at: :desc) }
end
रेल 2.3, 3 के लिए, आपको इसके बजाय इसकी आवश्यकता है:
default_scope order('created_at DESC')
रेल के लिए 2.x:
default_scope :order => 'created_at DESC'
created_at
वह क्षेत्र है जहां आप चाहते हैं कि डिफ़ॉल्ट छँटाई हो।
नोट: ASC , आरोही के लिए उपयोग करने के लिए कोड है और DESC अवरोही ( desc
, नहीं) के लिए है dsc
!) के लिए है।
scope
एक बार आपके द्वारा उपयोग किए जाने के बाद आप इसका उपयोग भी कर सकते हैं scope
:
class Book < ActiveRecord::Base
scope :confirmed, :conditions => { :confirmed => true }
scope :published, :conditions => { :published => true }
end
रेल 2 के लिए आपको चाहिए named_scope
।
:published
गुंजाइश आपको देता है Book.published
के बजाय
Book.find(:published => true)
।
3 रेल के बाद से आप उन तरीकों को एक साथ 'चेन' कर सकते हैं, उन्हें उनके बीच की अवधि के साथ समेट कर, इसलिए उपरोक्त स्कोप के साथ आप उनका उपयोग नहीं कर सकते हैं Book.published.confirmed
।
इस पद्धति के साथ, क्वेरी को वास्तव में निष्पादित नहीं किया जाता है जब तक कि वास्तविक परिणामों की आवश्यकता नहीं होती है (आलसी मूल्यांकन), इसलिए 7 स्कोप को एक साथ जंजीर किया जा सकता है लेकिन केवल 1 वास्तविक डेटाबेस क्वेरी के परिणामस्वरूप, प्रदर्शन समस्याओं से बचने के लिए 7 अलग-अलग प्रश्नों को निष्पादित करने से बचें।
आप एक पारित पैरामीटर का उपयोग कर सकते हैं जैसे कि एक तारीख या एक user_id (कुछ ऐसा जो रन-टाइम में बदल जाएगा और इसलिए इस तरह के 'आलसी मूल्यांकन' की आवश्यकता होगी, एक लंबोदर के साथ, इस तरह:
scope :recent_books, lambda
{ |since_when| where("created_at >= ?", since_when) }
# Note the `where` is making use of AREL syntax added in Rails 3.
अंत में आप के साथ डिफ़ॉल्ट गुंजाइश को अक्षम कर सकते हैं:
Book.with_exclusive_scope { find(:all) }
या इससे भी बेहतर:
Book.unscoped.all
जो किसी भी फ़िल्टर (शर्तों) या सॉर्ट (ऑर्डर द्वारा) को अक्षम कर देगा।
ध्यान दें कि पहला संस्करण Rails2 + में काम करता है जबकि दूसरा (अनकैप्ड) Rails3 + के लिए ही है
तो
... अगर आप सोच रहे हैं, हम्म, तो ये सिर्फ तरीकों की तरह हैं ..., हाँ, यह वही है जो ये स्कोप हैं!
वे होने की तरह हैं, def self.method_name ...code... end
लेकिन हमेशा माणिक के साथ वे आपके लिए चीजों को आसान बनाने के लिए छोटे वाक्यविन्यास शॉर्टकट (या 'चीनी') हैं!
वास्तव में वे कक्षा स्तर के तरीके हैं क्योंकि वे 'सभी' रिकॉर्ड के 1 सेट पर काम करते हैं।
उनका प्रारूप हालांकि बदल रहा है, रेल 4 के साथ एक कॉल करने योग्य वस्तु को पारित किए बिना # सीप का उपयोग करते समय पदावनति की चेतावनी है। उदाहरण के लिए गुंजाइश: लाल, जहां (रंग: 'लाल') को बदल दिया जाना चाहिएscope :red, -> { where(color: 'red') }
।
साइड नोट के रूप में, जब गलत तरीके से उपयोग किया जाता है, तो डिफ़ॉल्ट _scope का दुरुपयोग / दुरुपयोग किया जा सकता है।
यह मुख्य रूप से तब होता है जब इसका उपयोग केवल परिणामों को क्रमबद्ध करने के बजाय डिफ़ॉल्ट चयन ( डिफ़ॉल्ट के लिए एक बुरा विचारwhere
) को सीमित करने (फ़िल्टर करने) जैसी क्रियाओं के लिए किया जाता है ।
के लिए चयन, बस नियमित नामित स्कोप का उपयोग करें। और क्वेरी में उस स्कोप को जोड़ें, जैसे कि नामांकित स्कोप।where
Book.all.published
published
अंत में, स्कोप वास्तव में बहुत अच्छे हैं और आपको एक 'वसा मॉडल पतली नियंत्रक' DRYer दृष्टिकोण के लिए मॉडल में चीजों को पुश करने में मदद करते हैं।
default_scope { order("#{table_name}.created_at DESC") }
?
default_scope { order(created_at: :desc) }
4.2.6
के आधार पर सॉर्ट करने लगता है updated_at
नहीं created_at
।
updated_at
डिफ़ॉल्ट रूप से क्यों छाँटें ? : - |
ऊपर माइकल के उत्कृष्ट उत्तर के लिए एक त्वरित अपडेट।
रेल 4.0 के लिए आपको अपने ब्लॉक को इस तरह लगाना होगा:
class Book < ActiveRecord::Base
default_scope { order('created_at DESC') }
end
ध्यान दें कि आदेश विवरण घुंघराले ब्रेसिज़ द्वारा चिह्नित एक ब्लॉक में रखा गया है।
उन्होंने इसे बदल दिया क्योंकि यह कुछ गतिशील (वर्तमान समय की तरह) में पारित करना बहुत आसान था। यह समस्या को दूर करता है क्योंकि ब्लॉक का मूल्यांकन रनटाइम पर किया जाता है। यदि आप किसी ब्लॉक का उपयोग नहीं करते हैं तो आपको यह त्रुटि मिलेगी:
बिना किसी ब्लॉक के #default_scope को कॉल करने का समर्थन हटा दिया गया है। उदाहरण के लिए
default_scope where(color: 'red')
, कृपया उपयोग करेंdefault_scope { where(color: 'red') }
। (वैकल्पिक रूप से आप बस self.default_scope को फिर से परिभाषित कर सकते हैं।)
जैसा कि @Dan ने अपनी टिप्पणी में उल्लेख किया है, आप इस तरह से अधिक रूखे वाक्य रचना कर सकते हैं:
class Book < ActiveRecord::Base
default_scope { order(created_at: :desc) }
end
या कई स्तंभों के साथ:
class Book < ActiveRecord::Base
default_scope { order({begin_date: :desc}, :name) }
end
धन्यवाद @ दान !
default_scope { order(created_at: :desc) }
कि, मेरी तरह, आप रेल सिंटैक्स को रेल में कम करने की कोशिश करते हैं। <br/> यदि आपके पास ऑर्डर करने के लिए कई कॉलम हैं और आप नए सिंटैक्स का उपयोग करना चाहते हैं, तो आपको डीईसी को लपेटने की आवश्यकता हो सकती है। इस तरह मूंछों में कॉलमdefault_scope { order({begin_date: :desc}, :name) }
आप डिफ़ॉल्ट प्रकार के आदेश को लागू करने के लिए default_scope का उपयोग कर सकते हैं http://api.rubyonrails.org/classes/ActiveRecord/Scoping/Default/ClassMethods.html
default_scope
उस पृष्ठ के , क्योंकि इसे ( api.rubyonrails.org/classes/ActiveRecord/Scoping/Default/… ) ActiveRecord::Base
में से दर्शाया गया हैActiveRecord::Scoping::Default::ClassMethods