It is quite common to need to define time periods in your application, most often it is modeled by a start date and an end date. Then these dates are compared to the current date for thing like knowing if a customer is a paying member.
This way of doing often results in methods that could be hard to read
class User def paying_member? subscription_started_at <= Date.current && (subscription_ended_at.nil? || subscription_ended_at > Date.current) end end
But there is a way to improve the readability of your code using the Ruby’s Range class.
class User def paying_member? subscription_period.cover?(Date.current) end private def subscription_period subscription_started_at..subscription_ended_at end end
In the event that the customer do not have terminated its subscription the
subscription_period will return an infinite Range which will also validate our predicate.
Now let’s say that business consider that the subscription is supposed to be over the day before its stored end date, it is quite simple to modify the
subscription_period method to return a Range that exclude its upper limit.
class User # ... def subscription_period subscription_started_at...subscription_ended_at end end
In a Rails application, it is also possible to take advantage of the methods
Range#overlaps? added to the Range class by ActiveSupport.
class User def subscriber_kind case subscription_period when innovator_period then 'Innovator' when early_adopter_period then 'Early adopter' when early_majority_period then 'Early majority' when late_majority_period then 'Late majority' when laggards_period then 'Laggard' end def share_subscription_with(user) subscription_period.overlaps?(user.subscription_period) end end
Top comments (0)