Tim Harper just released an excellent RubyOnRails plugin called bundle-fu for bundling Javascript and CSS into one file. This is a really simple and powerful speedup gain you can add to your site to reduce the number of round trips to your server. The impact can be dramatic.

It does not do compression and Tim says:

Bundle-fu currently does not compress CSS or Javascript, as the speed gained by doing so is often marginal, at best.

However, I disagree with the “marginal, at best” part of that statement. Typically a JS file can be compressed upwards of 50% by just doing some simple JS compression techniques (you can also GZip the contents for an even bigger gain). For example, JQuery 1.2.1 uncompressed is 77Kb, and packed it is 26Kb and minified (Gzipped and packed) it is 14Kb.

That being said, I think its ok if bundle-fu does not add packing support since there are many different alternatives out there.

For example the new PackR plugin, a ruby port of Packer would complement bundle-fu nicely.

UPDATE: Less than two days after writing this post Tim updated Bundle-Fu to use the PackR plugin if it is installed. Impressive. You can read about it here.

Netbeans Ruby and Rails IDE

October 16th, 2007

I just started playing with the NetBeans 6 Beta 1 Ruby IDE. I found out about it through George Cook’s excellent writeup which includes plenty of screen shots to spare you from having to install it to see how nice it is.

I must say I was blown away with how much better it is than my current setup of Eclipse and Aptana with RadRails. I’ve been using Eclipse for about 7 years primarily for Java development so it is no small feat to get me to even consider playing with NetBeans. However, after playing with NetBeans for Ruby there is no comparison. NetBeans is a clear winner over Aptana with RadRails.

A few random highlights include:

  1. Real code-completion that actually works. This includes some impressive class introspection that picks up you local class properties.
  2. Some handy short-cuts that let you jump from a controller action to its view and back, and from also from your code to your tests and back
  3. One of my favorites is that the rdoc information is shown as you type out method names. This is a huge time-saver so you don’t have to dig through some external resource for syntax specifics.
  4. A nice integrated SVN gui. This has been a big source of pain for me as well in Eclipse where SVN support is totally lacking
  5. A macro recorder
  6. An integrated database tool
  7. This project is very actively developed. When I first started using RadRails the development cycle was brisk and lots of new features were flying around. Ever since Aptana picked up the project development has ground to nearly a halt and what is there consistently crashes my Eclipse.

In addition, you can install just a standalone Ruby IDE bundle so you don’t need to grab the Java (or other) stuff if you don’t need it.

I am still not ready to take the plunge to use NetBeans for my Java development. However, thanks to this very impressive offering of a Ruby IDE there is now a glimmer of hope that I may try NetBeans for my Java development in the future.

I have previously mentioned using the ruby plugin MiniMagick to resize images. However, I recently realized there is a much easier way that only requires ImageMagick and would therefore work for any web development environment including PHP, Ruby, ASP etc. This technique was inspired by the MiniMagick plugin and involves shelling out directly to the ImageMagick command-line utilities.

I will cover two common techniques:

  • resizing an image
  • determining an image’s width and height

Resizing An Image

To resize an image, you can use ImageMagick’s mogrify utility. For example, to resize an image to 100×100 you would type:

mogrify -thumbnail "100x100>" someimage.gif

The > symbol will make mogrify maintain the aspect ratio. To run this command from RubyOnRails, you can just use backticks to execute it from a command shell like so:

`mogrify -thumbnail "100x100>" someimage.gif`

Determining Image Width and Height

To determine the width and height of the image, we can use ImageMagick’s identify utility like so:

identify -format "%w %h" someimage.gif

This will return the width and height separated by a space. So, to parse these from Ruby you could do:

w, h = `identify -format "%w %h" someimage.gif`.split

It’s that easy. One other side benefit is by running this process from the command-line your webapp will not consume the additional memory needed for the resizing. The command shell will allocate and free this memory. For a RubyOnRails application, this is a huge benefit as one of the biggest issues with other techniques such as RMagick is that they typically may consume too much memory and will crash your web application.

Active Resource was just removed from the Rails 1.2 release branch. So, it looks like it will not be shipping with the release.

After a quick search I couldn’t find any more information about it, but I would expect an announcement will follow shortly. So you may need to stick with edge for a while longer if you are counting on Active Resource support.

I personally think it is better for them to get this one right before mass distribution since this feature has such a wide impact on Rails development. Better to pull it now and fine tune it versus releasing something that will change drastically between releases.

Runit cheat sheet

August 28th, 2006

Here is a nice RUnit cheat sheet courtesy of nubyonrails.

I am all about the cheat sheets, such as this handy prototype cheat sheet

I recently ran into some difficulties while fetching random html pages and images using ruby so I thought others may benefit from my experience.

