Computer >> कंप्यूटर ट्यूटोरियल >  >> प्रोग्रामिंग >> Ruby

Rails में Scopes बनाम क्लास मेथड: कौन सा दृष्टिकोण जीतता है?

यह लेख कोरियाई में भी उपलब्ध है, सूनसांग हॉन्ग का धन्यवाद!

Scopes आपके डेटाबेस से सही ऑब्जेक्ट निकालने का एक शानदार तरीका है:

app/models/review.rb
class Review < ActiveRecord::Base scope :most_recent, -> (limit) { order("created_at desc").limit(limit) } end 

आप scope का उपयोग इस तरह करेंगे:

app/models/homepage_controller.rb
@recent_reviews = Review.most_recent(5) 

उस scope को कॉल करना, हालांकि, Review पर एक नियमित रूबी क्लास मेथड को कॉल करने की तरह बिल्कुल दिखता है। और इसे क्लास मेथड के रूप में बनाना भी आसान है:

app/models/review.rb
def self.most_recent(limit) order("created_at desc").limit(limit) end 

app/controllers/homepage_controller.rb
@recent_reviews = Review.most_recent(5) 

तो जब आप नियमित रूबी क्लास मेथड का उपयोग कर सकते हैं तो scope का उपयोग क्यों करेंगे? क्या इन पूरी तरह से अलग, लेकिन समतुल्य, अवधारणाओं को अपने दिमाग में रखना उचित है? क्या होगा यदि आप अजीब बग में पड़ जाते हैं? क्या यह अतिरिक्त सामान वही नहीं है जो Rails को सीखना कठिन बनाता है?

कब scope के बजाय क्लास मेथड का उपयोग करना समझ में आएगा?

जब हमारे पास पहले से ही क्लास मेथड हैं तो scopes का उपयोग क्यों करें?

क्या होगा यदि आप किसी विशिष्ट तिथि के बाद लिखी गई सभी समीक्षाओं को प्राप्त करना चाहते हैं? लेकिन अगर कोई तिथि निर्दिष्ट नहीं की गई थी, तो आप सभी समीक्षाएं वापस करना चाहते थे?

एक scope के रूप में, यह इस तरह दिखता है:

app/models/review.rb
scope :created_since, ->(time) { where("reviews.created_at > ?", time) if time.present? } 

आसान है, है ना? क्लास मेथड के बारे में क्या?

app/models/review.rb
def self.created_since(time) if time.present? where("reviews.created_at > ?", time) else all end end 

इसमें थोड़ा अतिरिक्त काम लगता है। Scopes scopes वापस करना पसंद करते हैं, इसलिए उन्हें एक साथ चेन करना आसान है:

Review.positive.created_since(5.days.ago) 

लेकिन क्लास मेथड को उसी तरह काम करने के लिए, आपको विशेष रूप से उस मामले को संभालना होगा जहां time nil है। अन्यथा, कॉलर को यह पता लगाना होगा कि उसके पास एक वैध, चेनेबल scope है या नहीं।

मेथड जो हमेशा उसी प्रकार का ऑब्जेक्ट वापस करते हैं, वास्तव में उपयोगी होते हैं। आपको एज केस या त्रुटियों के बारे में ज्यादा चिंता करने की ज़रूरत नहीं है। आप मान सकते हैं कि आपको हमेशा एक ऑब्जेक्ट वापस मिलेगा जिसका आप उपयोग कर सकते हैं।

यहां, इसका मतलब है कि आप scopes को एक साथ चेन कर सकते हैं, बिना nil मान वापस आने की चिंता किए।

ऐसे तरीके अभी भी हैं जिनसे आप यह धारणा तोड़ सकते हैं कि आपको हमेशा एक scope वापस मिलेगा:

app/models/review.rb
scope :broken, -> { "Hello!!!" } 

