কম্পিউটার

আপনার কন্ট্রোলারকে ব্লাটিং ছাড়াই রেল মডেলগুলি অনুসন্ধান করুন এবং ফিল্টার করুন৷

রেল কন্ট্রোলারে অনুসন্ধান, বাছাই এবং ফিল্টার করা একটি ব্যথা হতে পারে। ইলাস্টিক সার্চ এবং সোলার দুর্দান্ত, উচ্চ-ক্ষমতাসম্পন্ন সমাধান, কিন্তু একটি ছোট অ্যাপের জন্য সত্যিই বড় নির্ভরতা৷

সৌভাগ্যবশত, রেলগুলিতে স্কোপ রয়েছে, যা আপনাকে সহজ অনুসন্ধান, ফিল্টারিং এবং বাছাইয়ের জন্য প্রয়োজনীয় অনেক কিছু সরবরাহ করতে পারে। আপনি যদি স্কোপ চেইনিংয়ের সুবিধা গ্রহণ করেন, তাহলে আপনি বড় নির্ভরতা না নিয়ে বা নিজেরাই পুনরাবৃত্ত অনুসন্ধান কোডের একটি গুচ্ছ না লিখে আপনার পছন্দসই বৈশিষ্ট্যগুলি তৈরি করতে পারেন৷

স্কোপের সাহায্যে অনুসন্ধান করা

একটি #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

এই স্কোপের প্রত্যেকটি পণ্যের একটি ক্লাস পদ্ধতি সংজ্ঞায়িত করে যা আপনি ফলাফলগুলিকে সীমিত করতে ব্যবহার করতে পারেন।

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

আপনার ফলাফলগুলি ফিল্টার করতে আপনার নিয়ামক এই সুযোগগুলি ব্যবহার করতে পারে:

app/controllers/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

অবশ্যই, এর কিছু পরিষ্কারের প্রয়োজন

আপনি দেখতে পাচ্ছেন কিভাবে এই কোডটি দুর্বোধ্য এবং পুনরাবৃত্তিমূলক হতে শুরু করে! অবশ্যই, আপনি রুবি ব্যবহার করছেন, তাই আপনি এটি একটি লুপে স্টাফ করতে পারেন:

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

# 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

একটি আরও পুনঃব্যবহারযোগ্য সমাধান

আপনি এই কোডটিকে একটি মডিউলে স্থানান্তর করতে পারেন এবং ফিল্টারিং সমর্থন করে এমন যেকোনো মডেলে এটি অন্তর্ভুক্ত করতে পারেন:

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 রাখলাম সংক্ষেপে আপনার নিজের প্রকল্পে এটি ব্যবহার করে দেখুন, এটি আমার অনেক সময় এবং কোড বাঁচিয়েছে৷

আপডেট: কিছু নির্দেশ করার জন্য জ্যান স্যান্ডব্রিঙ্ককে ধন্যবাদ:filtering_params-এ সাদাতালিকাভুক্ত প্যারামগুলি ভুলে যাওয়া সহজ . আপনি ভুলে গেলে, এটি আপনার অ্যাপকে গুরুতর পর্যন্ত খুলতে পারে নিরাপত্তা সমস্যা।

সেগুলি এড়াতে, status নামের স্কোপগুলি ব্যবহার করার পরিবর্তে , location , এবং starts_with , আমি এই নিবন্ধটি আপডেট করেছি সেই স্কোপের নাম এখন filter_by_status , filter_by_location , এবং filter_by_starts_with . সেগুলি আরও পরিষ্কার এবং নিরাপদ৷

একটি গুরুত্বপূর্ণ সতর্কতা

আপনার ওয়েব অ্যাপে মৌলিক অনুসন্ধান এবং ফিল্টারিং পাওয়ার একটি সহজ উপায় হল স্কোপে প্যারাম পাঠানো। কিন্তু আপনি যদি সতর্ক না হন, এবং আপনার ব্যবহারকারীরা যা পাঠান তা গ্রহণ না করলে, আপনার অ্যাপে বেশ কিছু বাজে নিরাপত্তা বাগ থাকতে পারে।

বিশেষ করে, order এসকিউএল ইনজেকশনের জন্য ঝুঁকিপূর্ণ। তাই আপনি যদি আপনার সাজানোর ক্রম সংজ্ঞায়িত করতে প্যারাম ব্যবহার করেন, তাহলে আপনার উচিত সর্বদা আপনার ব্যবহারকারী আপনাকে যে কলামের নাম পাঠাচ্ছেন তা পরীক্ষা করুন এবং শুধুমাত্র আপনার জানা মানগুলিকে নিরাপদ রাখার অনুমতি দিন৷

Rails SQL ইনজেকশন সাইট আপনাকে কোন ActiveRecord পদ্ধতিগুলি দুর্বল সে সম্পর্কে জানতে সাহায্য করবে, যাতে আপনি আপনার অ্যাপকে সুরক্ষিত রাখতে পারেন৷

আপনি কি ভিডিও দিয়ে আরও ভাল শিখতে পারেন?

একটি একেবারে নতুন অ্যাপ শুরু করা থেকে শুরু করে সার্চ এবং ফিল্টারিং যোগ করা পর্যন্ত, সঙ্গী স্ক্রিনকাস্টে আপনি প্রতিটি ধাপ দেখতে পারেন। আমরা একটি অ্যাপ তৈরি করব, নমুনা ডেটা দিয়ে এটি পূরণ করব, একটি অনুসন্ধান ফর্ম যোগ করব এবং এটিকে সংযুক্ত করব। এবং আপনি ভিডিওগুলির সাথে উত্সটি পাবেন, যাতে আপনি যখন আপনার নিজস্ব রেল অ্যাপগুলিতে সহজ অনুসন্ধান এবং ফিল্টারিং যোগ করেন তখন আপনি ফিরে উল্লেখ করতে পারেন৷

স্ক্রিনকাস্ট সম্পর্কে এখানে আরও জানুন!


  1. আপনার রেল অ্যাপে DynamoDB ব্যবহার করা

  2. কেন এবং কিভাবে AWS ElasticBeanstalk এবং RDS এর সাথে আপনার Rails 6 অ্যাপ হোস্ট করবেন

  3. আপনার SQL ডেটাতে ইলাস্টিক সার্চ-চালিত অনুসন্ধান এবং ভিজ্যুয়ালাইজেশন যোগ করুন

  4. কিভাবে আপনার Bing অনুসন্ধান ইতিহাস দেখতে এবং মুছে ফেলতে হয়