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

सुव्यवस्थित वैलिडेशन: अपने लेख वर्कफ़्लो में ड्राफ्ट से प्रकाशित तक

(मैंने यह पोस्ट कुछ महीने पहले अपनी सूची को भेजी थी। अगर आपको यह पसंद है, और आप इस तरह की और पोस्ट पढ़ना चाहते हैं, तो आपको साइन अप करना चाहिए!)

मेरे एक ऐप के साथ दूसरे दिन एक अजीब स्थिति आई।

मान लें कि आपके पास एक Article मॉडल है, और ये लेख पहले ड्राफ्ट के रूप में बनाए जाते हैं। ये ड्राफ्ट हल्के होने चाहिए। आप उन्हें तुरंत बनाने और संपादित करने में सक्षम होना चाहते हैं, बिना बॉडी की आवश्यकता के, या यहां तक कि शीर्षक के भी।

लेकिन जब आप इन लेखों को प्रकाशित करते हैं, तो आपको कुछ अतिरिक्त वैलिडेशन की आवश्यकता होती है। उनके पास एक शीर्षक, एक बॉडी, और वह सारा सामान होना चाहिए।

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

if और unless?

वैलिडेशन्स :if और :unless पैरामीटर्स का समर्थन करते हैं, लेकिन यह हमेशा इतना साफ नहीं होता:

app/models/article.rb
class Article < ActiveRecord::Base
  # validate in draft mode
  validates_presence_of :author_id
  # validate only when published
  validates_presence_of :body, unless: lambda { |o| o.draft? }
  ...
end

इसके अलावा, यह वह तरीका नहीं है जिस तरह से मैं एक लेख प्रकाशित करना चाहता हूं। मैं एक लेख प्रकाशित करने के बारे में एक क्रिया के रूप में सोचना चाहता हूं, न कि एक स्थिति जिसमें लेख है, इसलिए एक एट्रिब्यूट सेट करना और उसकी जांच करना सही उत्तर नहीं है।

एक कम-ज्ञात, हल्के ढंग से प्रलेखित रेल्स फीचर

यह समस्या रेल्स के वैलिडेशन कॉन्टेक्स्ट्स के लिए एकदम सही है। मैंने DHH द्वारा लिखे एक गिस्ट से कस्टम वैलिडेशन कॉन्टेक्स्ट्स के बारे में पहली बार सीखा। लेकिन यह ढूंढना मुश्किल था कि ये क्या थे, और उनका उपयोग कैसे करें, इसका एक अच्छा विवरण।

कस्टम कॉन्टेक्स्ट्स के लिए डॉक्यूमेंटेशन काफी पतला है। इसका एकमात्र उल्लेख जो मुझे API डॉक्स में मिला वह यहां था। और इन वैलिडेशन्स के लिए API डॉक्स कस्टम कॉन्टेक्स्ट्स का बिल्कुल उल्लेख नहीं करते! यह इसे विशेष रूप से कठिन बनाता है - यदि आप नहीं जानते कि किसी चीज़ को क्या कहा जाता है, तो आप उस पर अधिक डॉक्यूमेंटेशन कैसे ढूंढते हैं?

मैंने अंततः यहां एक अच्छा अवलोकन पाया: https://blog.arkency.com/2014/04/mastering-rails-validations-contexts/। यह पढ़ने लायक है। आइए देखें कि यह हमारे उदाहरण के लिए कैसा दिखता है:

app/models/article.rb
class Article < ActiveRecord::Base
  # validate in draft mode
  validates_presence_of :author_id
  # validate only when published
  validates_presence_of :body, on: :publish
  ...
end
app/controllers/article_controller.rb
class ArticleController < ApplicationController
  respond_to :html
  def create
    @article = Article.create(article_params)
    respond_with @article
  end
  def publish
    @article = Article.find(params[:id])
    @article.attributes = article_params
    @article.save(context: :publish)
    respond_with @article
  end
  private
  def article_params
    params. require(:article). permit(:body, :title, :author_id)
  end
end

बहुत बुरा नहीं! एकमात्र अजीब बात पब्लिश मेथड में update के बजाय save का उपयोग करना है। ऐसा इसलिए होता है क्योंकि update पैरामीटर के रूप में वैलिडेशन कॉन्टेक्स्ट नहीं ले सकता। (शायद यह पुल रिक्वेस्ट के लिए एक अवसर है?)

