link_to_unless_current without request parameters

Not a really big thing, but I felt the need for a method like link_to_unless_current which ignores request parameters (you know, those things that come after the ‘?’ in the url). I couldn’t find it in the Rails api, so I wrote my own little snippet in a helper:

  # makes a link unless 'link' equals the current
  # page ignoring request parameters
  # e.g. this will not make a link:
  #   current page =
  #   link =
  # but this will:
  #   current page =
  #   link =
  def link_to_unless_current_ignore_parameters(title, link)
    link_to_unless(request.request_uri.gsub(/?.*/, '') == url_for(link), title, link)

If someone knows a better way, please let me know :) I thought about aliasing the original method and having an optional boolean parameter that defines whether to ignore the request parameters, but decided to go with this instead.

First tutorial: Writing a blog in Rails 2.0.2

I’ve just finished my first tutorial, writing a blog in Rails 2.0.2. It’s of course inspired by the great 15 minute blog screencast by DHH, which convinced me to try Rails in the first place. This one is with some new Rails 2 conventions and explanations on why some things work.

Now, without further ado, go and read it:

How to write a blog in Rails 2.0.2 (not quite in 15 minutes)

Comments and criticisms are always welcome, it’s my first tutorial ;)

Conditional fragment caching

We were just wondering if it’s possible to provide a condition to fragment caching, in order to only cache certain fragments when no user is logged in to our site. This is to ensure anonymous users (the majority of visitors), who will see the same page anyway, will get it loaded from cache. People who log in will see their personalized site.

I was unable to find anything on Google about this, so I wrote my own helper. It looks so obvious that I’m probably not the first to write this, but I figured I’d share it anyway:

def cache_if (condition, name = {}, &block)
  if condition
    cache(name, &block)

Using this, you can write something like:

<% cache_if @current_user.blank?, 'navigation' do %>
  Navigation content here, including user specific navigation
<% end %>

Loading additional files when starting script/console

I use the Rails console quite a lot, and from a co-worker I had received a .irbrc file that contains a method called ‘log_to’ which enables on-screen query logging in the Rails console. It still required me to call this method every time I started the console though, because even though it’s defined in .irbrc, it cannot be executed from there since it uses Rails specific code (which is not loaded at the time that the .irbrc is loaded.

So, naturally I was wondering whether it is possible to auto-execute any commands while starting script/console. It turns out it isn’t (according to the friendly people on IRC). With the help of madnificent though, I can now do it. He made a small change to rails/railties/lib/commands/console.rb, which will change the behaviour of the console such that it will look in #{RAILS_ROOT}/console_scripts for any additional Ruby files to load.

Please note, for this to work you will need to either freeze rails in your vendor directory, or change your local rails source. As I’m very new to Rails I’m not sure why this kind of functionality is not already in (or perhaps it is but I just could not find it), but I’m hoping it will be picked up somehow ;)

I have also included the script I wanted to load in the first place, I find it quite handy to be able to see what kind of queries my commands are generating.

You can find the files on Pastebin.

Pretty test output with the Turn gem

Have you ever been annoyed that when you run tests, you only see periods, E’s and F’s; not being able to see what actually went wrong until all the tests were done?

I found this pretty gem last week, thanks to some nice people in #rubyonrails. It’s called Turn, and I am unable to find a repository for it anywhere. What it does, is update your test output as follows:

Without Turn:

Loaded suite
Finished in 0.339899 seconds.
8 tests, 8 assertions, 0 failures, 0 errors

With Turn:

Loaded suite

test_truth                                                            PASS

test_truth                                                            PASS
# some output removed here
pass: 8,  fail: 0,  error: 0
total: 8 tests with 8 assertions in 0.373991 seconds

Continue reading