Computer >> कंप्यूटर ट्यूटोरियल >  >> प्रोग्रामिंग >> Ruby

रेल्स मॉडल्स को आसानी से खोजें और फ़िल्टर करें जबकि कंट्रोलर्स को लीन रखें

रेल्स कंट्रोलर्स में खोज, सॉर्टिंग और फ़िल्टरिंग एक दर्द हो सकता है। ElasticSearch और Solr बेहतरीन, उच्च-शक्ति वाले समाधान हैं, लेकिन एक छोटे ऐप के लिए वास्तव में बड़ी निर्भरताएं हैं।

सौभाग्य से, रेल्स में स्कोप्स शामिल हैं, जो सरल खोज, फ़िल्टरिंग और सॉर्टिंग के लिए आपको जो चाहिए उसका बहुत कुछ प्रदान कर सकते हैं। यदि आप स्कोप चेनिंग का लाभ उठाते हैं, तो आप बड़ी निर्भरताएं लिए बिना या खुद बहुत सारा दोहराव वाला खोज कोड लिखे बिना अपनी इच्छित सुविधाओं का निर्माण कर सकते हैं।

स्कोप्स के साथ खोज

एक #index मेथड की कल्पना करें जो आपके RESTful कंट्रोलर पर प्रोडक्ट्स की एक टेबल दिखाता है। प्रोडक्ट्स एक्टिव, पेंडिंग, या इनएक्टिव हो सकते हैं, एक ही स्थान पर उपलब्ध हैं, और उनका एक नाम है।

यदि आप इन प्रोडक्ट्स को फ़िल्टर करने में सक्षम होना चाहते हैं, तो आप कुछ स्कोप्स लिख सकते हैं:

app/models/product.rb
class Product < ActiveRecord::Base scope :filter_by_status, -> (status) { where status: status } scope :filter_by_location, -> (location_id) { where location_id: location_id } scope :filter_by_starts_with, -> (name) { where("name like ?", "#{name}%")} end 

इनमें से प्रत्येक स्कोप Product पर एक क्लास मेथड परिभाषित करता है जिसका उपयोग आप प्राप्त होने वाले परिणामों को सीमित करने के लिए कर सकते हैं।

@products = Product.filter_by_status("active").filter_by_starts_with("Ruby") # => 'Ruby' से शुरू होने वाले सभी एक्टिव प्रोडक्ट्स 

आपका कंट्रोलर इन स्कोप्स का उपयोग आपके परिणामों को फ़िल्टर करने के लिए कर सकता है:

app/controllers/product_controller.rb
def index @products = Product.where(nil) # एक अनाम स्कोप बनाता है @products = @products.filter_by_status(params[:status]) if params[:status].present? @products = @products.filter_by_location(params[:location]) if params[:location].present? @products = @products.filter_by_starts_with(params[:starts_with]) if params[:starts_with].present? end 

और अब आप केवल उन्हीं एक्टिव प्रोडक्ट्स को दिखा सकते हैं जिनके नाम 'Ruby' से शुरू होते हैं।

https://example.com/products?status=active&starts_with=Ruby 

स्पष्ट रूप से, इसे कुछ सफाई की आवश्यकता है

आप देख सकते हैं कि यह कोड कैसे अनियंत्रित और दोहरावदार होने लगता है! बेशक, आप रूबी का उपयोग कर रहे हैं, इसलिए आप इसे एक लूप में डाल सकते हैं:

app/controllers/product_controller.rb
def index @products = Product.where(nil) filtering_params(params).each do |key, value| @products = @products.public_send("filter_by_#{key}", value) if value.present? end end private # पैरामीटर नामों की सूची जिनका उपयोग प्रोडक्ट सूची को फ़िल्टर करने के लिए किया जा सकता है def filtering_params(params) params.slice(:status, :location, :starts_with) end 

एक अधिक पुन: प्रयोज्य समाधान

आप इस कोड को एक मॉड्यूल में स्थानांतरित कर सकते हैं और इसे किसी भी मॉडल में शामिल कर सकते हैं जो फ़िल्टरिंग का समर्थन करता है:

app/models/concerns/filterable.rb
module Filterable extend ActiveSupport::Concern module ClassMethods def filter(filtering_params) results = self.where(nil) filtering_params.each do |key, value| results = results.public_send("filter_by_#{key}", value) if value.present? end results end end end 
app/models/product.rb
class Product include Filterable ... end 
app/controllers/product_controller.rb
def index @products = Product.filter(params.slice(:status, :location, :starts_with)) end 

अब आपके पास कंट्रोलर में एक लाइन और मॉडल में एक लाइन के साथ अपने मॉडल्स की फ़िल्टरिंग और खोज है। यह कितना आसान है? आप बिल्ट-इन order क्लास मेथड का उपयोग करके बिल्ट-इन सॉर्टिंग भी प्राप्त कर सकते हैं, लेकिन अपने खुद के स्कोप्स लिखना सॉर्टिंग के लिए शायद बेहतर विचार है। इस तरह आप इनपुट को सैनिटी-चेक कर सकते हैं।

