इसे मॉडल करने का एक तरीका यहां दिया गया है। मान लें कि हमारे पास एक मॉडल 'सगाई' है जिसमें प्रारंभ डेटाटाइम, समाप्ति डेटाटाइम और नाम है। एक सहभागिता में 'user_engagements' नामक एक अन्य जॉइन टेबल के माध्यम से कई उपयोगकर्ता होते हैं (संबंधित UserEngagement मॉडल के साथ)। तो हमारे पास है
User
has_many :user_engagements
has_many :engagements, :through => :user_engagements
Engagement
#fields - starts_at, ends_at (both datetime)
has_many :user_engagements
has_many :users, :through => :user_engagements
UserEngagement
belongs_to :user
belongs_to :engagement
अब हमारे पास एक अच्छी सरल स्कीमा है। एक जुड़ाव मूल रूप से कुछ ऐसा मॉडल करता है जो हो रहा है, और user_engagements उन उपयोगकर्ताओं को मॉडल करता है जो उस काम को करने के लिए बुक किए गए हैं। हमारी एक धारणा है (कोड में नहीं लिखा है) कि जब वे कुछ कर रहे होते हैं तो वे कुछ और करने के लिए उपलब्ध नहीं होते हैं।
हमारा अगला कार्य एक ऐसी विधि लिखना है जो उपयोगकर्ताओं को एक निश्चित समय अवधि के भीतर उपलब्ध कराती है, अर्थात एक नया जुड़ाव। इसलिए, हम एक जुड़ाव बनाते हैं और हम उन सभी उपयोगकर्ताओं को चाहते हैं जिनकी सगाई नहीं है जो हमारी नई सगाई के साथ पार हो जाती है। मुझे लगता है कि ऐसा करने का सबसे आसान तरीका उन सभी उपयोगकर्ताओं को ढूंढना हो सकता है जिनके पास क्रॉसिंग-ओवर जुड़ाव है और फिर उन सभी उपयोगकर्ताओं को वापस कर दें जो वे नहीं हैं। क्या आपको पता है मेरा क्या मतलब है। यह कहने का एक और सटीक तरीका है कि e2 e1 के साथ क्रॉस ओवर करता है, यह है कि e2 e1 के अंत से पहले शुरू होता है और e1 के शुरू होने के बाद समाप्त होता है।
आइए इसे एंगेजमेंट ऑब्जेक्ट का एक तरीका बनाएं क्योंकि यह पूरी तरह से एंगेजमेंट के डेटा पर निर्भर है।
#in Engagement
def unavailable_user_ids
User.find(:all, :include => [:user_engagements], :select => "users.id", :conditions => ["user_engagements.starts_at < ? and user_engagements.ends_at > ?", self.ends_at, self.starts_at]).collect(&:id)
end
def available_users
User.find(:all, :conditions => ["id not in (?)", self.unavailable_user_ids])
end
मुझे लगता है कि इसे एक प्रश्न में प्राप्त करने का एक और अधिक कुशल तरीका है, लेकिन मैं अपनी उंगली को sql पर नहीं डाल सकता।