While I enjoy coding Ruby at night, I still code Java during my day job. So far, every project at work has used Struts. As there’s a lot of momentum behind Spring in the Java community lately, I decided to do a bit of reading to keep up. A couple of days ago, I just finished reading Spring in Action (Manning). Overall, Spring seemed pretty nice, but the one thing that stuck out to me was Aspect-Oriented Programming.
I had never seen AOP in use before reading the Spring book, but it seems to make a lot of sense for separation of cross-cutting concerns. The main concerns that seem to come up in nearly every project I’ve worked on are security, transactions, and logging.
In Rails, security is generally performed through a before_filter in a controller for certain methods. So you generally end up with code that looks something like this:
While this works, I often feel as though the security is tacked on. I’m also afraid that if I change my underlying security API (either by changing libraries or if the public API is changed), then I have to update every single controller in my application to reflect those changes. Finally, the calls to each of the before_filters is a lot of duplicate code.
Note: these solutions don’t use AOP, though I do try to keep to separation of concerns.
My first thought is that I’d like to pull out all of the security code into one place. An initial thought of mine would be to use ApplicationController and have a single filter there.
Another thought would be to pull out this altogether and have a SecurityController that extends Base::Controller and which ApplicationController extends.
Of these two solutions, I like the second solution better. This keeps the security stuff all together and it can be easily changed. If the API changes then only one controller would have to be updated.
Rails has a solid Observer Pattern implemented for ActiveRecord. Just like having observers for the models, we could have observers for the controllers. This would allow us to call a method before another method is implemented within a controller. I haven’t done too much research into the Observers within Rails, though I do know that they are specific to ActiveRecord. If possible, we could extend their base class to be an observer for the controller, like so:
The nice thing about leaving code as it is now is that I know that it works pretty quick. If we change the filter to occur earlier in its own controller, then the code is called for every controller/action, versus a case-by-case check within each controller. This is a lot of overhead and could definitely impact performance. This is less than desirable. Though slightly different, the Observer Pattern still has to check every controller/action that may have been called.
As of right now, I don’t have any plans on implementing anything with AOP yet. I like the thought, but I don’t really had the time. There does seem to be a pretty good AOP ruby gem Aquarium which I may look into integrating with Rails at a later date.
Until then, what have you tried implementing with AOP? Do you use AOP on any of your Rails projects?
Questions? E-mail me: this domain AT gmail DOT com