سؤال

دعونا نقول لدي شكل حيث يمكن للمستخدمين البحث عن شخص يبدأ اسمه مع معين name سلسلة, على سبيل المثال, "مي" أن العثور على "مايك" و "ميغيل".ربما أود أن إنشاء تجد بيان مثل ذلك:

find(:all, :conditions => ['name LIKE ?', "#{name}%"])

دعونا نقول شكل أيضا اثنين من الحقول الاختيارية ، hair_color و eye_color التي يمكن استخدامها لمواصلة تصفية النتائج.تجاهل اسم جزء من الاستعلام تجد بيان للناس التي يمكن أن تتخذ في عدد التعسفي من المعلمات الاختيارية قد تبدو مثل هذا:

find(:all, :conditions => { params[:person] })

والتي بلدي اثنين من المعلمات الاختيارية تتصرف كما يعادل هذا:

find(:all, :conditions => { :hair_color => hair_color, :eye_color => eye_color })

ما لا أستطيع فهمه هو كيفية دمج هذين النوعين من الاستفسارات حيث المطلوب في الحقل "اسم" على "مثل" الشرط أعلاه ، الاختياري hair_color و eye_color المعلمات (وربما غيرها) يمكن أن تضاف إلى مزيد من تصفية النتائج.

أنا بالتأكيد يمكن بناء سلسلة الاستعلام للقيام بذلك ، ولكن أشعر يجب أن يكون هناك "القضبان الطريق" التي هي أكثر أناقة.كيف يمكنني دمج إلزامية ربط المعلمات الاختيارية المعلمات ؟

هل كانت مفيدة؟

المحلول

هذا هو الكمال استخدام اسم النطاق.

إنشاء نطاق اسمه في نموذج:

named_scope :with_name_like, lambda {|name|
  {:conditions => ['name LIKE ?', "#{name}%"]}
}

عند هذه النقطة يمكنك الاتصال

Model.with_name_like("Mi").find(:all, :conditions => params[:person])

و القضبان دمج الاستفسارات بالنسبة لك.

تحرير:رمز وسيم:

إذا كان اسم اختياري يمكنك إما حذف اسمه نطاق من أسلوب سلسلة مع إن الحالة:

unless name.blank?
   Model.with_name_like("Mi").find(:all, :conditions => params[:person])
else
   Model.find(:all, :conditions => params[:person])
end

أو يمكنك إعادة تسمية نطاق أن تفعل الشيء نفسه.

named_scope :with_name_like, lambda {|name|
  if name.blank?
    {}
  else
    {:conditions => ['name LIKE ?', "#{name}%"]}
  end
}

التحديث

هنا القضبان 3 الإصدار الأخير مقتطف الشفرة:

scope :with_name_like, lambda {|name|
  if not name.blank?
    where('name LIKE ?', "#{name}%")
  end
}

نصائح أخرى

لتتوافق أيضا مع طلب وسيم، ولكن لا شيء يسمح بدلا فارغة؟ (والذي هو udeful في حال كنت ترغب في استخدام "things = Thing.named_like (بارامس [: اسم])" مباشرة)

named_scope :named_like, lambda do |*args| 
  if (name=args.first)
    {:conditions => ["name like ?",name]}
  else
    {}
  end
end

# or oneliner version:

named_scope :named_like, lambda{|*args| (name=args.first ? {:conditions => ["name like ?",name]} : {}) } }

وآمل أن يساعد

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