आपको कुछ प्रयास बचाने के लिए, मैंने Filterable को एक गिस्ट में डाल दिया है। इसे अपने प्रोजेक्ट में आज़माएं, इसने मुझे बहुत समय और कोड बचाया है।

अपडेट: Jan Sandbrink को कुछ इंगित करने के लिए धन्यवाद: filtering_params में पैरामीटर्स को व्हाइटलिस्ट करना भूलना आसान है। यदि आप भूल जाते हैं, तो यह आपके ऐप को गंभीर सुरक्षा समस्याओं के लिए खोल सकता है।

इस सब से बचने के लिए, status, location, और starts_with नाम के स्कोप्स का उपयोग करने के बजाय, मैंने इस लेख को अपडेट किया है ताकि वे स्कोप्स अब filter_by_status, filter_by_location, और filter_by_starts_with नाम से जाने जाएं। वे स्पष्ट और सुरक्षित हैं।

एक महत्वपूर्ण चेतावनी

पैरामीटर्स को स्कोप्स में भेजना आपके वेब ऐप में बुनियादी खोज और फ़िल्टरिंग प्राप्त करने का एक आसान तरीका है। लेकिन यदि आप सावधान नहीं हैं, और अपने यूजर्स जो कुछ भी भेजते हैं उसे स्वीकार करते हैं, तो आपके ऐप में कुछ बहुत बुरे सुरक्षा बग हो सकते हैं।

विशेष रूप से, order SQL इंजेक्शन के लिए कमजोर है। इसलिए यदि आप अपने सॉर्ट ऑर्डर को परिभाषित करने के लिए पैरामीटर्स का उपयोग कर रहे हैं, तो आपको हमेशा उन कॉलम नामों की जांच करनी चाहिए जो आपका यूजर आपको भेज रहा है और केवल उन मानों को अनुमति दें जिन्हें आप जानते हैं कि वे सुरक्षित हैं।

Rails SQL Injection साइट आपको यह जानने में मदद करेगी कि कौन से ActiveRecord मेथड्स कमजोर हैं, ताकि आप अपने ऐप को सुरक्षित रख सकें।

क्या आप वीडियो के साथ बेहतर सीखते हैं?

आप साथी स्क्रीनकास्ट में हर कदम देख सकते हैं, एक बिल्कुल नए ऐप को शुरू करने से लेकर खोज और फ़िल्टरिंग जोड़ने तक। हम एक ऐप बनाएंगे, इसे सैंपल डेटा से भरेंगे, एक खोज फॉर्म जोड़ेंगे, और इसे हुक अप करेंगे। और आपको वीडियो के साथ सोर्स भी मिलेगा, ताकि जब आप अपने रेल्स ऐप्स में सरल खोज और फ़िल्टरिंग जोड़ें तो आप वापस रेफर कर सकें।

स्क्रीनकास्ट के बारे में यहाँ और जानें!

  1. AWS Elastic Beanstalk और RDS पर Rails 6 को सहजता से डेप्लॉय करें: एक पूर्ण गाइड AWS Elastic Beanstalk और RDS पर Rails 6 को सहजता से डेप्लॉय करें: एक पूर्ण गाइड

    एक एप्लिकेशन लिखते समय, आपको जिन प्रमुख मुद्दों पर विचार करना होता है, उनमें से एक यह है कि एप्लिकेशन को बाकी दुनिया के साथ कैसे साझा किया जाएगा। एक सामान्य दृष्टिकोण Heroku पर लॉन्च करना रहा है। इसे सेट अप करना आसान है और यह पूरी तरह से मैनेज्ड है। लेकिन, टीमों के लिए बाद में Heroku छोड़ना भी आम ह

  1. अपने SQL डेटाबेस में Elasticsearch खोज और विज़ुअलाइज़ेशन को सहजता से जोड़ें अपने SQL डेटाबेस में Elasticsearch खोज और विज़ुअलाइज़ेशन को सहजता से जोड़ें

    नए NoSQL डेटा स्टोर पर ध्यान केंद्रित करने वाली सभी चर्चाओं के बावजूद, रिलेशनल और SQL-आधारित डेटाबेस अभी भी जीवित और अच्छे हैं। वास्तव में, हमारे साथ काम करने वाला लगभग हर ग्राहक अपने MongoDB, Redis, या Elasticsearch के साथ अपने वातावरण में कुछ MySQL, PostgreSQL या MS SQL Server रखता है। रिलेशनल डेट

  1. बिंग सर्च हिस्ट्री प्रबंधित करें: बेहतर गोपनीयता के लिए देखें और हटाएं बिंग सर्च हिस्ट्री प्रबंधित करें: बेहतर गोपनीयता के लिए देखें और हटाएं

    जब आप अपने माइक्रोसॉफ्ट खाते में लॉग इन होते हैं, तो बिंग आपके द्वारा की गई हर खोज को ट्रैक करता है। यदि आप अतीत में की गई किसी चीज़ पर वापस जाना चाहते हैं तो यह इतिहास उपयोगी हो सकता है। लेकिन यह एक गोपनीयता चिंता का विषय भी हो सकता है, क्योंकि खोज इतिहास स्वाभाविक रूप से कुछ काफी व्यक्तिगत जानकारी