Tuesday, February 5, 2008

will_paginate remotely

I've patched the awesome will_paginate plugin from Mislav Marohnic to support rails' link_to_remote helper. Now you can easily tell will_paginate that it should update an element in the DOM instead of doing a full request cycle:
1 <%= will_paginate @pages, :update => "story_box", :params=> {}%>

I submitted a patch to Mislav, but I can't tell you when or if it'll get into the official release. For the more adventurous hackers out there here's a messier but more concise version of the patched code:

monkeypatch the page_link_or_span method in will_paginate/lib/will_paginate/view_helpers.rb:
 1 def page_link_or_span(page, span_class = 'current', text = nil)
2 text ||= page.to_s
3 if page and page != current_page
4 if update = @options[:update]
5 @template.link_to_remote text, :update => update, :url => url_options(page)
6 else
7 @template.link_to text, url_options(page)
8 end
9 else
10 @template.content_tag :span, text, :class => span_class
11 end
12 end

Monday, February 4, 2008

Spring IOC in JRuby - life outside the container

If you're a JRuby aficionado you probably read about the Spring IOC Plugin for rails, but what if you want to get spring IOC running outside a servlet container? Here's how.

Now, the first important thing I learned is that spring uses the Java Thread's context class loader to load its resources. If you're using JRuby's $CLASSPATH to set up your test environment this poses a problem. So, first thing I override the current Thread's context class loader at the end of my test.rb environment file:


require 'java'
require 'jruby'

java.lang.Thread.current_thread.context_class_loader = JRuby.runtime.getJRubyClassLoader

Now we can move on to Spring. We can't use the WebApplicationContext that the Spring plugin uses because it'll (obviously) complain that there isn't a servlet context. So let's fall back on the ClassPathXmlApplicationContext. Add this wherever you'd like to hook in and replace the spring context from the plugin:

config = ["classpath:applicationContext.xml",
"classpath:applicationContext-service.xml"]
ctx = ClassPathXmlApplicationContext.new(config.to_java(:string))

And there you go! Provided you've configured the $CLASSPATH correctly you should be on your way.