𝗪𝗵𝗮𝘁 𝗖𝗹𝗮𝘂𝗱𝗲 𝗧𝗵𝗼𝘂𝗴𝗵𝘁 𝗛𝗲 𝗞𝗻𝗲𝘄 𝗔𝗯𝗼𝘂𝘁 𝗥𝗮𝗶𝗹𝘀 𝗖𝗮𝗹𝗹𝗯𝗮𝗰𝗸𝘀
আমি LineItem রেকর্ড এবং তাদের S3 ফাইলগুলো ডিলিট করার জন্য একটি rake task চালানোর চেষ্টা করছিলাম। আমি Order-এর মতো parent model-গুলোতে থাকা ব্যয়বহুল (expensive) callbackগুলো এড়াতে চেয়েছিলাম।
আমি Claude-এর কাছে সাহায্য চেয়েছিলাম। এটি আমাকে খুব আত্মবিশ্বাসের সাথে একটি উত্তর দিয়েছিল। কিন্তু সেটি ভুল ছিল।
Rails, counter cache এবং কেন আপনাকে AI-এর পরামর্শ যাচাই করতে হবে, সে সম্পর্কে আমি যা শিখেছি তা নিচে দেওয়া হলো।
𝗧𝗵𝗲 𝗣𝗿𝗼𝗯𝗹𝗲𝗺 LineItem, OrderItem-এর অন্তর্ভুক্ত। OrderItem, Order-এর অন্তর্ভুক্ত। উভয় ক্ষেত্রেই counter_cache এবং touch ব্যবহার করা হয়েছে। একটি LineItem ডিলিট করলে একটি cascade ট্রিগার হয়। এই cascade-এর ফলে shipping estimation এবং total recalculation-এর মতো ভারী কাজগুলো (heavy jobs) শুরু হয়ে যায়। CPU এবং S3 খরচ কমাতে আমার এই cascade থামানো প্রয়োজন ছিল।
𝗧𝗵𝗲 𝗔𝗜 𝗠𝗶𝘀𝘁𝗮𝗸𝗲
Claude skip_callback ব্যবহার করার পরামর্শ দিয়েছিল।
এটি একটি খারাপ ধারণা। skip_callback ক্লাসটিকে গ্লোবালি (globally) পরিবর্তন করে ফেলে। এটি আপনার অ্যাপের প্রতিটি thread-কে প্রভাবিত করে। যদি পুনরায় সক্রিয় করার আগেই আপনার কোড ক্র্যাশ করে, তবে আপনার callback গুলো চিরতরে বন্ধ হয়ে থাকবে।
এরপর আমি no_touching চেষ্টা করলাম। নিরাপদ থাকার জন্য আমি OrderItem এবং Order উভয় ক্ষেত্রেই কলটিকে wrap করেছিলাম।
টেস্টগুলো পাস করলেও কনসোলে ভিন্ন কিছু দেখা গেল। Order-এর timestamp তখনও পরিবর্তিত হচ্ছিল।
𝗧𝗵𝗲 𝗥𝗲𝗮𝗹 𝗥𝗲𝗮𝘀𝗼𝗻 সমস্যাটি ছিল counter_cache কীভাবে touch-এর সাথে কাজ করে তা নিয়ে।
- যখন আপনি
counter_cache: trueএবংtouch: trueএকসাথে ব্যবহার করেন, Rails সেগুলোকে bundle করে ফেলে। - এটি একটি মাত্র raw SQL
UPDATE ALLকমান্ড চালায়। - Raw SQL, ActiveRecord lifecycle-কে বাইপাস (bypass) করে।
- যেহেতু এটি lifecycle বাইপাস করে, তাই
after_commithooks কাজ করে না।
এটি একটি অদ্ভুত প্যারাডক্স (paradox) তৈরি করেছিল:
- raw SQL bundle-এর কারণে OrderItem callback গুলো কাজ করেনি।
- Order callback গুলো কাজ করেছিল কারণ চেইনের পরবর্তী ধাপটি ছিল একটি সাধারণ touch।
𝗧𝗵𝗲 𝗙𝗶𝘅
আমার শুধু grandparent-কে no_touching-এর মধ্যে wrap করা প্রয়োজন ছিল।
Order.no_touching { line_item.destroy! }
এটি AR-level touch-কে Order model-এ পৌঁছাতে বাধা দেয়। এটি OrderItem-এর raw SQL থামায় না, তবে তাতে কিছু যায় আসে না কারণ counter cache bundle ইতিমধ্যেই সেই callback গুলোকে স্কিপ করে ফেলে।
𝗞𝗲𝘆 𝗧𝗮𝗸𝗲𝗮𝘄𝗮𝘆𝘀
counter_cache: true+touch: true= raw SQLUPDATE ALL।- Raw SQL সমস্ত
after_commithooks স্কিপ করে। - একটি সাধারণ touch (counter cache ছাড়া) স্ট্যান্ডার্ড AR lifecycle অনুসরণ করে এবং callback ট্রিগার করে।
- AI কোডকে কখনো অন্ধভাবে বিশ্বাস করবেন না। Claude আপনাকে একটি উত্তর দিতে চায়, কিন্তু সেই উত্তরটি একটি hallucination কি না, তা নিয়ে সে মাথা ঘামায় না।
সবসময় Rails console-এ আপনার ধারণাগুলো পরীক্ষা করে দেখুন। আপনি যে আচরণটি বন্ধ করতে চান তা আসলেই বন্ধ হচ্ছে কি না তা দেখতে ইচ্ছা করে কোডটি ভেঙে দেখুন।
Optional learning community: https://t.me/GyaanSetuAi