রেইলস কন্ট্রোলারে সার্চিং, সর্টিং, এবং ফিল্টারিং পেইনফুল হতে পারে। ElasticSearch এবং Solr চমৎকার, হাই-পাওয়ারড সমাধান, কিন্তু একটি ছোট অ্যাপের জন্য বড় ডিপেন্ডেন্সি।
সৌভাগ্যে, রেইলসে স্কোপস আছে, যা সিম্পল সার্চিং, ফিল্টারিং, এবং সর্টিং-এর জন্য আপনার প্রয়োজনীয় অনেক কিছু দিতে পারে। আপনি যদি স্কোপ চেইনিংয়ের সুবিধা নেন, তবে বড় ডিপেন্ডেন্সি নেওয়া ছাড়া বা রিপিটেটিভ সার্চ কোড লিখা ছাড়া আপনি চাওয়া ফিচারগুলো বিল্ড করতে পারেন।
স্কোপস দিয়ে সার্চিং
আপনার RESTful কন্ট্রোলারের একটি #index মেথড কল্পনা করুন যা প্রোডাক্টের একটি টেবিল দেখায়। প্রোডাক্টগুলো এক্টিভ, পেন্ডিং, বা ইনएक্টিভ হতে পারে, একটি লোকেশনে উপলব্ধ, এবং একটি নাম থাকে।
আপনি যদি এই প্রোডাক্টগুলো ফিল্টার করতে চান, তবে আপনি কিছু স্কোপ লিখতে পারেন:
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")
# => 'Ruby' দিয়ে শুরু হওয়া সব এক্টিভ প্রোডাক্ট
আপনার কন্ট্রোলার এই স্কোপগুলো ব্যবহার করে আপনার রেজাল্ট ফিল্টার করতে পারে:
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
স্পষ্টতই এটিকে কিছু ক্লিনআপ দরকার
আপনি দেখতে পাচ্ছেন কীভাবে এই কোড অনরুলি এবং রিপিটেটিভ হতে শুরু করে! অবশ্য, আপনি রুবি ব্যবহার করছেন, তাই আপনি এটিকে একটি লুপে ঠেলে দিতে পারেন:
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
একটি আরও রিযusable সমাধান
আপনি এই কোডটি একটি মডিউলে মুভ করে যেকোনো ফিল্টারিং সাপোর্ট করা মডেলে ইনক্লুড করতে পারেন:
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
class Product
include Filterable
...
end
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 SQL ইনজেকশনের জন্য ভালনरेबल। তাই আপনি যদি প্যারাম ব্যবহার করে আপনার সর্ট অর্ডার ডিফাইন করেন, তবে আপনাকে সবসময় আপনার ইউজার যা পাঠাচ্ছে সেটি চেক করতে হবে এবং শুধু সেই ভ্যালু আলাউ করুন যেগুলো আপনি জানেন সেফ।
Rails SQL Injection সাইট আপনাকে শিখাবে কোন ActiveRecord মেথডগুলো ভালনरेबल, যাতে আপনি আপনার অ্যাপ সিকিউর রাখতে পারেন।
ভিডিও দিয়ে ভালো শিখেন?
আপনি প্রতিটি স্টেপ দেখতে পারেন, একটি ব্র্যান্ড নিউ অ্যাপ শুরু করার থেকে সার্চিং এবং ফিল্টারিং যোগ করার পর্যন্ত, কম্পানিয়ন স্কリーনকাস্টে। আমরা একটি অ্যাপ তৈরি করব, স্যাম্পল ডেটা দিয়ে ফিল করব, একটি সার্চ ফর্ম যোগ করব, এবং ইটকে হুক আপ করব। এবং আপনি ভিডিওর সাথে সোর্সও পাবেন, যাতে আপনি আপনার নিজের রেইলস অ্যাপে সিম্পল সার্চিং এবং ফিল্টারিং যোগ করার সময় রেফার করতে পারেন।
স্ক্রীনকাস্ট সম্পর্কে আরও জানুন!