سؤال

أحاول بناء مجموعة من الشروط ديناميكيًا باستخدام صفيف كما هو مقترح في الإجابة الأولى هنا: واحد أو أكثر من المعاملات في النموذج ابحث عن الظروف مع روبي على القضبان. ومع ذلك ، يبدو أنني أقوم بشيء غير صحيح ، ولست متأكدًا مما إذا كان ما أحاول غير سليم بشكل أساسي أو إذا كنت ببساطة أسرع بناء الجملة الخاص بي.

أقوم بتبسيط إلى حالة واحدة هنا لمحاولة توضيح المشكلة حيث حاولت بناء دليل بسيط للمفهوم على هذا المنوال قبل أن أضع على أنماط الحالة الخمسة المختلفة التي أتنافس عليها.

هذا يعمل:

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 التجزئة بدلا من الحجج المطلوبة. مع نمو مشروعك ، قد يظهر المزيد من الظروف وستفقد مسارها. تبدو التجزئة وتصرفها أكثر وضوحًا بالإضافة إلى أنه يمكنك التحقق من صحةها بسهولة لتجنب أخطاء البرمجيات.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top