2009-02-07 6 views
31

यह उन चीजों में से एक है, जो शायद इतना आसान है कि मैं इसे कभी नहीं ढूंढूंगा क्योंकि हर कोई इसे पहले ही जानता है।रेल. object अगर रेल? फिर विचारों में जादू '?

मैं वस्तुओं मैं अपने विचारों में शून्य के लिए जाँच करने के लिए तो मैं एक शून्य भिन्नता नहीं है मिल गया है:

<%= tax_payment.user ? tax_payment.user.name : '' %> 

तो यह:

<%= if tax_payment.user; tax_payment.user.name; end %> 

या मैं इस प्रकार कर सकता है ठीक है ... ज्यादातर भाषाओं के लिए। लेकिन मुझे लगता है कि चमकदार रूबी या रेलता का थोड़ा सा होना चाहिए, अगर मैं सबसे अच्छा कर सकता हूं तो मैं अभी भी लापता हूं।

उत्तर

55

के बारे में क्या:

<%= tax_payment.user.name if tax_payment.user %> 
+2

मुझे पता था कि यह एक प्रमुख स्लैपर होगा, धन्यवाद। – Jeremy

44

तुम भी नए Object.try वाक्य रचना कोशिश कर सकते हैं, यमक क्षमा। आप Introduce Null Object Refactoring की जाँच कर सकता है

tax_payment.try(:user).try(:name) 
+0

कूल जो भी मैं ढूंढ रहा था, वही है, मैं उस रिलीज की प्रतीक्षा करता हूं। – Jeremy

7

थोड़ा और व्यापक समाधान के लिए,:

यह चमकदार नया रेल 2.3 में है। इस पुनर्रचना के बुनियादी यांत्रिकी कि बजाय ग्राहक कोड में nil के लिए जाँच की आप के बजाय यह सुनिश्चित करें कि प्रदाता पहली जगह में एक nil पैदा करता है कभी, एक संदर्भ विशेष अशक्त वस्तु शुरू करने और लौटने कि द्वारा ।

तो, एक खाली स्ट्रिंग, खाली सरणी, एक खाली हैश या एक विशेष खाली ग्राहक या खाली उपयोगकर्ता या केवल nil के बजाय कुछ वापस लौटें और फिर आपको पहले स्थान पर nil की जांच करने की आवश्यकता नहीं होगी।

तो, आपके मामले में आप

class NullUser < User 
    def name 
     return '' 
    end 
end 

की तरह कुछ रूबी में है वहाँ वास्तव में एक और, काफी सुंदर, परिचय अशक्त वस्तु पुनर्रचना को लागू करने के रास्ते होता हालांकि,: आप वास्तव में की जरूरत नहीं है एक शून्य ऑब्जेक्ट प्रस्तुत करें, क्योंकि nilपहले से ही एक ऑब्जेक्ट है! तो, आप नलयूसर के रूप में व्यवहार करने के लिए बंदर-पैच nil कर सकते हैं - हालांकि, बंदर-पैचिंग के संबंध में सभी सामान्य चेतावनियां और नुकसान इस मामले में और भी दृढ़ता से लागू होते हैं, क्योंकि nil चुपचाप NoMethodError एस निगलते हैं या ऐसा कुछ आपके पूरी तरह से गड़बड़ कर सकता है डीबगिंग अनुभव और वास्तव में उन मामलों को ट्रैक करने के लिए कठिन है जहां nil है जो वहां नहीं होना चाहिए (nil के विपरीत जो शून्य ऑब्जेक्ट के रूप में कार्य करता है)।

2

मैं सिर्फ

<%= tax_payment.user.name rescue '' %> 
+2

यह क्यों कम किया जा रहा है, क्या यह बुरा अभ्यास है? मेरे लिए पूरी तरह से सुरुचिपूर्ण लगता है। –

+0

मैं सिर्फ सिद्धांत पर उभर रहा हूं कि अगर इन सभी वर्षों में किसी ने इसे समझाया नहीं है, तो क्यों नहीं? प्रतिनिधिमंडल को पेश करने के लिए – labyrinth

10

रूबी समुदाय इस मुहावरे को स्वचालित करने के लिए ध्यान का एक अविश्वसनीय राशि डाल दिया है।रेल

  • एक और try
  • andand
  • का अधिक सुरक्षित andand
  • Kernel::ergo
  • send-with-default
  • maybe
  • पर

    सबसे प्रसिद्ध में शायद रेल में try method है। हालांकि, इसे somecriticism प्राप्त हुआ है।

    किसी भी मामले में, मुझे लगता है कि बेन का समाधान पूरी तरह से पर्याप्त है।

    2

    एक अन्य विकल्प है, जो भावना कभी कभी बनाता है ...

    तो tax_payment.user रिटर्न शून्य, nil.to_s (कोई रिक्त स्ट्रिंग) छपा है, जो हानिरहित है। यदि कोई उपयोगकर्ता है, तो यह उपयोगकर्ता के नाम को प्रिंट करेगा।

    9

    मैं हमेशा इस दृष्टिकोण को प्राथमिकता दी है:

    मॉडल:

    class TaxPayment < ActiveRecord::Base 
        belongs_to :user 
        delegate :name, :to=>:user, :prefix=>true, :allow_nil=>true 
    end 
    

    दृश्य:

    <%= tax_payment.user_name %> 
    

    http://apidock.com/rails/Module/delegate

    +0

    अप-वोट! – Jeremy

    0

    आप एक सहायक विधि है जो इस तरह दिखता है लिख सकते हैं:

    def print_if_present(var) 
        var ? var : "" 
    end 
    

    और फिर इस तरह इसका इस्तेमाल (ध्यान में रखते हुए): var नहीं के बराबर है

    <%= print_if_present(your_var) %>

    हैं, तो यह सिर्फ एक अपवाद को ऊपर उठाने के बिना कुछ भी नहीं प्रिंट करता है।