यह लेख कोरियाई में भी उपलब्ध है, सूनसांग होंग के लिए धन्यवाद!
कार्यक्षेत्र आपके डेटाबेस से सही वस्तुओं को निकालने का एक शानदार तरीका है:
class Review < ActiveRecord::Base
scope :most_recent, -> (limit) { order("created_at desc").limit(limit) }
end
आप इस तरह के दायरे का इस्तेमाल करेंगे:
@recent_reviews = Review.most_recent(5)
उस दायरे को कॉल करना, हालांकि, बिल्कुल दिखता है जैसे Review
. पर क्लास मेथड को कॉल करना . और इसके बजाय इसे एक वर्ग विधि के रूप में बनाना आसान है:
def self.most_recent(limit)
order("created_at desc").limit(limit)
end
@recent_reviews = Review.most_recent(5)
तो आप एक दायरे का उपयोग क्यों करेंगे जब आप नियमित रूबी वर्ग विधियों का उपयोग कर सकते हैं? क्या यह आपके दिमाग में इन पूरी तरह से अलग, लेकिन समकक्ष, अवधारणाओं को रखने लायक है? क्या होगा यदि आप अजीब कीड़े में भाग लेते हैं? क्या यह सब अतिरिक्त चीजें ऐसी चीज नहीं हैं जो रेल को सीखना कठिन बनाती हैं?
जब करेगा क्लास मेथड के बजाय स्कोप का उपयोग करना समझ में आता है?
स्कोप का उपयोग क्यों करें जब हमारे पास पहले से ही वर्ग विधियाँ हैं?
क्या होगा यदि आप किसी विशिष्ट तिथि के बाद लिखी गई सभी समीक्षाओं को प्राप्त करना चाहते हैं? लेकिन अगर कोई तारीख निर्दिष्ट नहीं की गई थी, तो आप सभी चाहते थे इसके बजाय समीक्षाएँ वापस आ गईं?
एक दायरे के रूप में, यह इस तरह दिखता है:
scope :created_since, ->(time) { where("reviews.created_at > ?", time) if time.present? }
काफी आसान है, है ना? कक्षा पद्धति के बारे में क्या?
def self.created_since(time)
if time.present?
where("reviews.created_at > ?", time)
else
all
end
end
इसमें थोड़ा अतिरिक्त काम लगता है। स्कोप स्कोप लौटाना पसंद करते हैं, इसलिए उन्हें एक साथ श्रृंखलाबद्ध करना आसान होता है:
Review.positive.created_since(5.days.ago)
लेकिन वर्ग पद्धति को उसी तरह काम करने के लिए, आपको विशेष रूप से उस मामले को संभालना होगा जहां समय शून्य है। अन्यथा, कॉलर यह पता लगाना होगा कि क्या इसका एक वैध, श्रृंखलाबद्ध दायरा है।
वे विधियां जो हमेशा एक ही तरह की वस्तु लौटाती हैं, वास्तव में उपयोगी होती हैं . आपको किनारे के मामलों या त्रुटियों के बारे में ज्यादा चिंता करने की जरूरत नहीं है। आप मान सकते हैं कि आपको हमेशा एक ऐसी वस्तु वापस दी जाएगी जिसका आप उपयोग कर सकते हैं।
यहां, इसका मतलब है कि आप nil
. के बारे में चिंता किए बिना स्कोप को एक साथ चेन कर सकते हैं मूल्य वापस आ रहे हैं।
अभी भी ऐसे तरीके हैं जिनसे आप इस धारणा को तोड़ सकते हैं कि आपको हमेशा एक गुंजाइश वापस मिल जाएगी:
scope :broken, -> { "Hello!!!" }
irb(main):001:0> Review.broken.most_recent(5)
NoMethodError: undefined method `most_recent' for "Hello!!!":String
लेकिन मैंने ऐसा वास्तविक कोड में कभी नहीं किया है।
स्कोपों के बारे में मुझे जो चीज सबसे ज्यादा पसंद है, वह यह है कि वे इरादे को व्यक्त करते हैं . आप अगले व्यक्ति को बता रहे हैं जो आपका कोड पढ़ता है, "इस विधि को जंजीर से बांधा जा सकता है, अंततः वस्तुओं की सूची में बदल जाएगा, और वस्तुओं के सही सेट का चयन करने में आपकी सहायता करेगा।" यह एक सामान्य वर्ग पद्धति की तुलना में बहुत अधिक है।
आपको स्कोप के बजाय क्लास मेथड का उपयोग कब करना चाहिए?
चूंकि स्कोप आशय व्यक्त करते हैं, इसलिए जब भी मैं सरल, अंतर्निहित स्कोप (जैसे where
का पीछा कर रहा होता हूं, मैं उनका उपयोग करता हूं। और limit
) अधिक जटिल क्षेत्रों में . वस्तुओं के सही समूह को ढूँढ़ना ही स्कोप के लिए डिज़ाइन किया गया था।
दो अपवाद हैं:
- जब मुझे कार्यक्षेत्रों को पहले से लोड करने की आवश्यकता होती है, तो मैं इसके बजाय उन्हें संबद्धता में बदल देता हूं ।
- जब मैं चेन बिल्ट-इन स्कोप से अधिक बड़े स्कोप में करता हूं, तो मैं क्लास मेथड्स का उपयोग करता हूं ।
जब आपका दायरा तर्क जटिल हो जाता है, तो एक वर्ग विधि इसे रखने के लिए सही जगह लगती है।
क्लास मेथड के अंदर, आप रूबी कोड को डेटाबेस कोड के साथ आसानी से मिला सकते हैं। यदि आपके पास रूबी में लिखने के लिए आसान कोड है, तो आप अपनी वस्तुओं को उनके डिफ़ॉल्ट क्रम में पकड़ सकते हैं, और उन्हें सही क्रम में रखने के लिए सॉर्ट_बी का उपयोग कर सकते हैं।
या, यदि आप विशेष रूप से मुश्किल महसूस कर रहे हैं, तो एक वर्ग विधि कुछ अलग स्थानों से डेटा ले सकती है:आपका डेटाबेस, रेडिस, या बाहरी एपीआई या सेवा। फिर, यह उन सभी को वस्तुओं के संग्रह में इकट्ठा कर सकता है जो महसूस एक स्कोप की तरह जिसे एक ऐरे में बदल दिया गया है।
फिर भी, अपने चयन, सॉर्टिंग, जॉइनिंग और फ़िल्टरिंग कोड को दायरे के अंदर रखना अभी भी अच्छा है। फिर, अपने कार्यक्षेत्र का उपयोग अपनी कक्षा पद्धति के अंदर करें। आप एक स्पष्ट वर्ग पद्धति के साथ समाप्त हो जाएंगे, और आप अपने पूरे ऐप में उपयोग कर सकते हैं।
स्कोप मेरी पसंदीदा रेल सुविधाओं में से एक है। आप कुछ शक्तिशाली चीजें कर सकते हैं - विशेष रूप से उपयोगी स्कोप उदाहरण देखने के लिए रेल मॉडल को छांटने और फ़िल्टर करने पर मेरा लेख पढ़ें।
और स्कोप का उपयोग करने में महारत हासिल करने का एक बहुत ही सरल तरीका है:छोटे, केंद्रित ऐप्स के अंदर उनके साथ खेलें। प्रैक्टिसिंग रेल्स का निःशुल्क नमूना अध्याय आपको दिखाएगा कि कैसे। इसे देखें!