কম্পিউটার টিউটোরিয়াল

রেইলসে .each দিয়ে খালি কলেকশন হ্যান্ডলিং

আমি each-কে ভালোবাসি, কিন্তু এর সাথে আমার একটা সমস্যা আছে। যখন আপনার একটি খালি কলেকশন থাকে, তখন কী হয়?

আপনি যদি [].each কল করেন, কিছুই হবে না এবং [] রিটার্ন করবে। কখনো কখনো আপনি এটাই চান। তবে অধিকাংশ সময়, বিশেষ করে UI বিল্ড করার সময়, আপনি খালি লিস্টকে 스페শ্যালি হ্যান্ডল করতে চান। উদাহরণস্বরূপ, আমি সাধারণত ডেটা নেই এমন সময় আলাদা মেসেজ দেখাতে চাই।

তবে যেহেতু [].each [] রিটার্ন করে, nil না, আপনি এমন কিছু লিখতে বাধ্য হন:

app/views/users/index.html.erb
<% 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-এর মত কিছু চাই, "অথবা" অপশনসহ।

রেইলস কলেকশন রেন্ডার করা

ভিউর ভিতরে, রেইলস সাহায্য করতে পারে। এটা জিনিসগুলোর কলেকশন রেন্ডার করার খুব এক্সপার্ট:

app/views/users/index.html.erb
<%= render @users %>
app/views/users/_user.html.erb
<p><%= user.name %></p>

যখন render-কে @users পাস করা হয়, সেটা _user.html.erb রেন্ডার করে @users-এর ভিতরের প্রতিটি ইউজারের জন্য একবার। আপনি পুরোপুরি each স্কিপ করতে পারেন।

বোনাস হিসেবে, যদি @users খালি হয়, render nil রিটার্ন করে, ঠিক যেমন আমরা চাই! তাই আপনি এভাবে লিখতে পারেন, এবং অরিজিনাল ভার্সনের মত আউটপুট পাবেন:

app/views/users/index.html.erb
<%= render(@users) || render('empty') %>
app/views/users/_user.html.erb
<p><%= user.name %></p>
app/views/users/_empty.html.erb
<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 প্যাটার্ন ব্যবহার করি।

আপনি কী ভাবেন ভালো? আপনি খালি লিস্ট কীভাবে হ্যান্ডল করেন? কোনো ভালো উপায় পেয়েছেন? হলে বলুন!

  1. জাভাস্ক্রিপ্টে কন্ডিশনাল স্টেটমেন্টস

  2. PHP-এ each() ফাংশন

  3. C#-এ স্ট্রিংয়ে প্রতিটি শব্দের ফ্রিকোয়েন্সি বের করা

  4. SQL Server-এ IF...ELSE স্টেটমেন্ট