
مرحبا اصدقاء ليس سراً أن العمل في مشاريع كبيرة ذات منطق معقد ، لا يصبح Active Record مساعداً ، بل يمثل عبئًا. تخيل أنك بحاجة إلى إنشاء استعلام معقد جدًا لـ PostgreSQL بطريقة أصلية (في لغة SQL فقط) ، حيث يجب أن يكون هناك عدد معين من المتغيرات. ولكن هناك واحد تافه غير سارة في Rails ، وظيفة تنفيذ الاستعلامات الأصلية لا تسمح باستخدام المجلدات المسماة. ولكن هناك حل :) تم اختباره وتنفيذه بنجاح في مشروع باستخدام Rails API 5.2 + Ruby 2.6.0 + Postgres 11.
لذلك ، أكثر قليلا عن المشكلة. الطريقة الرئيسية التي تسمح لك بتنفيذ استعلامات SQL الخاصة بك هي exec_query:
sql = 'SELECT id, name, desc FROM schema.news WHERE id=$1' bindings = [[nil, 100]] new = ActiveRecord::Base.connection.exec_query(sql, 'SQL', bindings).first
يوضح المثال أعلاه أن تكوين المجلدات يحدث ، بعبارة ملطفة ، من خلال مكان واحد ، عندما نحاول الحصول على الأخبار تحت الرقم 100 من قاعدة البيانات. لا يمكن تسمية الروابط ، ولكن يتم ترقيمها فقط. وهذا يعقد إلى حد كبير قراءة ودعم الاستعلامات الأصلية. بدلاً من ذلك ، يمكنك استخدام استدعاء الأسلوب find_by_sql لفئة الطراز:
sql = 'SELECT id, name, desc FROM schema.news WHERE id=:id' new = New.find_by_sql([sql, id: 100]).first
كل شيء أكثر متعة ومفهومة هنا. لكن السؤال هو ، هذا مقبول أو أكثر إذا كنت تريد تنفيذ طلب بسيط. ولكن إذا كان الطلب معقدًا بالفعل ، فإن تشغيله من خلال النموذج و Active Record نفسه يمثل خسارة كبيرة في السرعة (ببطء) والأداء (يستهلك موارد الخادم). لماذا لا توجد مجلدات مسماة عند العمل مع الاستعلامات الأصلية يعد لغزًا بالنسبة لي ، ولكن هناك حلًا - اكتب برنامج التغليف الصغير الخاص بي ، والذي يمكنه العمل مع المجلدات المُسماة بكل بساطة ، وهو ما قمت به.
أحمل رمز الفئة الساكنة:
كما ترون من الكود ، كل شيء بسيط مثل ركن المنزل. يعمل الاستعلام مثل هذا:
sql = 'SELECT id, name, desc FROM schema.news WHERE id=:id' binding = { id: 100 } new = SqlQuery.execute(sql, binding).first
الإخراج هو دائما مجرد تجزئة. شرح قليلا. تأخذ طريقة التنفيذ سلسلة استعلام وتجزئة مع المجلدات. من الواضح أن الارتباطات الموجودة في الطلب والتجزئة يجب أن تتطابق. بعد ذلك ، نقوم بالتجول بين التجزئات مع المجلدات واستبدالها بمتغيرات مرقمة من النموذج $ 1 ، $ 2 ، وما إلى ذلك في الطلب نفسه ، وإنشاء مجموعة من القيم المرقمة في نفس الوقت ، حيث يكون العنصر الأول للصفيف هو $ 1 ، والثاني هو $ 2 ، وهكذا. ثم ننفذ الاستعلام باستخدام طريقة exec_query القياسية ، ونعمل من خلال الاستجابة مع المخطط ونحول المفاتيح الموجودة في التجزئة إلى أحرف. بعد ذلك ، يتم تشغيل المخطط مرة أخرى وفقًا للإجابة ، حيث نتحقق من كل قيمة حقل لمحتوى JSON فيها. إذا كان هناك JSON وكان صالحًا ، فقم بتحويله إلى تجزئة تحتوي على مفاتيح ورموز ، وإذا لم يكن الحقل هو JSON ، فقم بإلقاء استثناء نعيد فيه القيمة. هذا كل شيء.
كما ترون ، ليس من المنطقي وضع المئات من جميع أنواع الأحجار الكريمة ، وتبديد الأداء العام ، من أجل الحصول على النتيجة المرجوة. يمكنك كتابة العديد من القرارات اللازمة بسرعة كبيرة بنفسك ، بعد أن قضيت ما لا يقل عن الوقت والكود.
روابط إلى جيثب وقطع الجواهر مع البرنامج المساعد:
github.com/kirill-dan/active_sql_bindingsrubygems.org/gems/active_sql_bindingsحظا سعيدا للجميع ، أراك قريبا.
طبع من بلوق الخاص بك. الأصل
هنا