Ruby's compact Method: A Real Use Case

In Ruby, the compact method is a handy tool when dealing with arrays containing nil values. Let’s delve into its functionality through a practical example:

Consider a scenario where you’re developing a system to activate promo codes. Each promo code may or may not have an expiration date. To handle this, you’ve written a method activate_promo_code! that creates a record in the database to activate the promo code, setting its expiration date to the earliest of the provided expiration date or a default expiration period from today.

Here’s the initial implementation:

1
2
3
4
5
6
7
def activate_promo_code!(promo_code)
  promo_code_entries.create(
    promo_code: promo_code,
    expires_at: [promo_code.expired_at, Date.today + DEFAULT_PROMO_CODE_EXPIRATION_DAYS].min,
    discount: promo_code.discount
  )
end

However, you noticed that the code might throw an error if promo_code.expired_at is nil. To address this, you decided to use the compact method. Let’s see how it’s done:

1
2
3
4
5
6
7
def activate_promo_code!(promo_code)
  promo_code_entries.create(
    promo_code: promo_code,
    expires_at: [promo_code.expired_at, Date.today + DEFAULT_PROMO_CODE_EXPIRATION_DAYS].compact.min,
    discount: promo_code.discount
  )
end

Now, what does compact do here?

In this context, promo_code.expired_at might be nil if the promo code doesn’t have an expiration date. So, when we use [promo_code.expired_at, Date.today + DEFAULT_PROMO_CODE_EXPIRATION_DAYS].compact, it removes any nil values from the array. This ensures that min is called only on valid dates, avoiding potential errors.

By using compact, it removes any nil values from the array. When you call .compact on an array, it returns a new array with all nil elements removed