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

ActiveRecord-এ কাস্টম অর্ডারে ডেটাবেস রিকর্ড রিট্রিভ করুন

रेल्स में, यदि आपके पास उनके IDs हैं, तो अपने डेटाबेस से रिकॉर्ड्स का एक गुच्छा प्राप्त करना आसान है:

Person.where(id: [1, 2, 3]).map(&:id) => [1, 2, 3]

लेकिन क्या होगा यदि आप रिकॉर्ड्स को एक अलग क्रम में वापस प्राप्त करना चाहते थे? हो सकता है कि आपका सर्च इंजन सबसे अधिक प्रासंगिक IDs पहले लौटाता है। आप अपने रिकॉर्ड्स को उस क्रम में कैसे रखते हैं?

आप फिर से where आज़मा सकते हैं:

Person.where(id: [2, 1, 3]).map(&:id) => [1, 2, 3]

लेकिन यह बिल्कुल भी काम नहीं करता। तो आप अपने रिकॉर्ड्स को सही क्रम में कैसे प्राप्त करते हैं?

संगत तरीका: case स्टेटमेंट्स

रूबी की तरह, SQL case...when स्टेटमेंट्स का समर्थन करता है।

आप इसे बहुत बार नहीं देखते, लेकिन case...when स्टेटमेंट्स लगभग हैश की तरह कार्य कर सकते हैं। आप एक मान को दूसरे पर मैप कर सकते हैं:

case :b when :a then 1 when :b then 2 when :c then 3 end # => 2

वह केस स्टेटमेंट एक हैश की तरह दिखता है:

{ :a => 1, :b => 2, :c => 3 }[:b] # => 2

तो, आपके पास कुंजियों को उस क्रम में मैप करने का एक तरीका है जिसमें उन्हें दिखना चाहिए। और आपका डेटाबेस उस मनमाने क्रम द्वारा आपके परिणामों को सॉर्ट और वापस कर सकता है।

यह जानकर, आप अपने IDs और उनकी स्थिति को एक case स्टेटमेंट में डाल सकते हैं, और इसे एक SQL order क्लॉज में उपयोग कर सकते हैं।

तो यदि आप अपने ऑब्जेक्ट्स को क्रम [2, 1, 3] में वापस चाहते हैं, तो आपका SQL ऐसा दिख सकता है:

SELECT * FROM people WHERE id IN (1, 2, 3) ORDER BY CASE id WHEN 2 THEN 0 WHEN 1 THEN 1 WHEN 3 THEN 2 ELSE 3 END;

इस तरह, आपके रिकॉर्ड्स सही क्रम में वापस आते हैं। CASE प्रत्येक ID को उस क्रम में बदल देता है जिसमें इसे वापस किया जाना चाहिए।

बेशक, यह हास्यास्पद लगता है। और आप कल्पना कर सकते हैं कि हाथ से ऐसा क्लॉज बनाना कितना कष्टप्रद होगा।

लेकिन आपको इसे हाथ से बनाने की ज़रूरत नहीं है। रूबी इसके लिए है:

lib/extensions/active_record/find_by_ordered_ids.rb
module Extensions::ActiveRecord::FindByOrderedIds extend ActiveSupport::Concern module ClassMethods def find_ordered(ids) order_clause = "CASE id " ids.each_with_index do |id, index| order_clause << sanitize_sql_array(["WHEN ? THEN ? ", id, index]) end order_clause << sanitize_sql_array(["ELSE ? END", ids.length]) where(id: ids).order(order_clause) end end end ActiveRecord::Base.include(Extensions::ActiveRecord::FindByOrderedIds) Person.find_ordered([2, 1, 3]) # => [2, 1, 3]

ठीक वैसे ही जैसे हम चाहते थे!

एक क्लीनर, MySQL-विशिष्ट तरीका

यदि आप MySQL का उपयोग करते हैं, तो इसे करने का एक क्लीनर तरीका है। MySQL में विशेष ORDER BY FIELD सिंटैक्स है:

SELECT * FROM people WHERE id IN (1, 2, 3) ORDER BY FIELD(id, 2, 1, 3);

आप इसे रूबी से भी जनरेट कर सकते हैं:

lib/extensions/active_record/find_by_ordered_ids.rb
module Extensions::ActiveRecord::FindByOrderedIds extend ActiveSupport::Concern module ClassMethods def find_ordered(ids) sanitized_id_string = ids.map {|id| connection.quote(id)}.join(",") where(id: ids).order("FIELD(id, #{sanitized_id_string})") end end end ActiveRecord::Base.include(Extensions::ActiveRecord::FindByOrderedIds)

तो, यदि आप MySQL का उपयोग कर रहे हैं, और संगतता के बारे में बहुत चिंतित नहीं हैं, तो यह जाने का एक अच्छा तरीका है। यह उन स्टेटमेंट्स के रूप में पढ़ना बहुत आसान है जो आपके लॉग्स के माध्यम से उड़ते हैं।

जब आप रिकॉर्ड्स को एक विशिष्ट, मनमाने क्रम में प्रदर्शित करना चाहते हैं, तो आपको उन्हें रूबी में सॉर्ट करने की आवश्यकता नहीं है। थोड़े से कोड स्निपेट के साथ, आप डेटाबेस को वह करने दे सकते हैं जो यह अच्छा करता है: डेटा ढूंढना, सॉर्ट करना, और आपके ऐप को वापस करना।

  1. এক্সেলে হাইলাইট করার পদ্ধতি

  2. মাইএসকিউএল ডাটাবেস ব্যাকআপ করার পদ্ধতি

  3. অ্যান্ড্রয়েড SQLite-এ ডেসেন্ডিং অর্ডারে রেকর্ড দেখানোর পদ্ধতি

  4. MS SQL Server-এ ডেটাবেস নির্বাচন