I’ve noticed I have the same piece of code sitting at the top of several of my controllers. They tend to look like this:
def app_description(app):
""" Dictionary describing an app. """
return {'name': app.app,
'id': app.id,
'is_new': app.is_new(),
'created_on': app.created_on.strftime("%m/%d/%Y"),
'configured': app.configured }
I’ll call this from a couple different actions in the controller, but generally not outside that controller. It accesses properties. It calls methods. It formats opaque objects (like dates).
My question is: is this controller code, or model code?
The case for controller:
- It defines my API.
- It’s currently only used in that module.
- There doesn’t seem to be any logic here.
The case for model:
- It seems like a description of the data, which the model should be responsible for.
- It feels like I might want to use this in other controllers. Haven’t gotten there yet, but these functions are still pretty new, so they might.
- Attaching a function to the object it clearly belongs to seems better than leaving it as a module-level function.
- It could be more succinctly defined on the model. Something like having the top-level model object define
.description(), and the subclasses just define a black/whitelist of properties, plus override the method itself to call functions. I’m pretty sure that would be fewer lines of code (as it would save me the repetition of things like'name': app.name), which seems like a good thing.
The answer I finally decided on:
In the short term, having these methods is fine in the controllers. If they define the output, then, OK, they can stay there. They’re only used in the model.
Theres a couple things to watch out for, which indicate they’ve grown up, and need to go elsewhere:
@ajaxifydecorator that does things like setsContent-Typeheaders, does JSON encoding, etc. In this case, I moved the datetime standard formatting into there — when the JSON encoder hits a datetime (formerly unserializable), it always treats it the same (seconds since the epoch, for me).I suspect there’s more, but basically, I don’t think there all as similar as I thought they were initially. I’m currently happy thinking about them as a convention for simple objects in our (small-ish, new-ish) codebase, with the understanding that after a few iterations, a better solution may present itself. In the meantime, they stay in the controller and define my AJAXy-JSON-only interface.