Đây là một cách để mô hình hóa nó. Giả sử chúng ta có một mô hình 'Tương tác' có ngày bắt đầu, ngày kết thúc và tên. Một tương tác có nhiều người dùng, thông qua một bảng tham gia khác được gọi là 'user_engagements' (với mô hình UserEngagement tương ứng). Vì vậy, chúng tôi có
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
Bây giờ chúng ta có một giản đồ đơn giản. Tương tác về cơ bản mô hình hóa điều gì đó đang xảy ra và user_engagements mô hình hóa những người dùng được đặt trước để làm điều đó. Chúng tôi có một giả định (không được viết trong mã) rằng khi họ đang làm một việc gì đó, họ sẽ không sẵn sàng để làm bất cứ điều gì khác.
Nhiệm vụ tiếp theo của chúng tôi là viết một phương thức trả về những người dùng có sẵn trong một khoảng thời gian nhất định, tức là một tương tác mới. Vì vậy, chúng tôi thực hiện tương tác và chúng tôi muốn tất cả những người dùng không có tương tác sẽ chuyển sang tương tác mới của chúng tôi. Tôi nghĩ cách đơn giản nhất để làm điều này có thể là tìm tất cả những người dùng có tương tác chéo và sau đó trả lại tất cả những người dùng không phải là họ. Nếu bạn hiểu ý tôi. Một cách chính xác hơn để nói e2 chéo với e1 là e2 bắt đầu trước khi kết thúc e1 VÀ kết thúc sau khi bắt đầu e1.
Hãy làm cho điều này trở thành một phương pháp của đối tượng tương tác vì nó hoàn toàn phụ thuộc vào dữ liệu của một tương tác.
#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
Tôi cảm thấy có một cách hiệu quả hơn để đạt được điều này trong một truy vấn nhưng tôi không thể đặt ngón tay vào sql.