شروط مع ربط المتغيرات المعلمات الاختيارية
-
10-07-2019 - |
سؤال
دعونا نقول لدي شكل حيث يمكن للمستخدمين البحث عن شخص يبدأ اسمه مع معين 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]} : {}) } }
وآمل أن يساعد