Mysql
 sql >> Database >  >> RDS >> Mysql

Elenco degli utenti disponibili in una determinata data

Ecco un modo per modellarlo. Diciamo che abbiamo un modello 'Engagement' che ha una data/ora di inizio, una data/ora di fine e un nome. Un coinvolgimento ha molti utenti, attraverso un'altra tabella di join chiamata 'user_engagements' (con il modello UserEngagement corrispondente). Quindi abbiamo

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

Ora abbiamo uno schema semplice e carino. Un coinvolgimento fondamentalmente modella qualcosa che sta accadendo e user_engagements modella gli utenti che sono prenotati per fare quella cosa. Abbiamo un presupposto (non scritto nel codice) che quando stanno facendo qualcosa non sono disponibili a fare nient'altro.

Il nostro prossimo compito è scrivere un metodo che restituisca gli utenti disponibili entro un determinato periodo di tempo, ovvero un nuovo coinvolgimento. Quindi, prendiamo un impegno e vogliamo tutti gli utenti che non hanno un impegno che si incrocia con il nostro nuovo impegno. Penso che il modo più semplice per farlo potrebbe essere trovare tutti gli utenti che hanno un coinvolgimento di crossover e quindi restituire tutti gli utenti che non sono loro. Se capisci cosa intendo. Un modo più preciso per dire che e2 incrocia con e1 è che e2 inizia prima della fine di e1 E finisce dopo l'inizio di e1.

Facciamo in modo che questo sia un metodo per un oggetto di coinvolgimento poiché dipende totalmente dai dati di un coinvolgimento.

#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

Sento che esiste un modo più efficiente per ottenere questo in una query, ma non riesco a mettere il dito su sql.