Jon Leighton isn’t the only one picking a fight with Rails controllers. Keith Gaddis suggests in The Problem With Controllers that we’ve relegated the command pattern to the depths of our queuing frameworks:
The problem with controllers in Rails is that they’re a part of the web domain—their job is to respond to requests, and ONLY to respond to requests. Anything that happens between the receipt of a request and sending a response is Somebody Else’s Job™. Commands are that Somebody Else™. Commands are also very commonly utilized to put work into the background.
Why are commands an appropriate place to handle that logic? Commands give you the opportunity to encapsulate all of the logic required for an interaction in one spot. Sometimes that interaction is as simple as a method call—more often there are several method calls involved, not all of which deal with domain logic (and thus, are inappropriate for inclusion on the models). Commands give you a place to bring all of these together in one spot without increasing coupling in your controllers or models.
He’s released Imperator, a Ruby gem to help move that logic, simplify our controllers, and make them less model-dependent.
class DoSomethingCommand < Imperator::Command attribute :some_object_id attribute :some_value validates_presence_of :some_object_id action do obj = SomeObject.find(self.some_object_id) obj.do_something(self.some_value) end end end
The project is brand new and will likely evolve so check the source on GitHub.