ActiveHelper + Rails is no pain in the ass!
Saturday, April 10th, 2010Recently (about 6 minutes ago) I added support for Rails in ActiveHelper. The library as-it is still completely independent from any MVC framework and simply provides a generic helper API.
However, we got some Rails bindings now.
If you’re not yet familiar with ActiveHelper, no problem, it’s brandnew. Consider skimming the introducing post first. Or directly jump to the github repository.
Writing the helper
Let’s assume you want to create a new helper to replace the #link_to method. Why not name it LinkingHelper?
class LinkingHelper < ActiveHelper::Base provides :link_for def link_for(title, url) '<a href="' + url + '">' + title + '</a>' end end
You’d put this into app/active_helpers/linking_helper.rb.
Preparing the controller
Bla bla bla, it’s obvious how to use ActiveHelpers in controllers.
class BlogController < ActionController::Base active_helper LinkingHelper def show @post = Post.find params[:id] end end
Helping the view
As soon as the controller did include the LinkingHelper its provided methods are around in the view.
1 2 3 4 5 6 | Bookmarkable link: <%= link_for @post.title, @post.url %> <h1><%= @post.title %></h1> <p> <%= @post.body %> </p> |
You used your #link_for to generate a link in line 1.
So… where’s the benefit?
Being a good programmer you instantly decide to extract the markup logic from the LinkingHelper to some separate MarkupHelper.
The latter would provide a method #tag for generating markup.
Your former helper now looks like this.
1 2 3 4 5 6 7 | class LinkingHelper < MarkupHelper provides :link_for def link_for(title, url) tag(:a, title, :href => url) end end |
Noticed the inheritance in line 1? Wow- that’s OOP features in helpers. Nice.
Reusing old-school helpers
Now what if you still want to use #url_for to setup the link address? It’s hidden somewhere in Rails gloomy mixin magic.
You know it’s floating around in your view. So go and use it.
1 2 3 4 5 6 7 8 9 | class LinkingHelper < MarkupHelper provides :link_for needs :url_for def link_for(title, url) url = url_for(url) tag(:a, title, :href => url) end end |
Step-by-step, dude. You simply use #url_for in line 6. Your helper knows about it since you defined the dependency (line 3).
That’s gonna work- but… why?
Well, any ActiveHelper simply delegates dependencies back to where it was imported into. In our case, any call to #url_for is routed to the ActionView instance which has to care about that.
Delegation for a better world
The new keywords in the Helper World are delegation and interfaces.
Besides that, we got back OOP and inheritance to helpers.
Lemme end this boring post by quoting Manuel who’s just diving into ActiveHelpers.
It’s funny- ActiveHelpers is nothing more than 80 lines of code. Anyway, it’s forcing you to write clean code… in a gentle way!
Isn’t that great?