Inilah salah satu cara untuk memodelkannya. Katakanlah kita memiliki model 'Engagement' yang memiliki tanggal mulai, waktu akhir, dan nama. Sebuah engagement memiliki banyak pengguna, melalui tabel join lain yang disebut 'user_engagements' (dengan model UserEngagement yang sesuai). Jadi kita punya
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
Sekarang kita memiliki skema sederhana yang bagus. Keterlibatan pada dasarnya memodelkan sesuatu yang terjadi, dan keterlibatan_pengguna memodelkan pengguna yang dipesan untuk melakukan hal itu. Kami memiliki asumsi (tidak tertulis dalam kode) bahwa ketika mereka melakukan sesuatu, mereka tidak dapat melakukan hal lain.
Tugas kita selanjutnya adalah menulis metode yang mengembalikan pengguna yang tersedia dalam jangka waktu tertentu, yaitu keterlibatan baru. Jadi, kami membuat keterlibatan dan kami ingin semua pengguna yang tidak memiliki keterlibatan menyeberang dengan keterlibatan baru kami. Saya pikir cara paling sederhana untuk melakukan ini adalah dengan menemukan semua pengguna yang memiliki keterlibatan lintas-silang dan kemudian mengembalikan semua pengguna yang bukan mereka. Jika kamu tahu maksud saya. Cara yang lebih tepat untuk mengatakan e2 menyilang dengan e1 adalah bahwa e2 dimulai sebelum akhir e1 DAN berakhir setelah awal e1.
Mari jadikan ini sebagai metode objek pertunangan karena ini sepenuhnya bergantung pada data pertunangan.
#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
Saya merasa ada cara yang lebih efisien untuk mendapatkan ini dalam satu kueri tetapi saya tidak bisa meletakkan jari saya di sql.