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

आपका रेल्स कोड कहां जाता है? नॉन-CRUD लॉजिक को व्यवस्थित करना

रेल्स ट्यूटोरियल्स खत्म करने और अपना खुद का ऐप शुरू करने के बाद, चीजें भ्रमित हो जाती हैं। जैसे आपका नॉन-CRUD, सामान्य लॉजिक कहां जाता है? ट्विटर से फॉलोअर्स लेना MVC में कैसे फिट बैठता है? दो लोगों से पूछें, और आपको चार उत्तर मिलेंगे। या आपका थ्रेड घंटों तक एक-दूसरे का अपमान करने वाले स्मार्ट लोगों में बदल जाता है, जबकि आप अपना सिर डेस्क पर पीटते हैं। किसी भी तरह, आपको सिरदर्द रह जाता है।

आप कुछ सामान्य, नॉन-रेल्स लॉजिक के बिना वह ऐप नहीं बना सकते जिसका आप सपना देख रहे हैं। तो आप अपना कोड कहां रखते हैं, और फिर भी चीजों को सरल रखते हैं?

शुरू करने के लिए आसान जगह

जब मेरे पास लॉजिक होता है जो मौजूदा एक्टिवरिकॉर्ड मॉडल से संबंधित महसूस होता है, तो मैं इसे उस मॉडल में रखकर शुरू करूंगा। उदाहरण के लिए, अगर मेरे पास एक Game मॉडल होता और मैं CSV फाइलों से गेम्स का एक समूह आयात करना चाहता, तो मैं उस मेथड को सीधे Game क्लास पर रखूंगा:

app/models/game.rb
class Game < ActiveRecord::Base
  def self.parse_from_csv(csv_string)
    games = []
    CSV.parse(csv_string, quote_char: "'") do |row|
      games << Game.from_csv_row(row) if (row[0] == 'G')
    end
    games
  end

  def self.from_csv_row(row)
    Game.new({
      dgs_game_id: row[1],
      opponent_name: row[2],
      created_at: row[4],
      updated_at: row[4],
    })
  end
end

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

लेकिन अगर आप उस मॉडल को जोड़ते और बदलते रहते हैं, तो यह बड़ा और जटिल हो जाएगा। मॉडल के विभिन्न भाग अजीब तरीकों से इंटरैक्ट करेंगे। जितना अधिक आप इसे बदलते हैं, उतना ही कठिन इसे बदलना होगा।

उस स्थिति में, आप शायद उस कोड को नॉन-एक्टिवरिकॉर्ड मॉडल में रीफैक्टर करना चाहेंगे।

नॉन-एक्टिवरिकॉर्ड मॉडल्स

सिर्फ इसलिए कि यह एक रेल्स ऐप में है, इसका मतलब यह नहीं है कि इसे एक्टिव/एक्शन-जो भी से विरासत में मिलना होगा।

आप अपना खुद का रूबी कोड, प्लेन रूबी ऑब्जेक्ट्स में लिख सकते हैं, और उन्हें अपने रेल्स ऐप में उपयोग कर सकते हैं। इन ऑब्जेक्ट्स को अभी भी मॉडल्स कहा जा सकता है, क्योंकि वे आपकी समस्या के एक हिस्से को मॉडल कर रहे हैं। उनके पास बस उनके डेटा को स्टोर करने वाला एक्टिवरिकॉर्ड डेटाबेस नहीं है।

अगली बार जब मैंने उस गेम CSV पार्सर पर काम किया, तो Game क्लास थोड़ी बहुत बड़ी हो रही थी। इसलिए मैंने पार्सर लॉजिक को अपनी खुद की GameCSVParser क्लास में स्थानांतरित कर दिया।

पूरा कमिट यहां है, लेकिन यह है कि नॉन-एक्टिवरिकॉर्ड क्लास कैसी दिखती है:

app/models/game_csv_parser.rb
class GameCSVParser
  def initialize(csv_string)
    @rows = CSV.parse(csv_string, quote_char: "'")
  end

  def games
    game_rows.map { |row| Game.new(game_attributes(row)) }
  end

  private

  def game_rows
    @rows.select { |row| is_game_row?(row) }
  end

  def game_attributes(row)
    {
      dgs_game_id: row[1],
      opponent_name: row[2],
      created_at: row[4],
      updated_at: row[4],
    }
  end

  def is_game_row?(row)
    row[0] == 'G'
  end
