As apps evolve over time, they can sometimes grow in less-than-ideal ways. You may start by adding a feature here, and then you need something sort of the same there, and if you're not careful, things can end up a bit messy.
Last week, I had a scenario where we had two different types of users, and each had a "profile" record, but the profile data was different enough, that the original developer decided to use a different model for each type of profile. Those two different profiles had one feature in common though: a profile image. Later, to make it easier to access this profile image uniformly throughout the application, we had a function on the
User model that checked both types of profiles, but it was causing some issues with lazy loading in certain scenarios.
One approach I considered was just eager loading both profile types on the
User query in these very specific scenarios. This would have fixed the lazy loading problem, and it wouldn't really have brought any noticeable performance impact by eager loading some null relationships, but it just felt wrong. It felt like we already had a somewhat awkward situation, and this would make it even more awkward.
Instead, I ended up refactoring these profile relationships to move the profile image onto the
User model directly. This took a bit more effort, but it was clearly the right solution. While sometimes you need to be pragmatic and just ship something "good enough" to meet a deadline, consider if you can possibly take a little more time to not make the code worse. The opposite extreme of "refactor everything!" has its own pitfalls as well, so finding the sweet spot takes some practice.