सेविंग से परे

कस्टम वैलिडेशन कॉन्टेक्स्ट्स केवल अलग-अलग तरीकों से रिकॉर्ड सेव करने से अधिक के लिए उपयोगी हैं। कॉन्टेक्स्ट valid? के साथ काम करते हैं:

@article.valid?(:publish)

इसलिए आप वैलिडेशन कॉन्टेक्स्ट्स का उपयोग कहीं भी कर सकते हैं जहां आप यह प्रश्न पूछना चाहते हैं: क्या इस ऑब्जेक्ट में यह संपत्ति है? और यदि नहीं, तो क्यों नहीं?

DHH एक मेथड बनाते हैं जो -able? में समाप्त होता है जो valid?(:context) को डेलीगेट करता है। मुझे वास्तव में उसका लुक पसंद है:

app/models/article.rb
class Article
  validate :has_been_published, on: :view
  validate :is_not_spam, on: :view
  def viewable?
    valid? :view
  end
  private
  def has_been_published
    if published_at.future?
      errors.add(:published_at, "is in the future")
    end
  end
  def is_not_spam
    if is_spam?(body)
      errors.add(:body, "has been detected as spam")
    end
  end
end

इस तरह, जब आप इसे जांचते हैं, तो आपको केवल true या false से अधिक जानकारी मिलती है:

unless @article.viewable?
  # @article.errors अब भरा हुआ है
end

क्या लेख देखने योग्य है? खैर, क्यों नहीं?

बस पर्याप्त हल्का

कुछ अन्य तरीके हैं जिनसे आप इस तरह का वैलिडेशन व्यवहार प्राप्त कर सकते हैं। आप अपने स्वयं के वैलिडेशन्स के साथ कस्टम ActiveModel सर्विस ऑब्जेक्ट्स बना सकते हैं। आप अपने वैलिडेशन्स पर :if या :unless का उपयोग कर सकते हैं। लेकिन रेल्स में बहुत सी चीजों की तरह, कस्टम वैलिडेशन कॉन्टेक्स्ट्स पठनीयता और लचीलेपन के बीच एक अच्छा समझौता हैं।

  1. Enlightenment डेस्कटॉप रिव्यू: एक सुंदर, हल्का लेकिन अलग डेस्कटॉप मैनेजर Enlightenment डेस्कटॉप रिव्यू: एक सुंदर, हल्का लेकिन अलग डेस्कटॉप मैनेजर

    डेस्कटॉप एनवायरनमेंट रिव्यू की हमारी श्रृंखला को जारी रखते हुए, आज एक ऐसा विकल्प है जिसका निश्चित रूप से एक विशिष्ट उद्देश्य है। Enlightenment एक अत्यंत हल्का विंडो मैनेजर है जिसमें इसमें बड़ी मात्रा में उपयोगिता बेक की गई है। यह वास्तव में एक विशिष्ट विकल्प है जिसे आप या तो पसंद करते हैं या नापसंद

  1. किसी भी Rack एप्लिकेशन में इनकमिंग ईमेल को निर्बाध रूप से प्रोसेस करें किसी भी Rack एप्लिकेशन में इनकमिंग ईमेल को निर्बाध रूप से प्रोसेस करें

    तो आपका क्लाइंट अभी कॉल किया... वह चाहता है कि उसका ऐप इनकमिंग ईमेल को संभाले। बिल्कुल Basecamp की तरह। कोई समस्या नहीं, आप सोचते हैं, बहुत सारी सेवाएं आपको ईमेल को POST द्वारा आपके ऐप पर भेजेंगी। आसान होना चाहिए। है ना? नहीं। प्रत्येक सेवा एक मालिकाना प्रारूप का उपयोग करती है। कुछ आपको पार्स्ड

  1. Rails प्रदर्शन में महारत: अपने ऐप्स का निदान और त्वरण करने का सिद्ध दृष्टिकोण Rails प्रदर्शन में महारत: अपने ऐप्स का निदान और त्वरण करने का सिद्ध दृष्टिकोण

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