Ruby has two (and probably many more) great libraries for fetching http data:

OpenURI has a much nicer API and takes care of things like http redirects for you. However, if you try to fetch data over HTTPS, you will see a message like Certificate Verify Failed.

To get around this limitation I’ve written this simple method for fetching data that will enable ssl when necessary and follow all redirects:

def self.get_data(url, limit = 10)
  raise "Too Many Redirects" if limit == 0
  uri = URI.parse url
  server = Net::HTTP.new uri.host, uri.port
  server.use_ssl = uri.scheme == 'https'
  server.verify_mode = OpenSSL::SSL::VERIFY_NONE
  response = server.get uri.request_uri

  case response
    when Net::HTTPSuccess then response['host'] = uri.host; response['path'] = uri.path; response
    when Net::HTTPRedirection then self.get_data(response['location'], limit - 1)
    else
      response.error!
  end
end

Also, you will notice that I add the host and path into the response since in my case I use that information for building the full path to the images.

Enjoy!

NOTE: This blog is no longer running Typo

In this article I am going to discuss the steps necessary to add the excellent CodeRay syntax
highlighting library to your Typo blog installation. The newest version of Typo ships with
support for the syntax gem, but I have found that the
CodeRay gem does a much better job and supports a lot more languages including:

  • ruby
  • C
  • Delphi
  • HTML
  • RHTML
  • Nitro-XHTML

Install CodeRay

There are a couple different ways you can install CodeRay:

  • By gem
  • In the typo/vendor directory.

For my case, I chose to install CodeRay using the vendor directory since the gem way
is not ideal for a shared hosting environment.

To install CodeRay into your typo/vendor directory:

# Either download the CodeRay source into your typo/vendor/coderay directory or setup
an svn:externals for CodeRay. To setup the svn:externals, type this from the root
of your typo install:

svn propedit svn:externals vendor

and add this line into the externals for the vendor directory:

coderay svn://rubyforge.org/var/svn/coderay/trunk/coderay/trunk/lib

and then update your CodeRay src with this command:

svn up vendor

Create the CodeRay text filter

Now we will create a custom Typo text filter for sending code through CodeRay.

NOTE: This requires either Typo 4 or greater, or an earlier unreleased Typo that supports
text filters.

If you want to skip the explanation, here is a patch file
that you can apply from the root of your typo installation:

patch < typo.coderay.diff

This diff contains the following four changes:

  • A modification to the typo environment
  • A CodeRay text filter
  • A CodeRay css stylesheet
  • A modification to the add the CodeRay stylesheet to the typo theme

A modification to the typo environment

In order to have typo load the CodeRay code into our rails environment, we needed to add
the vendor/coderay path into the config load paths. The patch will do this for you.

A CodeRay text filter

The CodeRay text filter is very similar to the Code text filter. It is impressive how
little code it takes to add this CodeRay functionality into typo. All of the work for this
text filter is done in this method:

def self.macrofilter(controller,content,attrib,params,text='')
  lang = attrib['lang'] || 'ruby'
  tokens = CodeRay.scan(text, lang)
  result = tokens.div(:line_numbers => :table)
  '<notextile>#{result}</notextile>'
end

A CodeRay css stylesheet

After applying the patch, the CodeRay css file will be located here:

public/stylesheets/coderay.css

A modification to the add the CodeRay stylesheet to the typo theme

The patch above will apply the CodeRay css to the default azure theme. You can manually
add it to any theme by just adding this line to the top of your theme within the tags:

<%= stylesheet_link_tag "/stylesheets/coderay", :media => ‘all’ %>

Using the CodeRay text filter

To use the CodeRay text filter in your code, surround any code you wish to display in
typo:coderay tags and optionally specify the language to format (the default is ruby).
Here is a simple example (Note: remove the space between typo and coderay, I only added it so it would not be grabbed by the coderay text filter):

  <typo: coderay lang="html">
    <div id="somediv">The div that I am</div>
  </typo: coderay>

In this article, I am going to walk you through a simple technique for resizing images on the server in your Ruby On Rails app using MiniMagick. I have previously written about a technique for resizing images using javascript on the client, but I prefer the server method when possible.

MiniMagick is a ruby gem/plugin that is a wrapper around a great ruby image library called ImageMagick. There is also another well known library called RMagick that wraps ImageMagick that includes a lot more features. I chose MiniMagick for my case since I am on a shared host and the memory footprint is much smaller for MiniMagick since it basically just wraps the ImageMagick command line utilities.

Prerequisites

So, before we get started, make sure you have ImageMagick installed on your machine.

MiniMagick comes as both a gem and a plugin. Choose the one that makes sense for your project and install it. In my case, I chose the plugin since I wanted to keep MiniMagick checked in with my code in subversion.

