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

अपने नियंत्रक को फुलाए बिना रेल मॉडल खोजें और फ़िल्टर करें

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

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

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

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

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

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

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

@products = Product.filter_by_status("active").filter_by_starts_with("Ruby") # => All active products whose names start with 'Ruby'

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

ऐप/कंट्रोलर/product_controller.rb
def index
  @products = Product.where(nil) # creates an anonymous scope
  @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

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

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

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

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

ऐप/कंट्रोलर/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

# A list of the param names that can be used for filtering the Product list
def filtering_params(params)
  params.slice(:status, :location, :starts_with)
end

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

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

ऐप्लिकेशन/मॉडल/चिंताएं/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
ऐप/कंट्रोलर/product_controller.rb
def index
  @products = Product.filter(params.slice(:status, :location, :starts_with))
end

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

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

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

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

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

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

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

रेल एसक्यूएल इंजेक्शन साइट आपको यह जानने में मदद करेगी कि कौन सी ActiveRecord विधियां असुरक्षित हैं, ताकि आप अपने ऐप को सुरक्षित रख सकें।

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

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

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


  1. AWS ElasticBeanstalk और RDS के साथ अपने रेल 6 ऐप को क्यों और कैसे होस्ट करें?

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

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

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

  1. अपने बिंग खोज इतिहास को कैसे देखें और हटाएं

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