Voici une façon de le modéliser. Disons que nous avons un modèle 'Engagement' qui a un début datetime, fin datetime et un nom. Un engagement a de nombreux utilisateurs, via une autre table de jointure appelée 'user_engagements' (avec le modèle UserEngagement correspondant). Nous avons donc
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
Maintenant, nous avons un joli schéma simple. Un engagement modélise fondamentalement quelque chose qui se passe, et user_engagements modèle les utilisateurs qui ont réservé pour faire quelque chose. Nous avons une hypothèse (non écrite dans le code) que lorsqu'ils font quelque chose, ils ne sont pas disponibles pour faire autre chose.
Notre tâche suivante consiste à écrire une méthode qui renvoie les utilisateurs disponibles dans un délai donné, c'est-à-dire un nouvel engagement. Donc, nous prenons un engagement et nous voulons que tous les utilisateurs qui n'ont pas un engagement qui croise avec notre nouvel engagement. Je pense que la façon la plus simple de le faire pourrait être de trouver tous les utilisateurs qui ont un engagement croisé, puis de retourner tous les utilisateurs qui ne le sont pas. Si tu vois ce que je veux dire. Une manière plus précise de dire que e2 se croise avec e1 est que e2 commence avant la fin de e1 ET se termine après le début de e1. Faisons-en une méthode d'un objet d'engagement car elle dépend totalement des données d'un engagement.
#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
je me sens comme il y a un moyen plus efficace pour obtenir ce dans une requête, mais je ne peux pas à mettre le doigt sur le sql.
Excellent! Cela ressemble exactement à ce que je cherchais, je vais voir jusqu'où je vais en arriver là. Je vous remercie :) – amr