end

मैं सीधे एक नया प्लेन रूबी ऑब्जेक्ट बनाने जाऊंगा यदि मैं जो लॉजिक जोड़ रहा हूं वह किसी विशिष्ट एक्टिवरिकॉर्ड मॉडल से संबंधित महसूस नहीं होता। या अगर कोड ऐसा लगता है कि यह किसी ऐसी चीज का हिस्सा होना चाहिए जो अभी तक ऐप में मौजूद नहीं है। अन्यथा, वे ज्यादातर रीफैक्टरिंग के माध्यम से सामने आते हैं।

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

बहुत सारे रेल्स ऐप्स प्लेन रूबी ऑब्जेक्ट्स की समान कैटेगरीज़ का उपयोग करते हैं। ये पैटर्न हैं जिनका पालन करके आप कोड लिख सकते हैं जिसे अन्य डेवलपर्स पहचानेंगे। आपने उनमें से कुछ के बारे में पहले ही सुना होगा।

सर्विस ऑब्जेक्ट्स, प्रेजेंटर्स, और जॉब्स

सर्विस ऑब्जेक्ट्स, प्रेजेंटर्स, और जॉब्स के बारे में कुछ खास नहीं है। वे सिर्फ प्लेन रूबी ऑब्जेक्ट्स हैं जो एक विशेष पहचानने योग्य तरीके से कार्य करते हैं।

उदाहरण के लिए, एक रेस्क्यू जॉब एक प्लेन रूबी क्लास है जिसमें एक perform मेथड और एक @queue होता है:

app/workers/fetch_games_for_player.rb
class FetchGamesForPlayer
  @queue = :default
  def self.perform(player_id)
    player = Player.scoped_by_id(player_id).ready_for_fetching.first
    player && player.fetch_new_games!
  end
end

perform तब कॉल किया जाता है जब जॉब चलाया जाता है।

एक प्रेजेंटर एक प्लेन रूबी ऑब्जेक्ट है जिसमें कोड होता है जो केवल व्यू के अंदर समझ में आता है:

app/presenters/user_presenter.rb
class UserPresenter
  def show_related_users?
    @user.related.count > 3
  end
end

यह रेल्स के व्यू हेल्पर्स को भी शामिल कर सकता है, या कुछ अलग ऑब्जेक्ट्स ले सकता है और उन्हें व्यू की सुविधा के लिए एक एकीकृत ऑब्जेक्ट के रूप में मान सकता है।

एक सर्विस ऑब्जेक्ट एक प्लेन रूबी ऑब्जेक्ट है जो एक प्रक्रिया का प्रतिनिधित्व करता जिसे आप करना चाहते हैं। उदाहरण के लिए, एक पोस्ट पर कमेंट लिखना हो सकता है:

  1. कमेंट छोड़ें।
  2. पोस्ट के लेखक को एक नोटिफिकेशन मेल भेजें।

एक सर्विस ऑब्जेक्ट दोनों कर सकता है, और उस लॉजिक को आपके कंट्रोलर से बाहर रख सकता है।

सर्विस ऑब्जेक्ट्स पर एक बेहतरीन लेख यहां है। यह उदाहरणों से भरा है।

सरल प्रक्रियाओं के लिए, मैं सर्विस ऑब्जेक्ट्स की जहमत नहीं उठाता। लेकिन अगर कंट्रोलर बहुत भारी होने लगे, तो वे उस अतिरिक्त लॉजिक को रखने के लिए एक अच्छी जगह हैं।

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

आप कहां से शुरू करते हैं?

