Utiliser les Ranges Ruby pour manipuler des dates
Il est assez fréquent d’avoir besoin de définir des périodes temporelles dans une application, le plus souvent elle est modélisée par une date de début et une date de fin, et de comparer ces dates à la date courante. Problème : cela donne souvent lieu à des méthodes dont la lisibilité laisse à désirer.
class User
def paying_member?
subscription_started_at <= Date.current &&
(subscription_ended_at.nil? || subscription_ended_at > Date.current)
end
end
Et puis j'ai vu ce tweet de Matt Swanson qui m'a rappelé qu'il était possible de créer des Range
Ruby avec des dates pour simplifier certaines de ces opérations
Comme on peut le voir, mon exemple précédent se trouve fortement simplifié et plus lisible grâce à l'utilisation de la classe Range
par rapport à la version initiale.
Et maintenant que nous avons un objet sous la main pour modéliser la période d'abonnement d'un utilisateur il devient plus facile de modifier le comportement de notre application ou d'ajouter des fonctionnalités.
Par exemple, si il est acté que la date de fin d'un abonnement correspond au premier jour où l'utilisateur n'est plus abonné, on peut modifier notre période pour exclure la date de fin du Range
class User
# ...
def subscription_period
subscription_started_at...subscription_ended_at
end
end
Dans une application Rails on peut aussi profiter des méthodes Range#includes?
ou Range#overlaps?
ajoutées par ActiveSupport. On peut les utiliser pour par exemple partitionner les utilisateurs selon le moment où ils ont souscrit, ou par exemple savoir si 2 abonnés ont été abonné au service sur la même période de temps.
Et pour finir, voici quelques lien pour aller plus loin sur le sujet