تجاوز "البحث" في ActiveRecord بطريقة DRY
-
09-06-2019 - |
سؤال
لدي بعض النماذج التي تحتاج إلى وضع شروط بحث مخصصة عليها.على سبيل المثال، إذا كان لدي نموذج جهة اتصال، ففي كل مرة يتم فيها استدعاء Contact.find، أرغب في تقييد جهات الاتصال التي يتم إرجاعها والتي تنتمي فقط إلى الحساب قيد الاستخدام.
لقد وجدت هذا عبر Google (الذي قمت بتخصيصه قليلاً):
def self.find(*args)
with_scope(:find => { :conditions => "account_id = #{$account.id}" }) do
super(*args)
end
end
يعمل هذا بشكل رائع، باستثناء بعض المناسبات التي يكون فيها account_id غامضًا، لذا قمت بتعديله ليناسب:
def self.find(*args)
with_scope(:find => { :conditions => "#{self.to_s.downcase.pluralize}.account_id = #{$account.id}" }) do
super(*args)
end
end
هذا أيضًا يعمل بشكل رائع، ولكن أريد أن يكون جافًا.لدي الآن بعض النماذج المختلفة التي أريد استخدام هذا النوع من الوظائف فيها.ما هي أفضل طريقة للقيام بذلك؟
عند الإجابة، يرجى تضمين الكود لمساعدة عقولنا على فهم البرمجة الوصفية روبي فو.
(أنا أستخدم الإصدار 2.1 من Rails)
المحلول
لا تخبرنا بإصدار Rails الذي تستخدمه [تحرير - إنه موجود على Rails 2.1 وبالتالي فإن النصيحة التالية تعمل بكامل طاقتها]، لكنني أوصيك باستخدام النموذج التالي بدلاً من التحميل الزائد على نفسك:
account.contacts.find(...)
سيؤدي هذا تلقائيًا إلى التفاف البحث في نطاق يتم فيه تضمين جملة المستخدم (نظرًا لأن لديك account_id أفترض أن لديك الحساب في مكان ما قريب)
أقترح عليك التحقق من الموارد التالية على النطاقات
نصائح أخرى
نصيحة جان سليمة.بافتراض أن نماذجك تبدو كما يلي:
class Contact < ActiveRecord::Base
belongs_to :account
end
class Account < ActiveRecord::Base
has_many :contacts
end
يجب أن تستخدم contacts
ربط الحساب الجاري للتأكد من أنك تحصل عليه فقط Contact
السجلات التي تم تحديد نطاقها لهذا الحساب، مثل ذلك:
@account.contacts
إذا كنت ترغب في إضافة المزيد من الشروط إلى استعلام جهات الاتصال الخاصة بك، فيمكنك تحديدها باستخدام البحث:
@account.contacts.find(:conditions => { :activated => true })
وإذا وجدت نفسك تستعلم باستمرار عن المستخدمين المنشطين، فيمكنك إعادة تصميمه في نطاق مسمى:
class Contact < ActiveRecord::Base
belongs_to :account
named_scope :activated, :conditions => { :activated => true }
end
والتي ستستخدمها بعد ذلك مثل هذا:
@account.contacts.activated
لإعطاء إجابة محددة لمشكلتك، أقترح نقل الطريقة المذكورة أعلاه إلى وحدة ليتم تضمينها في النماذج المعنية؛لذلك كنت قد فعلت
class Contact
include NarrowFind
...
end
ملاحظة.احذر من هروب SQL من account_id، فمن المحتمل أن تستخدم ملف :conditions=>[".... =?", $account_id]
بناء الجملة.