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

স্ট্রিমলাইনড ভ্যালিডেশন: আর্টিকেল ওয়ার্কফ্লোতে ড্রাফ্ট থেকে পাবলিশ পর্যন্ত

(এই পোস্ট আমি আমার লিস্টে কয়েক মাস আগে পাঠিয়েছিলাম। আপনি যদি পছন্দ করেন, এবং এরকম আরো পড়তে চান, তবে সাইন আপ করুন!)

আমার একটি অ্যাপ্লিকেশনে একদিন একটি অদ্ভুত পরিস্থিতি встреতে হলো।

মনে করুন আপনার একটি Article মডেল আছে, এবং এই আর্টিকেলগুলো প্রথমে ড্রাফ্ট হিসেবে তৈরি হয়। এই ড্রাফ্টগুলো লাইটওয়েট হওয়া উচিত। আপনি চান সেগুলো তাত্ক্ষণিক তৈরি ও এডিট করতে পারেন, বডি বা এমনকি টাইটেল ছাড়া।

তবে আপনি যখন এই আর্টিকেলগুলো পাবলিশ করেন, আপনাকে কিছু এক্সট্রা ভ্যালিডেশন দরকার। সেগুলোকে টাইটেল, বডি, এবং বাকি সব থাকা উচিত।

আপনি কয়েকটি if স্টেটমেন্ট লিখে চেকিং করতে পারেন। কিন্তু আপনাকে রেইলস থেকে मिलে সেরা ফর্ম হ্যান্ডলিং নেই। এবং আমি বের করেছি যে রেইলস যেসব জিনিস ভালো হ্যান্ডেল করে সেগুলো রেইলস দিয়ে করলে পরে অনেক মাথাব্যাথা বাঁচায়। এটা করার জন্য ভ্যালিডেশন ব্যবহার করার উপায় আছে কি?

if এবং unless?

ভ্যালিডেশন :if এবং :unless প্যারামিটার সাপোর্ট করে, কিন্তু এটা সবসময় ক্লিন নয়:

app/models/article.rb
class Article < ActiveRecord::Base # validate in draft mode validates_presence_of :author_id # validate only when published validates_presence_of :body, unless: lambda { |o| o.draft? } ... end

এর বাইরেও, আর্টিকেল পাবলিশ করার আমার পছন্দের উপায় এটা নয়। আমি আর্টিকেল পাবলিশ করার একটি অ্যাকশন হিসেবে চিন্তা করতে চাই, নাকি আর্টিকেল যে স্টেট-এ আছে সেটা হিসেবে না, তাই একটি অ্যাট্রিবিউট সেট ও চেক করা সঠিক জবাব নয়।

একটি কম পরিচিত, কম ডকুমেন্টেড রেইলস ফিচার

এই সমস্যা রেইলসের ভ্যালিডেশন কনটেক্সটের জন্য পर्फেক্ট ফিট। আমি কাস্টম ভ্যালিডেশন কনটেক্সট সম্পর্কে প্রথম জানলাম DHH-এর একটি গিস্ট থেকে। কিন্তু এটা কী, এবং কীভাবে ব্যবহার করবেন সেটা সম্পর্কে ভালো এক্সপ্লানেশন খুঁজে পাওয়া কঠিন ছিল।

কাস্টম কনটেক্সটের ডকুমেন্টেশন খুব থিন। API ডক্সে এর একমাত্র উल्लেখ ছিল এখানে। এবং এই ভ্যালিডেশনগুলোর API ডক্সে কাস্টম কনটেক্সটের কোনো উল্লেখ নেই! এটা এটা স্পেশালি কঠিন করে দেয় - আপনি যদি না জানেন কোনো জিনিসের নাম কী, তবে সেটা সম্পর্কে আরও ডকুমেন্টেশন কীভাবে খুঁজবেন?

আমি অবশেষে একটি ভালো ওভারভিউ পেলাম এখানে: https://blog.arkency.com/2014/04/mastering-rails-validations-contexts/. এটি পড়ার লायक। আমাদের উদাহরণের জন্য কেমন দেখায়:

app/models/article.rb
class Article < ActiveRecord::Base # validate in draft mode validates_presence_of :author_id # validate only when published validates_presence_of :body, on: :publish ... end
app/controllers/article_controller.rb
class ArticleController < ApplicationController respond_to :html def create @article = Article.create(article_params) respond_with @article end def publish @article = Article.find(params[:id]) @article.attributes = article_params @article.save(context: :publish) respond_with @article end private def article_params params. require(:article). permit(:body, :title, :author_id) end end

খারাপ নয়! একটু অদ্ভুত জিনিস হলো পাবলিশ মেথডে update-এর বদলে save ব্যবহার করতে হচ্ছে। এটা হয় কারণ update ভ্যালিডেশন কনটেক্সট প্যারামিটার হিসেবে নিতে পারে না। (হয়তো এটা একটি পুল রিকোয়েস্টের সুযোগ?)

সেভিং এর বাইরে

কাস্টম ভ্যালিডেশন কনটেক্সট সেভিং-এ আলাদা ভাবে রেকর্ড সেভ করার বাইরেও কাজে আসে। কনটেক্সট valid?-এর সাথে কাজ করে:

@article.valid?(:publish)

তাই আপনি ভ্যালিডেশন কনটেক্সট যেকোনো জায়গায় ব্যবহার করতে পারেন আপনি যখন জানতে চান: "এই অবজেক্টে এই প্রোপার্টি আছে কি? এবং না থাকলে, কেন না?"

DHH একটি মেথড বানান যা -able? দিয়ে এন্ড হয় এবং valid?(:context)-এ ডেলিগেট করে। আমি সেটার লুক খুব পছন্দ করি:

app/models/article.rb
class Article validate :has_been_published, on: :view validate :is_not_spam, on: :view def viewable? valid? :view end private def has_been_published if published_at.future? errors.add(:published_at, "is in the future") end end def is_not_spam if is_spam?(body) errors.add(:body, "has been detected as spam") end end end

এভাবে, আপনি চেক করলে, আপনি শুধু true বা false নয়, আরও ইনফরমেশন পাবেন:

unless @article.viewable? # @article.errors এখন পূর্ণ হবে end

আর্টিকেল ভিউএবল কিনো? ঠিক নাহলে কেন?

শুধু যতটা লাইটওয়েট দরকার

এই ধরনের ভ্যালিডেশন বিহেভিয়ার পাওয়ার আরও কয়েকটি উপায় আছে। আপনি কাস্টম ActiveModel সার্ভিস অবজেক্ট বানাতে পারেন তাদের নিজস্ব ভ্যালিডেশনসহ। আপনি আপনার ভ্যালিডেশনগুলোর ওপর :if বা :unless ব্যবহার করতে পারেন। তবে রেইলসে অনেক জিনিসের মত, কাস্টম ভ্যালিডেশন কনটেক্সট পঠনযোগ্যতা এবং ফ্লেক্সিবিলিটির মধ্যে একটি ভালো কম্পromise।

  1. Enlightenment ডেস্কটপ রিভিউ: একটি সুন্দর, হালকা কিন্তু ভিন্ন ডেস্কটপ ম্যানেজার

  2. যেকোনো Rack অ্যাপ্লিকেশনে ইনকামিং ইমেইল সিমলেসলি প্রসেস করুন

  3. রেইলস পারফরম্যান্সে দক্ষতা: অ্যাপ্স ডায়াগনোজ ও ত্বরান্বিত করার প্রামাণিক পদ্ধতি

  4. রেইলসে জেম ম্যানেজমেন্ট: Bundler এবং RubyGems কীভাবে একসাথে কাজ করে