This is part of the Semicolon&Sons Code Diary - consisting of lessons learned on the job. You're in the types category.
Last Updated: 2024-11-21
We had the following code used to calculate the availability of discounts.
order.downloads.select do |product|
last_updated_at = product.notes_files.maximum(:released_on)
if order.completed_at > last_updated_at
false
else
true
end
end
The problem? Well a product, when in a deleted state, can have no associated
note_files
records - thus product.notes_files
will be []
. And so the
maximum(:released_on)
applies to an empty set, returning nil
. Because the
next line compares this value with a term, it causes a type error.
The fix was a guard clause for deleted products (which, being deleted, ought not have discount offers anyway).
order.downloads.select { |product|
next false if product.deleted_at
# ... as before
end
Calling max/min etc. on a list of type T
will usually return an entity of another type
(e.g. nil
) if the list is empty. Anticipate this in your code.