This is part of the Semicolon&Sons Code Diary - consisting of lessons learned on the job. You're in the object-oriented-programming category.
Last Updated: 2024-11-23
I had the following code fail due to coordinates being nil when I didn't expect them to be:
class Tutor
geocode_by :postcode # this adds latitude and longitude attributes
before_save :set_town
def set_town
self.town = Geocoder.search([latitude, longitude]).first.city
end
end
The issue was that because set_town
got called before the geocode_by
generated the latitude
and longitude
coordinates. I had made a false
assumption about when data was available.
When accessing any attribute of a model that has state that only gets generated during certain stages of its lifecycle, ask yourself if the state is definitely going to available at this point.
And more generally, these kinds of mistakes are all too easy to make. It's worth
thinking of ways to make the triggering dependent on that state becoming present
(i.e. latitude
being set here) rather than simply waiting for a save event.
For example
class Tutor
geocode_by :postcode # this adds latitude and longitude attributes
after_save :set_town
def set_town
if latitude_changed?
self.town = Geocoder.search([latitude, longitude]).first.city
end
end
end