To install the MiniMagick plugin, just download the plugin zip and extract it into your vendor/plugins directory. Please read up on the NOTES at the bottom of this article before you go for a few bugs I found with the plugin and how to fix them.

Usage

In my case, I decided to create a separate Image model for managing my images. In my Image model, I added this resize method:

def self.resize(path)
  image = MiniMagick::Image.new(path)
  w, h = image['%w %h'].split
  w = w.to_f
  h = h.to_f
  @@max_size = 100
  if (w > @@max_size || h > @@max_size)
    if (w > h)
      h = (h*(@@max_size/w)).to_i
      w = @@max_size
    else
      w = (w*(@@max_size/h)).to_i
      h = @@max_size
    end
    image.thumbnail "#{w}x#{h}"
  end
end

Now, let’s break down some of the more interesting parts:

image = MiniMagick::Image.new(path)

The above line is used to create a new MiniMagick Image object. By using the new method, I will be manipulating the actual image file on disk rather than working on a copy. If you wanted to work on a copy without modifying the original image you could the MiniMagick::Image.from_file(path) instead. When working on a copy, you would also have to use the MiniMagick::Image.write(path) method to save your image after the manipulations.

w, h = image['%w %h'].split

This line is used to grab the image width and height. The array ([]) syntax of the MiniMagick::Image class is really just a wrapper around the identify utility in ImageMagick. For a full list of options, refer to this documentation.

The remainder of that method up until the line below is just an algorithm for resizing the image to no larger than 100px on its largest side. It maintains the aspect ratio as well.

image.thumbnail "#{w}x#{h}"

The line is used to actually resize the image based on our new computed width and height. The MiniMagick::Image library exposes all of the options provided by the ImageMagick mogrify utility. For a full list of options for mogrify refer to this documentation. If you chose to create your image using the MiniMagick::Image.from_file(path) method, here is where you would write your image back to disk.

And that’s it! You should be happily resizing images using MiniMagick in no time.

NOTES: At the time of this posting, the MiniMagick plugin had a few bugs, which I have logged:

  1. In the init.rb, change this line:
    require 'mini-magic'
    

    to:

    require 'mini_magic'
    
  2. If you are using the MiniMagick::Image.write method, you will need to add the “rb” (read binary) option to the open statement within it. The final write method should read as follows:
    def write(output_path)
      open(output_path, "wb") do |output_file|
        open(@path, "rb") do |image_file|
          output_file.write(image_file.read)
        end
      end
    end
    

If you ever need to count your Rails records based on a distinct column, here is a simple solution:

Gift.count_by_sql("select count(distinct url) from gifts")

In this example, I am counting the number of distinct gift urls from my gifts table.

RI For Your Ruby Gems

June 23rd, 2006

Ruby comes with a great utilty called RI for searching and displaying ruby documentation. I have had varying levels of success in getting this to work with ruby gems so I wanted to share my findings so others may benefit from my trials and errors.

Attempt 1

The first tip I found for this (thanks to Brandt Lofton on the RadRails mailing list) involves modifying your site_ruby/1.8/rubygems/doc_manager.rb by changing this line

r.document(['--quiet', '--op', rdoc_dir]
+ @rdoc_args.flatten + source_dirs)

To:

r.document(['--quiet', '--op', '--merge', '-r', '--ri-system', rdoc_dir]
+ @rdoc_args.flatten + source_dirs)

You must then run the command:

gem rdoc --all

This will install all of your installed gems rdoc documentation for use by Ri.

NOTE: In my experience, this command must complete or the documentation will not be installed properly. For instance, in InstantRails1.3a, the camping-unabridged.rb file causes problems so I renamed it to camping-unabriged.rb-renamed so it will be skipped.

Attempt 2

Some people have experienced problems (myself included) with those steps above. So, I recently tried to find an alternative approach. I found this
post
by Eric Hodel, who implemented a different patch for ruby-core.

I tried following in his footsteps, but I was not successful. However, others seem to have gotten that one to work, so you may have better luck than I did.

Attempt 3

If all else fails, they say the third time is the charm. If you can’t get either of those methods to work, there is one more thing you can do to manually install your gem documentation.

This should work for any ruby code you have. Just change directories to the root of the code you want to be able to search with Ri and run this command:

rdoc --ri-site

This will install your documentation into the share/site directory of your ruby install where Ri will be able to read it.

NOTE: I had problems trying to generate the docs for all of my ruby gems at once so you may want to just do this individually for the ones that matter the most, such as actionpack, activerecord etc.

It may seem like a lot of effort just to be able to see your gem documentation from within Ri, but from my personal experience it is completely worth it. Having the ability to instantly look up the Rails documentation has definitely flattened the learning curve for me with Rails as I instantly can see how stuff works, or what the name of that AJAX method is etc.

Enjoy!