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