سؤال

أريد العثور على سجلات في مجموعة من create_on >= بعض التاريخ والاسم في بعض قوائم الأسماء.

بالنسبة لـ ">=" يجب أن أستخدم شرط SQL.بالنسبة إلى "IN" يجب أن أستخدم مجموعة من الشروط حيث يكون المفتاح هو:name والقيمة هي مجموعة الأسماء.

هل هناك طريقة للجمع بين الاثنين؟

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

المحلول

يمكنك استخدام النطاقات المسماة في Rails 2.1 وما فوق

Class Test < ActiveRecord::Base
  named_scope :created_after_2005, :conditions => "created_on > 2005-01-01"
  named_scope :named_fred, :conditions => { :name => "fred"}
end

ثم يمكنك القيام به

Test.created_after_2005.named_fred

أو يمكنك إعطاء name_scope رمز lambda الذي يسمح لك بتمرير الوسائط

Class Test < ActiveRecord::Base
  named_scope :created_after, lambda { |date| {:conditions => ["created_on > ?", date]} }
  named_scope :named, lambda { |name| {:conditions => {:name => name}} }
end

ثم يمكنك القيام به

Test.created_after(Time.now-1.year).named("fred")

نصائح أخرى

إذا كنت تستخدم إصدارًا أقدم من Rails، فسيكون استعلام Honza قريبًا، لكنك تحتاج إلى إضافة أقواس للسلاسل التي يتم وضعها في حالة IN:

Person.find(:all, :conditions => ["created_at > ? AND name IN (?)", date, names])

يمكن أن يكون استخدام IN عبارة عن حقيبة مختلطة:إنه الأسرع بالنسبة للأعداد الصحيحة والأبطأ بالنسبة لقائمة السلاسل.إذا وجدت نفسك تستخدم اسمًا واحدًا فقط، فاستخدم بالتأكيد عامل يساوي:

Person.find(:all, :conditions => ["created_at > ? AND name = ?", date, name])

الشيء الرائع في name_scopes هو أنها تعمل على المجموعات أيضًا:

class Post < ActiveRecord::Base
  named_scope :published, :conditions => {:status => 'published'}
end

@post = Post.published

@posts = current_user.posts.published

لمعرفة المزيد عن name_scopes، راجع اعلان ريان و ال Railscast على name_scopes

class Person < ActiveRecord::Base
  named_scope :registered, lambda { |time_ago| { :conditions => ['created_at > ?', time_ago] } }
  named_scope :with_names, lambda { |names| { :conditions => { :names => names } } }
end

إذا كنت ستقوم بتمرير المتغيرات إلى نطاقاتك، فيجب عليك استخدام لامدا.

يمكنك سلسلة where بند:

Person.where(name: ['foo', 'bar', 'baz']).where('id >= ?', 42).first

النطاقات المسماة المقترحة بالفعل جيدة جدًا.الطريقة الكلاسيكية للقيام بذلك ستكون:

names = ["dave", "jerry", "mike"]
date = DateTime.now
Person.find(:all, :conidtions => ["created_at > ? AND name IN ?", date, names])

أعتقد أنني سأستخدم مكتشفات الواقع المعزز البسيطة أو البحث عن النشوة.

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