आपके नॉन-रेल्स बिजनेस लॉजिक के लिए बहुत सारी अलग-अलग जगहें हैं। चुनना कठिन हो सकता है। तो यहां मैं क्या करता हूं:

  1. यदि लॉजिक ज्यादातर किसी मौजूदा क्लास से संबंधित है, भले ही वह एक्टिवरिकॉर्ड मॉडल हो, तो मैं इसे उस क्लास में रखता हूं।
  2. यदि यह किसी मौजूदा क्लास में फिट नहीं होता, तो मैं लॉजिक को रखने के लिए एक नया प्लेन रूबी क्लास बनाता हूं।
  3. यदि ऐसा लगता है कि लॉजिक किसी ऐसी चीज का हिस्सा होना चाहिए जो अभी तक मौजूद नहीं है, तो मैं इसके लिए एक नया प्लेन रूबी क्लास बनाता हूं।
  4. यदि मैं बाद में कोड पर वापस आता हूं, और मॉडल बहुत जटिल हो रहा है, या कोड अब उस मॉडल में समझ में नहीं आता, तो मैं इसे अपने खुद के प्लेन रूबी क्लास में रीफैक्टर करूंगा।
  5. यदि कोड केवल व्यू में समझ में आता है, तो मैं इसे हेल्पर में जोड़ूंगा या एक प्रेजेंटर बनाऊंगा।
  6. यदि कोड को HTTP रिक्वेस्ट के दौरान चलने की आवश्यकता नहीं है, या पृष्ठभूमि में चलना है, तो यह जॉब में जाता है।
  7. यदि मैं कई अलग-अलग मॉडल्स या प्रक्रिया के चरणों को संभाल रहा हूं, और यह कंट्रोलर को समझने में बहुत कठिन बना रहा है, तो मैं इसे सर्विस ऑब्जेक्ट में डालूंगा।

आपके बारे में क्या? आपका कोड कहां जाता है? और क्या इनके अलावा कोई पैटर्न हैं जो आपने मददगार पाए हैं? एक कमेंट छोड़ें और मुझे बताएं।

और यदि आपके पास अभी तक कोई प्रक्रिया नहीं है, तो मेरा प्रयास करें। देखें कि यह आपको कैसे फिट बैठता है। कोड लिखने का कोई सही तरीका नहीं है, लेकिन जब आप अटक जाते हैं, तो इस तरह की प्रक्रिया आपको शुरू करने में मदद करेगी।

  1. आपका फोन कहां से आता है? आपका फोन कहां से आता है?

    आपका फोन शायद आपसे ज्यादा देशों में गया है। ऐसा इसलिए है क्योंकि इसमें आवर्त सारणी के आपसे ज्यादा टुकड़े हैं: एक अध्ययन में पाया गया कि औसत स्मार्टफोन में आवर्त सारणी के 83 स्थिर, गैर-रेडियोधर्मी तत्वों में से लगभग 62 अलग-अलग तत्व होते हैं, जबकि मानव शरीर में पहचाने जाने योग्य केवल ग्यारह नॉन-ट्रेस

  1. अपने रूबी कोड को उन्नत करें: क्लीनर OOP डिज़ाइन के लिए सामंजस्य और कपलिंग में महारत हासिल करें अपने रूबी कोड को उन्नत करें: क्लीनर OOP डिज़ाइन के लिए सामंजस्य और कपलिंग में महारत हासिल करें

    सामंजस्य (Cohesion) और कपलिंग (Coupling) दो सबसे महत्वपूर्ण ऑब्जेक्ट-ओरिएंटेड सिद्धांत हैं। सामंजस्य एक क्लास के अंदर सभी मेथड्स के बीच संबंध के बारे में है। क्या वे इंस्टेंस वेरिएबल्स और पैरामीटर्स के उसी सेट का उपयोग कर रहे हैं, सभी एक ही लक्ष्य की ओर मिलकर काम कर रहे हैं? या हर मेथड एक-दूसरे से अ

  1. रूबी के MRI सोर्स कोड में डीप डाइव रूबी के MRI सोर्स कोड में डीप डाइव

    यदि आप कुछ समय से रूबी का उपयोग कर रहे हैं तो आप इस बारे में उत्सुक हो सकते हैं कि हुड के नीचे कुछ चीजें कैसे काम करती हैं। रूबी इंटर्नल्स में गहराई से जाने का एक तरीका वह सोर्स कोड पढ़ना है जो इसे काम करता है। भले ही आप C न जानते हों, फिर भी आप कुछ दिलचस्प चीजें सीख सकते हैं। सोर्स कोड रूबी के लिए