Customized page.* methods for Rails’ RJS Templates

So you want to clear your live search fields the moment someone clicks on a result. Here’s a little bit of code that will let you do so in your RJS template:

How, oh how ever do I implement this for my app? Well, this works because in Ruby, it’s quite easy to add or override methods to any class or module. So let’s hack into ActionView, which is the part of Rails that gives you all those neat-o functions in your views (for example: the much-loved link_to).

The trick to overriding Rails code is to always have a copy of Edge Rails checked out to refer to, so you can get the namespace right. For this example, we have established that we want to extend the page.* methods that are prevalent through RJS templates and “render :update” calls. First we need to find out where the code lives. Let’s run a text search on our edge rails copy for ‘insert_html’, which is a commonly used RJS method. We then find out that it’s at action_pack/lib/action_view/helpers/prototype_helper.rb. Well, this is a start!

Next, we look at the namespace of the code in prototype_helper.rb_, and try to find inserthtml. We then see that it’s nested like so:

Now, in lib/actionview_hacks.rb, copy this namespace and replace the insert_html method with a method of your choice:

Next, update your environment.rb file by adding this somewhere:

That’s it! You can now call page.clear_my_live_search from any RJS template or render :update method. You can also use update_page_tag to insert the page. methods we just generated into your views as javascript.

Also, this example is quite basic. Some might call it overkill to override Rails helpers to get this running. Another good way of doing the same is to define a new method in one of your helpers that uses update_page, like so:

You can then use this helper all over the place, too.

This article barely touches the surface of what’s possible when extending Rails — most existing Rails plugins probably got their start by practically the same process as what we followed here.