irb(main):001:0> Review.broken.most_recent(5) NoMethodError: undefined method `most_recent' for "Hello!!!":String 

लेकिन वास्तविक कोड में ऐसा कभी नहीं हुआ।

मुझे scopes के बारे में सबसे ज्यादा पसंद यह है कि वे इरादा व्यक्त करते हैं। आप अपने कोड को पढ़ने वाले अगले व्यक्ति को बता रहे हैं, "यह मेथड चेनेबल है, अंततः ऑब्जेक्ट्स की एक सूची में बदल जाएगा, और आपको ऑब्जेक्ट्स का सही सेट चुनने में मदद करेगा।" यह एक सामान्य क्लास मेथड से कहीं अधिक कहता है।

क्लास मेथड के बजाय scope का उपयोग कब करना चाहिए?

क्योंकि scopes इरादा व्यक्त करते हैं, मैं उनका उपयोग तब करता हूं जब मैं सरल, बिल्ट-इन scopes (जैसे where और limit) को अधिक जटिल scopes में चेन कर रहा हूं। ऑब्जेक्ट्स का सही समूह ढूंढना वही है जिसके लिए scopes डिज़ाइन किए गए थे।

दो अपवाद हैं:

  1. जब मुझे scopes को प्रीलोड करने की आवश्यकता होती है, तो मैं उन्हें associations में बदल देता हूं।
  2. जब मैं बिल्ट-इन scopes को बड़े scopes में चेन करने से अधिक करता हूं, तो मैं क्लास मेथड का उपयोग करता हूं।

जब आपका scope तर्क जटिल हो जाता है, तो क्लास मेथड इसे रखने के लिए सही जगह की तरह लगता है।

क्लास मेथड के अंदर, आप रूबी कोड को डेटाबेस कोड के साथ आसानी से मिला सकते हैं। अगर आपके पास सॉर्टिंग कोड है जिसे रूबी में लिखना आसान है, तो आप अपने ऑब्जेक्ट्स को उनके डिफ़ॉल्ट क्रम में ले सकते हैं, और उन्हें सही क्रम में रखने के लिए sort_by का उपयोग कर सकते हैं।

या, यदि आप विशेष रूप से चालाक महसूस कर रहे हैं, तो एक क्लास मेथड कुछ अलग-अलग स्थानों से डेटा ले सकता है: आपका डेटाबेस, Redis, या एक बाहरी API या सेवा। फिर, यह उन सभी को ऑब्जेक्ट्स के एक संग्रह में इकट्ठा कर सकता है जो महसूस होता है जैसे एक scope जिसे एक सरणी में बदल दिया गया हो।

तब भी, अपने चयन, सॉर्टिंग, जॉइनिंग और फ़िल्टरिंग कोड को scopes के अंदर रखना अच्छा है। फिर, अपने क्लास मेथड के अंदर अपने scopes का उपयोग करें। आप एक स्पष्ट क्लास मेथड और scopes के साथ समाप्त होंगे जिन्हें आप अपने ऐप में पूरे उपयोग कर सकते हैं।

Scopes मेरी पसंदीदा Rails सुविधाओं में से एक हैं। आप कुछ शक्तिशाली चीजें कर सकते हैं - Rails मॉडल को सॉर्ट और फ़िल्टर करने पर मेरा लेख पढ़ें एक विशेष रूप से उपयोगी scope उदाहरण देखने के लिए।

और scopes का उपयोग करने में महारत हासिल करने का एक बहुत सरल तरीका है: उन्हें छोटे, केंद्रित ऐप्स के अंदर आज़माएं। Practicing Rails का मुफ्त नमूना अध्याय आपको दिखाएगा कि कैसे। इसे देखें!

  1. रूबी एरे में महारत: व्यावहारिक उदाहरण और आवश्यक मेथड्स रूबी एरे में महारत: व्यावहारिक उदाहरण और आवश्यक मेथड्स

    एरे क्या है? एक एरे रूबी में एक बिल्ट-इन क्लास है, जो शून्य या अधिक आइटम्स की सूची रखती है, और इसमें ऐसे मेथड्स शामिल हैं जो आपको इन सभी आइटम्स को आसानी से जोड़ने, एक्सेस करने और लूप करने में मदद करते हैं। यह उपयोगी है, क्योंकि यदि एरे मौजूद नहीं होते तो आपको कई वेरिएबल्स का उपयोग करना पड़ता। उदाहरण

  1. डबल VPN: यह कैसे काम करता है और कब इसका उपयोग करें डबल VPN: यह कैसे काम करता है और कब इसका उपयोग करें

    ऑनलाइन गोपनीयता और सुरक्षा से संबंधित बढ़ती समस्याओं का मुकाबला करने के लिए सुरक्षा समाधानों और बुनियादी ढांचे की अधिकता का निर्माण किया गया है, इसमें प्रमुख रूप से VPN और डबल VPN शामिल हैं हमने पहले ही सर्वश्रेष्ठ VPN समाधान और उनकी कार्यक्षमताओं पर विस्तार से चर्चा की है। (यदि आप सर्वश्रेष्ठ VPN

  1. Firefox क्यों आपकी रोजमर्रा की जरूरतों के लिए बेहतर ब्राउज़र विकल्प है Firefox क्यों आपकी रोजमर्रा की जरूरतों के लिए बेहतर ब्राउज़र विकल्प है

    मैं लगभग पंद्रह साल से Firefox का उपयोग कर रहा हूं, कम या ज्यादा। उस अवधि के दौरान, मैंने इसे एक सुंदर परियोजना में विकसित होते देखा है, अद्भुत एक्सटेंशन की दुनिया बनते देखा है, और फिर धीरे-धीरे सिकुड़ते और फीके पड़ते देखा है क्योंकि इसने वही किया जो प्रतियोगी करते हैं, उन मुख्य लाभों को खो दिया जो