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

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

एक अल्पज्ञात, हल्के ढंग से प्रलेखित रेल सुविधा

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

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

मुझे अंत में यहाँ एक अच्छा अवलोकन मिला: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
ऐप्लिकेशन/कंट्रोलर/लेख_कंट्रोलर.आरबी
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

इतना भी बेकार नहीं! केवल अजीब चीज है save . का उपयोग करना update . के बजाय प्रकाशित विधि में। ऐसा इसलिए होता है क्योंकि 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 is now filled out
end

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

बस काफी हल्का है

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


  1. प्रबुद्धता डेस्कटॉप समीक्षा:एक सुंदर, हल्का लेकिन अलग डेस्कटॉप प्रबंधक

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

  1. किसी भी रैक एप्लिकेशन में इनबाउंड ईमेल को हैंडल करें

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

  1. अपने रेल ऐप्स के प्रदर्शन को समझने का एक नया तरीका

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