بناء شروط سجل نشطة في صفيف - طريقة خاصة "مسح" تسمى الخطأ
سؤال
أحاول بناء مجموعة من الشروط ديناميكيًا باستخدام صفيف كما هو مقترح في الإجابة الأولى هنا: واحد أو أكثر من المعاملات في النموذج ابحث عن الظروف مع روبي على القضبان. ومع ذلك ، يبدو أنني أقوم بشيء غير صحيح ، ولست متأكدًا مما إذا كان ما أحاول غير سليم بشكل أساسي أو إذا كنت ببساطة أسرع بناء الجملة الخاص بي.
أقوم بتبسيط إلى حالة واحدة هنا لمحاولة توضيح المشكلة حيث حاولت بناء دليل بسيط للمفهوم على هذا المنوال قبل أن أضع على أنماط الحالة الخمسة المختلفة التي أتنافس عليها.
هذا يعمل:
excluded.push 12
excluded.push 30
@allsites = Site.all(:conditions => ["id not in (?)", excluded])
يؤدي هذا إلى طريقة خاصة "مسح" تسمى الخطأ:
conditionsSet = []
excluded.push 12
excluded.push 30
conditionsSet << ["id not in (?)", excluded]
@allsites = Site.all(:conditions => conditionsSet)
شكرا على أي نصيحة. لم أكن متأكدًا مما إذا كان الشيء الصحيح هو وضع هذا كعنصر متابعة في السؤال/الإجابات ذات الصلة التي لاحظتها في الأعلى. منذ أن واجهت مشكلة وليس إجابة. إذا كانت هناك طريقة أفضل لنشر هذا الأمر المتعلق بالمنصب الحالي ، فيرجى إخبارنا بذلك.
المحلول
جرب هذا:
القضبان 2.3
class Site < ActiveRecord::Base
def self.build_conditions(ids, name=nil, state=nil)
cond = []
cond << send(:sanitize_sql_array, ["id NOT IN (?)", ids]) unless ids.empty?
cond << send(:sanitize_sql_array, ["name = ? ", name]) unless name
cond << send(:sanitize_sql_array, ["state = ? ", state]) unless state
cond.join(" and ")
end
end
الآن في مكان ما في وحدة التحكم الخاصة بك:
Site.all(:conditions => Site.build_conditions([1,2]))
Site.all(:conditions => Site.build_conditions(nil, "ABC"))
القضبان 3
class Site < ActiveRecord::Base
def self.exclude_ids_by_name_and_state(ids, name=nil, state=nil)
result = scoped
result = result.where("id NOT IN (?)", ids) if ids.present?
result = result.where(:name => name) if name.present?
result = result.where(:state => state) if state.present?
result
end
end
الآن في مكان ما في وحدة التحكم الخاصة بك:
Site.exclude_ids_by_name_and_state([1,2])).all
Site.exclude_ids_by_name_and_state(nil, "ABC").all
نصائح أخرى
انت تريد:
conditionsSet += ["id not in (?)", excluded]
بدلاً من:
conditionsSet << ["id not in (?)", excluded]
+=
يضيف المصفمين معًا (فكر في الأمر على أنه دمج الاثنين في صفيف واحد) <<
يدفع عنصر جديد على الصفيف. لذلك أنت تحصل على: [["id not in (?)", excluded]]
عند استخدام <<
, ، و :conditions
يريد صفيف حيث هذا العنصر الأول هو سلسلة (وليس صفيف).
محاولة SmartTuple, إنه مصمم خصيصًا لحالات كهذه.
def self.build_conditions(options = {})
[
SmartTuple.new(" AND "),
(["id NOT IN (?)", ids] if options[:ids].present?),
({:name => options[:name]} if options[:name].present?),
({:state => options[:state]} if options[:state].present?),
].sum.compile
end
...
Site.all(:conditions => Site.build_conditions(:ids => {1,2]))
Site.all(:conditions => Site.build_conditions(:name => "abc", :state => "disabled")
بالنسبة لي ، من الأفضل أيضًا الاستخدام options
التجزئة بدلا من الحجج المطلوبة. مع نمو مشروعك ، قد يظهر المزيد من الظروف وستفقد مسارها. تبدو التجزئة وتصرفها أكثر وضوحًا بالإضافة إلى أنه يمكنك التحقق من صحةها بسهولة لتجنب أخطاء البرمجيات.