मुझे each
से प्यार है , लेकिन मुझे इससे समस्या है। क्या होता है जब आपके पास एक खाली संग्रह होता है?
अगर आप [].each
. को कॉल करते हैं , कुछ नहीं होगा और []
लौटा दी जाएगी। कभी-कभी, आप यही चाहते हैं। लेकिन अधिक बार, खासकर जब आप UI बना रहे हों, तो आप खाली सूचियों को एक विशेष तरीके से संभालना चाहेंगे। उदाहरण के लिए, जब मेरे पास कोई डेटा नहीं होता है, तो मैं आमतौर पर एक अलग संदेश दिखाना चाहता हूं।
लेकिन चूंकि [].each
रिटर्न []
, नहीं nil
, आप कुछ इस तरह लिख रहे हैं:
<% if @users.empty? -%>
<p>You don't have any users. <%= link_to "Add one!", new_user_path %></p>
<% else -%>
<% @users.each do |user| -%>
<p><%= user.name %></p>
<% end -%>
<% end -%>
यह काम करता है, लेकिन यह अजीब लगता है। मैं इसके बजाय कहूंगा, "इस संग्रह में प्रत्येक आइटम के लिए यह काम करें, जब तक कि इसमें कुछ भी न हो, इस मामले में यह दूसरी चीज पूरी तरह से करें।" मुझे each
जैसा कुछ चाहिए , "या अन्य" के साथ।
रेंडरिंग रेल कलेक्शंस
आपके विचारों के अंदर, रेल मदद कर सकता है। चीजों का संग्रह प्रस्तुत करने में यह बहुत अच्छा है:
<%= render @users %>
<p><%= user.name %></p>
जब render
पास हो गया है @users
, यह _user.html.erb
. प्रदान करता है @users
. के अंदर प्रत्येक उपयोगकर्ता के लिए एक बार . आप each
को छोड़ सकते हैं पूरी तरह से।
बोनस के रूप में, यदि @users
खाली है, render
रिटर्न nil
, जैसा हम चाहते हैं! तो आप इसे लिख सकते हैं, और मूल संस्करण के समान आउटपुट प्राप्त कर सकते हैं:
<%= render(@users) || render('empty') %>
<p><%= user.name %></p>
<p>You don't have any users. <%= link_to "Add one!", new_user_path %></p>
रेल के सम्मेलनों को समझने के बाद, यह बहुत अधिक प्रत्यक्ष है।
एक दृश्य के बाहर के बारे में क्या?
यदि आप रेल का अनुसरण करते हैं, तो render
संग्रह के साथ वस्तुओं के संग्रह को प्रस्तुत करने का एक तेज़, शक्तिशाली तरीका है।
लेकिन कभी-कभी आप प्रत्येक आइटम को प्रस्तुत करने के लिए अतिरिक्त आंशिक से निपटना नहीं चाहेंगे। या render
आपके डिजाइन का समर्थन नहीं करेगा। या आप एक दृश्य के अंदर भी नहीं होंगे।
मैंने अब तक जो सबसे अच्छा समाधान खोजा है वह है presence
।
list.presence
के समान है:
if list.present?
list
else
nil
end
यानी, अगर इसमें कुछ है तो आपको सूची वापस मिल जाएगी, और nil
अगर यह खाली है।
presence
. के साथ , आप लिख सकते हैं:
@users.each do |user|
puts user.name
end.presence || puts("You don't have any users.")
यह प्रत्येक नाम को प्रिंट करता है यदि @users
. में उपयोगकर्ता हैं , या You don't have any users
अन्यथा।
फिर भी, मैं presence
के बिना कर सकता था . यह एक हैक की तरह लगता है, क्योंकि यह एक है। अगर यह समर्थित होता, तो ऐसा कुछ बेहतर हो सकता:
@users.each do |user|
puts user.name
end || puts("You don't have any users.")
या स्मॉलटाक-ईश:
@users.each(if_empty: lambda { puts "You don't have any users." }) do |user|
puts user.name
end
या यहां तक कि (हांफना!):
for user in @users
puts user.name
else
puts "You don't have any users."
end
अभी के लिए, हालांकि, मैं आमतौर पर केवल presence
. के साथ जाता हूं या मूल if blank?; else each
पैटर्न।
आपके हिसाब से कौन बेहतर है? आप खाली सूचियों को कैसे संभालते हैं? क्या आपको कोई बेहतर तरीका मिला है? अगर ऐसा है, तो मुझे इसके बारे में बताएं!