Ruby on Rails feels so good because is it fast work with, and you are able to create substantial results in no time. The flexibility and pragmatism of Ruby and the extensive framework and conventions of Rails of course has a huge part in this, but all the great plugins that clever and kind developers are willing to share also plays a vital role in the “Rails feeling”.
I find myself using the same plugins over and over through different projects, and I thought I’d just write a bit about three of the ones I use the most, so others might also realize that these plugins can fill a common need in their Rails applications. All three plugins are MIT licensed and production ready.
Exception Notifier
Jamis Buck’s Exception Notifier plugin is a classic amongst plugins and is part of the “almost-made-it-into-core” plugin package in the official Rails repository. It simply enables your Rails application to compile an email packed with all kind of information and send to one or more recipients each time an unhandled error occurs on your site. For larger apps and teams some kind of error database is probably more appropriate, but in any case it is of vital sense to be aware of errors and bugs in your applications, and to have as much information about them as possible.
Now, there is one catch with the Exception Notifier plugin. It doesn’t play nice with Radiant CMS, so if you use that and want to get notified of errors (which of course you do!), you’ll have to put in a minor workaround. The problem is that Radiant alters where views are found to support extensions, and Exception Notifier also expects a helper to be included automatically, which it isn’t.
First we need to override the Radiant method that locates mailer views so it can find the one of Exception Notifier. Second we need to let the ExceptionNotifier class explicitly include the helper it need. Create a file in your lib-directory with the contents below, and include it in environment.rb:
module Radiant
module MailerViewPathsExtension
# Need to override this method for Exception Notifer and other plugins that sends emails to work properly
def full_template_path(template)
view_paths.each do |path|
full_path = File.join(path, template)
return full_path unless Dir["#{full_path}.*"].empty?
end
# If none of the view paths decided by Radiant fitted, try the default for the mailer
return File.join(template_root, template) if self.respond_to?(:template_root)
throw Exception.new "Unable to locate path for the ActionMailer template #{template}"
end
end
end
module ExceptionNotifierExt
def self.included(base)
base.class_eval {
include InstanceMethods
alias_method_chain :initialize_template_class, :includes
}
end
module InstanceMethods
def initialize_template_class_with_includes(assigns)
template = initialize_template_class_without_includes(assigns)
class << template
include ExceptionNotifierHelper
end
template
end
end
end
ExceptionNotifier.send :include, ExceptionNotifierExt if defined?(ExceptionNotifier)
Simple HTTP auth
You often find yourself creating Rails applications where the contents are for everyone to see, but only for a few select to modify. It's really not that hard to add users, roles, registration- and login forms, forgot password and user administration pages, and so on, but it takes time. Sometimes it is sufficient to just secure certain actions with a fixed username and password, and this is where the Simple HTTP auth plugin comes in. It lets you protect select controllers and actions with basic HTTP authentication, which is the box that pops up and requires a username and password to continue. I am aware that another plugin exist in the "almost-made-it-into-core" plugin package I mentioned earlier that does exactly the same thing, however, this plugin requires you to run Edge Rails and I usually don't. (In fact, if look at the code in that other plugin, you'll see that it just forwards to methods that are built into Rails 2.0.)
While this plugin works straight out the box, and even allows you to lookup usernames and password from a database if you want to do that, it makes it a bit harder to test the controllers and actions it is protecting. Once you start applying http authentication to your controllers, you'll naturally see your functional tests starting to fail, as they get 401 Not Authorized responses generated by the plugin. What I usually do is to add a login method to my test_helper.rb file, and call this method in my tests; either in the setup method or before I do a get or post to a protected action.
# Logs in using basic authentication
def login
@request.env['HTTP_AUTHORIZATION'] = "Basic #{Base64.encode64('my_username:my_password')}"
end
Localization Simplified
This is a perhaps less well-known plugin created by one of my fellow geeks in the Copenhagen Ruby Brigade, and it is used for localizing application that are in one language only - a language that is not English. Localization Simplified allows you to set the language of your application once and for all in environment.rb, and then makes sure that all ActiveRecord error messages, dates and times and currency localized according to that language. It also makes sure everything runs UTF-8.
Currently 14 languages are supported, amongst them all the Scandinavian languages (Danish, Swedish, Norwegian and Finnish) and all the major European languages (English, German, French, Spanish and Italian). If you are creating an application in a single language only, I can highly recommended this plugin over more heavy plugins such as Globalize or Gibberish.
Radiant is probably the best Ruby on Rails content management system (CMS) available at the moment. I’m using it in several customer projects, and while Radiant is still quite limited and aims to stay that way, it is quite easy to extend and blend with ordinary Rails resources through its pendant to engines; extensions.
Like engines, extensions allows developers to share not just “plain” Ruby code between applications (which is done through plugins), but also to share controllers, views and routes between them, as well as maintaining separate migration versions for each extension. One difference between engines and extensions I’ve spotted, is that while engines allows the developer to override and add individual actions in controllers, extensions allow only for replacing an entire controller.
Recently, John W. Long, creator of Radiant, wrote a nice tutorial on the basics of extensions, so if you haven’t had a look at that, I’d recommend it before proceeding with this article. The rest of this text puts focus on how to alter the behavior of Radiant to suit your needs by developing an extension.
I’ll use one of my own extensions, the first to be published as open-source; File Based Layout, as an example on how to override, modify and add functionality to the core of Radiant. I developed this extension to bridge a critical gap between “static” Radiant pages and “dynamic” Rails pages; the non-existent ability to let them share the same layout. To achieve this, I had to alter the Layout model and the Site- and LayoutControllers. This is possible through the dynamic nature of Ruby, but it requires some knowledge about “metaprogramming” which I for one didn’t have before I started to develop extensions.
Take a look at file_based_layout_extension.rb. The activate method, invoked by Radiant at the proper time, includes code in the Layout model and the Site- and LayoutControllers located in modules placed in the lib directory of the extension:
def activate
Layout.send :include, FileBasedLayout::LayoutExt
SiteController.send :include, FileBasedLayout::SiteControllerExt
Admin::LayoutController.send :include, FileBasedLayout::LayoutControllerExt
end
As other extensions might also want to extend models and controllers using similar module names, I have opted to namespace the modules with FileBasedLayout. Also, to make the three modules available to file_based_layout_extension.rb, they have to be required using require_dependency as I have in the top of the file.
To be able to store the name of a physical layout file with the Radiant Layout, I had to add a field the layouts table; layout_file. This is done by adding a migration file to the db/migrate directory, and running the command rake db:migrate:extensions. I also wanted to validate the length of this field, and add a convenience method to the Layout model called file_based? (can you guess what it does?). This is done in the self.included method in layout_ext.rb by invoking base.class_eval with a block of code to be added to the class:
def self.included(base)
base.class_eval {
validates_length_of :layout_file, :allow_nil => true, :maximum => 100, :message => '%d-character limit'
include InstanceMethods
}
end
module InstanceMethods
def file_based?
! layout_file.nil? && ! layout_file.empty?
end
end
This is pretty simple, as we are merely adding stuff to the Layout class, but if what if we wanted to override stuff of, say, the SiteController? To create the File Based Layout extension, I needed to override some pretty low-level stuff in Radiant, in particular the show_uncached_page method, which is invoked when Radiant gets a request for a page not placed in the cache. It’s not enough to just include a module with this method, as I do in layout_controller_ext.rb, as methods in the class takes precedence over included methods.
Instead, I had to place my new show_uncached_page method directly inside the block given to base.class_eval in site_controller_ext.rb. This way, the new method is, so to speak, placed last in the SiteController class, overriding previous definitions of the method:
def self.included(base)
base.class_eval {
private
def show_uncached_page(url)
@page = find_page(url)
unless @page.nil?
if @page.layout && @page.layout.file_based?
render :text => process_with_file_based_layout(@page), :layout => File.basename(@page.layout.layout_file, File.extname(@page.layout.layout_file))
else
...
end
...
}
end
And that’s it, really. When extending and changing Radiant or other Rails applications, the include, self.included and base.class_eval methods are your friends. There are, of course, performance penalties connected with especially class_eval, but as Radiant pages are cached, we don’t have to care too much about them.
The title of this article is a sentence, most Danish bands dream of shouting out at the Roskilde Festival some day. It means, “What’s up, Roskilde!”, and is usually followed by loud screaming in response from the audience at the Roskilde Festival; North Europe’s largest festival, located in Denmark near Copenhagen.
This year was my 14th year at Roskilde. While memories from the many years are hard to keep apart, each year is something special. This year will, without a doubt, first and foremost be remembered as the rainiest Roskilde Festival ever. Roskilde usually has rain; this year it had a flood. Roskilde usually has mud; this year it had liquid dirt. Roskilde usually has puddles (of rainwater, that is), this year it had ponds. But I won’t be one to complain – I had water in my tent at one point, but I was lucky to be camping in a relatively dry area.
In fact, I took pleasure in defying the rain. The festival opened Thursday at 5 PM, and at 1 PM, I was invited to a 10-year anniversary reception far away in the West camp. Thursday was the most rainy day of the festival, and probably will be the most rainy day of this entire year. It poured down for almost 24 hours non-stop, and I had to cross several ponds of mud deeper than the top of my wellies, but I made through to the reception party, and spent the next few hours eating canapés and drinking Champaign, a very odd thing to do indeed at Roskilde.
I also had great music experiences at the festival. Two bands, whose albums I immediately need to buy, are Goose and Loney, Dear, but I also enjoyed a number of Danish acts, as well as the band ending the festival; Basement Jaxx. That last concert, especially, reminded my of a thing that is so unique to Roskilde: People are always so damn nice to each other! I was up in front of the main stage, Orange, and of course it takes a lot of cheering, jumping, dancing, pushing, shoving and shouting to be part of the spearhead of 50.000 people, but it never gets uncomfortable or nasty.
Alas, 7 people died in front of Orange Stage in 2000, but the festival and the audience really learned from that. If I accidentally hit someone in my wild cheering (and that happens a lot), I apologize with a smile, and get a smile back. If I find me and my 189 centimetres towering in front a group of girls trying to see just a bit of the stage, I offer them to get in front of me. If things get wild and some of the more intoxicated people in the audience can’t behave them selves, I use my size to protect those who are smaller around me. The great thing is, most people tend are just as considerate as me, and that’s what’s makes the whole thing work.
I wouldn’t call this The Orange Feeling, but there has been an interesting discussion about that at Jaiku. Speaking of Jaiku; I attempted to microblog from the festival, and also wrote 16 entries during those 5 days, but I wasn’t really able to check on comments from the mobile phone, and didn’t really get that many anyway. It was an experiment, and I don’t know what to make of it yet. See you next year!
Hello, I'm Casper Fabricius. I have developed for the web for 10 years, and have been enjoying Ruby on Rails for the past 5.
My experience covers communities, shopping solutions, multi-language sites, heavy back-end lifting and a wide selection of more traditional websites. I like to integrate Ruby with Java and .NET through JRuby and IronRuby when it makes sense. I am passionate about test- and behavior-driven development, but at the same time I am pragmatic and believe in getting things done.
I live in Copenhagen, Denmark, where I work for a fantastic company: Podio. I do not currently take on freelance assignments.