Hey folks--
Couldn't resist making a sarcastic mention of our last attempt at discussing Locations, but I think we're all sort of diverging again so I'd like to revive the conversation. I made sort of a snarky comment to Adam, and he was kind enough to post back with both 1) his reasoning behind locations, 2) a history of previous location designs and 3) a justification for the current approach, which I had clobbered by making Locations concrete and adding Location types again. I'm appending his comments here. They're deep within github commit logs, and I think it's really good stuff so I wanted to share. I of course couldn't resist adding my $0.02 below all that (sorry for the long email).
Just to summarize (Adam, step in if I'm not paraphrasing well):
1) Location models are definitely hard to get right, and each deployment typically has very specific needs
2) There seems to be some debate over the OO principles "is-a" and "has-a": what things actually *are* locations, and should subclass or just use the base, and which things *have* locations, and just need a foreign key?
---From Adam:
i fixed the ui breakage in rapidsms/rapidsms@fb7a1ebf03d87ee6320e6e9bf26869c779369a46 [this was my above-mentioned commit], so forget about that.
i don't see how this solution to locations (a single `Location` model with associated `LocationType`s) would be sufficient for anything but the simplest projects. i removed it ages ago, because we tried it in the field a few times, and it wasn't flexible enough. i'm not saying my solution is perfect (actually, it's incomplete and sucks), but it more accurately models the real world, which is surely the point of _models_.
most deployments require multiple types of location. in ethiopia, for example, there were regions, districts (woredas), and health centers (otps). we had the latitude and longitude for each, but they were otherwise totally different models: regions had a name, and many districs; districts had explicit codes, and many health centers; health centers had auto-generated codes and many reporters; supplies could be delivered to districts or health centers, but not regions; stock outs were only reported at health centers.
this fairly typical situation could not be accurately modeled with a single `Location` model, so we broke it into multiple models, and duplicated some of the functionality. that sucked, because it meant we had to build our own mapping ui (again), which couldn't easily be shared with other deployments, because it was full of project-specific code. next time around (nigeria, i think), we tried to make a single monolithic `Location` model which would solve all of the problems from the previous deployment. that sucked even more, because it was complicated _and_ insufficient.
i won't talk about trying to combine multiple location-aware apps in the same project here, but as you can imagine, that was a cluster-fuck, too. when i tried to create a demo project (for an event) containing some of dimagi's stuff, a couple of unicef deployments, and matt's mctc thing, there were no less than three separate maps (two google, one openlayers), and four create/read/update/delete interfaces for various location types. collaboration fail.
the compromise which we eventually came up with was the `Location`-subclassing approach, which i'm still advocating for. rather than defining our own models in contrib (which always seem to be insufficient), i would prefer to provide a small-ish base class, which projects can subclass and customize however they like. since the functionality of the base class is constant, we can (and have) built a useful ui around it, with the usual CRUD operations, and plotting everything on a single map.
my point is, sure, your approach is simpler for one project, but bad for collaboration between projects. however, i'm not really involved in the project any more, so i'm not trying to prevent anyone from moving forward. just trying to make sure we don't repeat the same mistakes that we've made in the past.
sorry, that was rather long-winded. maybe i should copy it to the mailing list. [done!]
---
My $0.02 is that probably both cases apply to most deployments. I'd say for instance a health facility *has-a* location, whereas a district certainly *is* one. For my particular deployments that's the attitude I take: countries, districts, parishes, towns, etc. typically follow *close enough* of the same model that I can get away with having them all in one table, and differentiating by type. That also makes it quite easy if the needs of the project suddenly need to capture things at the subdistrict or county level, without creating new subclasses/database tables. Anything else (i.e. water pumps, health facilities) *has-a* location, because certainly they're going to have all sorts of different attributes and business logic. This doesn't make a generalized mapping app particularly possible, I realize, but then, I tend to think visualizations get pretty deployment-specific as it is.
Only other thing to bear in mind is the in-development (
http://docs.rapidsms.org/InDevelopment) simple_locations app, which uses a tree-based library. Definitely a WIP, but I think if we can cherry-pick what we like about both, come to an agreement about what the base location model should include, and collaborate within common domains where we have to subclass or reference locations (like the health_models app), hopefully we can avoid "collaboration fail."
later,
--dm