मैंने सैंडी मेट्ज़ देखा है ” कुछ भी नहीं है अब एक दो बार प्रस्तुति। मुझे पता है कि मैं अपनी रेल परियोजनाओं में सभी जगहों पर नील जाँच करता हूँ, लेकिन मुझे नहीं पता है कि कैसे नील जाँच से बचना है और संघों की बात आने पर इसे वस्तु उन्मुख तरीके से कैसे करना है।
इन संघों पर विचार करें:
#app/models/user.rb
class User < ActiveRecord::Base
belongs_to :blog
end
#app/models/blog.rb
class Blog < ActiveRecord::Base
belongs_to :hash_tag
has_one :user
end
#app/models/hash_tag.rb
class HashTag < ActiveRecord::Base
has_one :blog
end
मैं एक उपयोगकर्ता को पकड़ो:
@user = User.find(1)
और मैं उनका ब्लॉग ढूंढना चाहता हूं:
@user.blog
=> nil
यह वापस आता है nil
यहाँ इस वजह से user
कोई संबद्ध नहीं है blog
, इसलिए यदि मैं इसके लिए कुछ ऐसा करता हूं तो निम्न कोड एप्लिकेशन को तोड़ देगा user
:
@user.blog.title
=> undefined method `title" for nil:NilClass
साधारण तय यह है कि इसे गैर-ऑब्जेक्ट-ओरिएंटेड तरीके से किया जाए और बस एक नील जांच करें (लेकिन यह है कि हम बचना चाहते हैं क्योंकि अन्यथा आवेदन में सभी जगह निल्स चेक बिल्कुल सही हैं):
@user.blog.title if @user.blog
शून्य जांच अधिक बोझिल और प्रक्रियात्मक हो जाती है, जो आप नीचे दिए गए संघों के माध्यम से गहराई तक जाते हैं:
@user = User.find(1)
if @user.blog && @user.blog.hash_tag #checking for nil twice
@user.blog.hash_tag.tag_name
end
संघों के लिए शून्य जाँच से बचने का वस्तु-उन्मुख तरीका क्या है?
मैं रेल से अवगत हूँ " कोशिश विधि, हालांकि मेट्ज़ ने सिफारिश नहीं की try
तरीका। शायद जब यह रेल में संघों की बात आती है: try
सबसे अच्छा विकल्प है?
उत्तर:
उत्तर № 1 के लिए 6प्रोग्रामिंग डिज़ाइन गाइडलाइन कहा जाता है डेमोंटर का कानून
इसे अपने रेल मॉडल पर लागू करना है:
#app/models/user.rb
class User < ActiveRecord::Base
belongs_to :blog
delegate :title, to: :blog, prefix: true, allow_nil: true
# then you can call user.blog_title
delegate :tag_name, to: :blog, prefix: true, allow_nil: true
# follow LoD
end
#app/models/blog.rb
class Blog < ActiveRecord::Base
belongs_to :hash_tag
delegate :tag_name, to: :hash_tag, allow_nil: true
has_one :user
end
और अब आप यह कर सकते हैं:
@user = User.find(1)
@user.blog_title # no error even if there is no associated blog
@user.tag_name # no error even if there is no associatd blog or no associated hash_tag object
कृपया संदर्भ के लिए निम्नलिखित लिंक पढ़ें:
- http://apidock.com/rails/Module/delegate
- http://samurails.com/tutorial/rails-delegate-dont-break-the-law-of-demeter/
जवाब के लिए 2 № 2
निफ्टी रत्न है andand
जो मैं इस तरह के मामलों में उपयोग करता हूं। आम तौर पर आपको लिखना होगा:
@user.blog && @user.blog.title
andand
मणि लागू करता है सामान्य अशक्त पैटर्न। andand
एक विधि के साथ वस्तु का विस्तार करता है andand
, जो किसी वस्तु को लौटाता है, जब तक कि वह शून्य न हो। शून्य के मामले में, NullPatern ऑब्जेक्ट मैथ_मिसिंग मैजिक का उपयोग करके सभी मेथड कॉल के लिए निल वापस करने के लिए दिया जाता है।
@user.blog.andand.title
जब आप अधिक स्थितियों की जांच करने की आवश्यकता होती है तो यह और भी अधिक शक्तिशाली होता है:
@user.blog && @user.blog.title && @user.blog.title.capitalize
हो जाता है:
@user.blog.andand.title.andand.capitalize
उत्तर № 3 के लिए 1
मुझे लगता है कि यह एक विकल्प हो सकता है
मै इस्तेमाल करूंगा:
rescue
तरीका
सावधान: यह विधि अपवादों को पकड़ती है और तदनुसार प्रतिक्रिया करती है; अगर आपको अपवादों का अलग तरह से जवाब देने की आवश्यकता है तो इसका उपयोग न करें। मुझे आशा है कि आप समझ गए होंगे
@user = User.find(1)
tag_name = @user.blog.hash_tag.tag_name rescue "" # respond with default value
उदाहरण:
2.1.1 :001 > var1 = nil
=> nil
2.1.1 :002 > my_val = var1.some_method
NoMethodError: undefined method `some_method" for nil:NilClass
from (irb):2
from /home/shiva/.rvm/rubies/ruby-2.1.1/bin/irb:11:in `<main>"
2.1.1 :003 > my_val = var1.some_method rescue ""
=> ""
एक और विकल्प होगा .try
तरीका; http://apidock.com/rails/Object/try
.try
में परिभाषित किया गया हैRails
इसलिए से उपलब्ध नहीं होRails
@person.non_existing_method if @person.respond_to?(:non_existing_method)
# instead use
@person.try(:non_existing_method) # => returns nil if does not respond_to
शून्य पर कॉल किए जाने पर शून्य वापस करने का प्रयास करें चाहे वह विधि का जवाब दे:
nil.try(:to_i) # => nil, rather than 0