আপনি রেল টিউটোরিয়াল শেষ করার পরে এবং আপনার নিজের অ্যাপ শুরু করার পরে, জিনিসগুলি বিভ্রান্তিকর হয়ে ওঠে। যেমন আপনার নন-CRUD, সাধারণ যুক্তি কোথায় যায়? টুইটার থেকে অনুগামীদের দখল কিভাবে MVC-তে ফিট করে? দুইজনকে জিজ্ঞাসা করুন, এবং আপনি চারটি উত্তর পাবেন। অথবা আপনার থ্রেড একগুচ্ছ স্মার্ট লোকে পরিণত হয় যারা ঘন্টার পর ঘন্টা একে অপরকে অপমান করে, যখন আপনি ডেস্কের বিরুদ্ধে আপনার মাথা মারেন। যেভাবেই হোক, আপনার মাথা ব্যাথা থাকবে।
আপনি কিছু ছাড়া যে অ্যাপটির স্বপ্ন দেখেছেন সেটি তৈরি করতে পারবেন না সাধারণ, নন-রেল যুক্তি। তাহলে আপনি আপনার কোড কোথায় রাখবেন, এবং এখনও জিনিসগুলি সহজ রাখবেন?
শুরু করার সহজ জায়গা
যখন আমার কাছে এমন যুক্তি থাকে যা একটি বিদ্যমান ActiveRecord মডেলের সাথে সম্পর্কিত মনে হয়, আমি এটিকে সেই মডেলে রেখে শুরু করব৷ উদাহরণস্বরূপ, যদি আমার একটি Game
থাকত মডেল এবং আমি CSV ফাইলগুলি থেকে একগুচ্ছ গেম আমদানি করতে চেয়েছিলাম, আমি সেই পদ্ধতিটিকে Game
-এ রাখতাম ক্লাস:
class Game < ActiveRecord::Base
def self.parse_from_csv(csv_string)
games = []
CSV.parse(csv_string, quote_char: "'") do |row|
games << Game.from_csv_row(row) if (row[0] == 'G')
end
games
end
def self.from_csv_row(row)
Game.new({
dgs_game_id: row[1],
opponent_name: row[2],
created_at: row[4],
updated_at: row[4],
})
end
end
আপনার কাছে আপনার পদ্ধতির প্রয়োজনীয় সমস্ত তথ্য রয়েছে। এটি সহজেই পরীক্ষাযোগ্য। এবং সম্ভবত এটিই যেখানে একজন নতুন অবদানকারী প্রথমে সেই যুক্তিটি খুঁজবেন।
কিন্তু আপনি যদি সেই মডেলটি যোগ করতে এবং পরিবর্তন করতে থাকেন তবে এটি বড় এবং জটিল হয়ে উঠবে। মডেলের বিভিন্ন অংশ অদ্ভুত উপায়ে যোগাযোগ করবে। যত বেশি আপনি এটি পরিবর্তন করবেন, এটি পরিবর্তন করা তত কঠিন হবে৷৷
সেক্ষেত্রে, আপনি সম্ভবত সেই কোডটিকে একটি নন-অ্যাক্টিভ রেকর্ড মডেলে রিফ্যাক্টর করতে চান।
Non-activeRecord মডেল
শুধুমাত্র একটি Rails অ্যাপে থাকার কারণে, এর অর্থ এই নয় যে এটিকে সক্রিয়/অ্যাকশন-যাই হোক না কেন থেকে উত্তরাধিকার সূত্রে প্রাপ্ত হতে হবে।
আপনি আপনার নিজের রুবি কোড, প্লেইন রুবি অবজেক্টে লিখতে পারেন এবং সেগুলি আপনার রেল অ্যাপে ব্যবহার করতে পারেন। এই বস্তুগুলিকে এখনও মডেল বলা যেতে পারে, কারণ তারা আপনার সমস্যার অংশ মডেলিং করছে। তাদের শুধুমাত্র তাদের ডেটা সংরক্ষণ করার জন্য একটি ActiveRecord ডাটাবেস নেই।
পরের বার যখন আমি সেই গেম CSV পার্সারে কাজ করি, Game
ক্লাস একটু বড় হয়ে যাচ্ছিল। তাই আমি পার্সার লজিকটিকে তার নিজস্ব GameCSVParser
-এ সরিয়ে নিয়েছি ক্লাস।
সম্পূর্ণ প্রতিশ্রুতি এখানে আছে, কিন্তু নন-অ্যাক্টিভরেকর্ড ক্লাসটি এইরকম দেখাচ্ছে:
class GameCSVParser
def initialize(csv_string)
@rows = CSV.parse(csv_string, quote_char: "'")
end
def games
game_rows.map { |row| Game.new(game_attributes(row)) }
end
private
def game_rows
@rows.select { |row| is_game_row?(row) }
end
def game_attributes(row)
{
dgs_game_id: row[1],
opponent_name: row[2],
created_at: row[4],
updated_at: row[4],
}
end
def is_game_row?(row)
row[0] == 'G'
end
end
আমি যে যুক্তি যোগ করছি তা কোনো নির্দিষ্ট ActiveRecord মডেলের সাথে সম্পর্কিত না হলে আমি একটি নতুন প্লেইন রুবি অবজেক্ট তৈরি করতে যাব। অথবা যদি কোডটি মনে হয় এটি এমন একটি জিনিসের অংশ হওয়া উচিত যা এখনও অ্যাপে বিদ্যমান নেই। অন্যথায়, তারা বেশিরভাগ রিফ্যাক্টরিংয়ের মাধ্যমে পপ আপ করে।
প্লেইন রুবি অবজেক্টের সাহায্যে আপনি যেকোনো কিছু লিখতে পারেন। কিন্তু জেনে আপনি যেকোন কিছু লিখতে পারেন আপনাকে দিকনির্দেশনা দিয়ে সাহায্য করে না। আপনি কি পদ্ধতি প্রয়োজন? আপনার সমস্ত নতুন বস্তু কিভাবে ইন্টারঅ্যাক্ট করবে?
অনেক রেল অ্যাপ একই বিভাগ ব্যবহার করে সাধারণ রুবি বস্তুর। এই বিভাগগুলি হল প্যাটার্ন যা আপনি কোড লিখতে অনুসরণ করতে পারেন যা অন্যান্য বিকাশকারীরা চিনতে পারে। আপনি হয়তো ইতিমধ্যেই তাদের কয়েকটির কথা শুনেছেন৷
৷পরিষেবার বস্তু, উপস্থাপক এবং কাজ
পরিষেবার বস্তু, উপস্থাপক এবং চাকরি সম্পর্কে বিশেষ কিছু নেই। এগুলি কেবল সাধারণ রুবি বস্তু যা একটি নির্দিষ্ট স্বীকৃত উপায়ে কাজ করে৷
উদাহরণস্বরূপ, একটি Resque কাজ একটি প্লেইন রুবি ক্লাস যার একটি perform
আছে পদ্ধতি এবং একটি @queue
:
class FetchGamesForPlayer
@queue = :default
def self.perform(player_id)
player = Player.scoped_by_id(player_id).ready_for_fetching.first
player && player.fetch_new_games!
end
end
perform
যখন কাজ চালানো হয় তখন বলা হয়৷
একজন উপস্থাপক কোড সহ একটি সাধারণ রুবি অবজেক্ট যা শুধুমাত্র একটি ভিউ এর মধ্যেই বোঝা যায়:
class UserPresenter
def show_related_users?
@user.related.count > 3
end
end
এতে রেলের ভিউ হেল্পারও অন্তর্ভুক্ত থাকতে পারে, অথবা কয়েকটি ভিন্ন অবজেক্ট নিতে পারে এবং ভিউয়ের সুবিধার জন্য সেগুলিকে একটি ইউনিফাইড অবজেক্ট হিসেবে বিবেচনা করতে পারে।
একটি পরিষেবা বস্তু একটি সাধারণ রুবি বস্তু যা আপনি সম্পাদন করতে চান এমন একটি প্রক্রিয়াকে প্রতিনিধিত্ব করে। উদাহরণস্বরূপ, একটি পোস্টে একটি মন্তব্য লিখতে পারে:
- মন্তব্য করুন।
- পোস্টের লেখককে একটি বিজ্ঞপ্তি মেল পাঠান।
একটি পরিষেবা বস্তু উভয়ই করতে পারে এবং সেই যুক্তিটিকে আপনার কন্ট্রোলারের বাইরে রাখতে পারে।
এখানে পরিষেবা বস্তুর উপর একটি মহান গ্রহণ আছে. এটা উদাহরণে পূর্ণ।
সাধারণ প্রক্রিয়াগুলির জন্য, আমি পরিষেবার বস্তু নিয়ে বিরক্ত করি না৷৷ কিন্তু যদি কন্ট্রোলার খুব ভারী হতে শুরু করে, তাহলে সেই অতিরিক্ত যুক্তি দেওয়ার জন্য তারা একটি ভাল জায়গা।
আপনি আপনার নিজের ব্যবসা যুক্তি সংগঠিত করতে এই নিদর্শন ব্যবহার করতে পারেন. এগুলি কেবল সাধারণ রুবি বস্তু, তবে এগুলি হল রুবি বস্তু যা একটি নির্দিষ্ট স্বাদ ভাগ করে, যার একটি নাম রয়েছে এবং আপনি অন্য বিকাশকারীদের সাথে কথা বলতে পারেন৷
আপনি কোথায় শুরু করবেন?
আপনার নন-রেল ব্যবসায়িক যুক্তিতে অনেকগুলি বিভিন্ন জায়গায় যেতে পারে। এটা নির্বাচন করা কঠিন হতে পারে. তাই আমি যা করি তা এখানে:
- যদি যুক্তিটি বেশিরভাগই বিদ্যমান ক্লাসের সাথে সম্পর্কিত হয়, এমনকি এটি একটি ActiveRecord মডেল হলেও, আমি এটিকে সেই ক্লাসে রাখি।
- যদি এটি একটি বিদ্যমান ক্লাসের সাথে মানানসই না হয়, আমি যুক্তি ধরে রাখার জন্য একটি নতুন প্লেইন রুবি ক্লাস তৈরি করি৷
- যদি মনে হয় যুক্তি এমন কিছুর অংশ হওয়া উচিত যা এখনও বিদ্যমান নেই, আমি এটির জন্য একটি নতুন সাধারণ রুবি ক্লাস তৈরি করব।
- যদি আমি পরে কোডে ফিরে আসি, এবং মডেলটি খুব জটিল হয়ে উঠছে, বা সেই মডেলে কোডটির আর কোনো মানে হয় না, আমি এটিকে তার নিজস্ব প্লেইন রুবি ক্লাসে রিফ্যাক্ট করব।
- কোডটি যদি শুধুমাত্র একটি দৃশ্যের মধ্যেই বোধগম্য হয়, তাহলে আমি এটিকে একজন সাহায্যকারীতে যোগ করব বা একটি উপস্থাপক তৈরি করব৷
- কোডটি HTTP অনুরোধের সময় চালানোর প্রয়োজন না হলে বা ব্যাকগ্রাউন্ডে চালানোর প্রয়োজন না হলে, এটি একটি কাজে চলে যায়৷
- যদি আমি একটি প্রক্রিয়ার বিভিন্ন মডেল বা পর্যায় নিয়ে কাজ করি, এবং এটি কন্ট্রোলারকে বুঝতে খুব কঠিন করে তোলে, আমি এটিকে একটি পরিষেবা বস্তুতে রাখব৷
তোমার কী অবস্থা? আপনার কোড কোথায় যায়? এবং আপনার কাছে কি এগুলি ছাড়াও কোনও নিদর্শন আছে যা আপনি সহায়ক বলে মনে করেছেন? একটি মন্তব্য করুন এবং আমাকে জানান৷৷
এবং যদি আপনার এখনও কোনও প্রক্রিয়া না থাকে তবে আমার চেষ্টা করুন। দেখুন কিভাবে এটা আপনার জন্য মানায়। কোড লেখার কোনো নিখুঁত উপায় নেই, কিন্তু আপনি যখন আটকে যান, তখন এই ধরনের একটি প্রক্রিয়া আপনাকে শুরু করতে সাহায্য করবে।