1. Using Rails 3 route helpers outside of a controller/view

    I’m working on a job for delayed_job which sends an email including a link back to the site. I wanted to use Rails’s built-in URL helpers like new_post_path and edit_blog_url. After a little poking around I found this method call which gives you access to all the helpers from anywhere:

      Rails.application.routes.url_helpers
    

    Append your helper call to that method chain to get the final string:

      Rails.application.routes.url_helpers.new_post_path 
      => '/posts/new'
    
      Rails.application.routes.url_helpers.edit_person_url(@person, :host => 'server.com') 
      => 'http://server.com/people/3/edit'
    

    If you use the _url version of the helper you’ll need to provide the host at the same time you include any other parameters that helper might need.

  2. encosion - Ruby Library for the Brightcove API

    I’m working on a project at work that allows a user to upload videos. We use Brightcove to host and present our video so I wrote a little library for working with their API. It’s called encosion and it’s over at Github . I haven’t completely duplicated the functionality of theirAPI yet since all I needed to do was read and write video, but I encourage others to contribute and add on to the project!

  3. Ruby library for the new Google Analytics API - Gattica

    Just released a new Ruby library on Github called Gattica . Gattica is a gem that lets you talk to the newly released Google Analytics API . Check it out and let me know what you think!

  4. Gasohol library released - easily search a Google Appliance Server with Ruby

    Another release today, this time it’s a small Ruby library for searching a Google Appliance Server called Gasohol . I’ve been working on a prototype search at my job as a full Rails app, but I removed the part that searches and parses results from the GSA and open sourced it.

    As always, check out the readme for usage instructions. I plan to turn this into a gem eventually, but for now you’ll need to pull the files down manually and drop into the rest of your code. More to come!

  5. Radiant extension for searching flickr

    I’ve just released an extension for Radiant CMS which lets you search flickr and returns an unordered list of the thumbnails that match. The extension is listed in the Radiant Extension Registry and is hosted on its own page on Github . Just create a directory in/vendor/extensions called something like flickr and drop the extension in there. Restart Radiant and you’re good to go!

    Check out the README for usage.

  6. Cache anything (easily) with Rails and memcached

    Update 6/9/2010 – A similar mechanism was made available in Rails 2.1 using Rails.cache. See Railscast #115 for an introduction.

    When I first heard about memcached I was excited because of the promise of a very fast caching mechanism that could store anything, but was a little frightened by the idea of dipping my toes into the caching world. Isn’t caching hard? Not the actual process of storing something. Expiring from cache is a different story. I’m only going to deal with the first problem.

    So, how easy is it? First, get memcached. If you’re running something like Ubuntu this is as easy as:

    sudo apt-get install memcached
    

    Of if you have Macports on your Mac then:

    sudo port install memcached
    

    Once you have memcache you’ll want to start it running:

    memcached -vv
    

    The -vv puts memcache in Very Verbose mode so you get to see all the action. You’ll run this as a daemon once you’re ready to go for real (replace -vv with -d).

    My example below uses Ruby and Rails but there are memcache libraries for just about every language out there . For Ruby we’re using memcache-client and you’ll need the gem:

    sudo gem install memcache-client
    

    Okay, all the hard stuff is out of the way. Rails already tries to require 'memcache' so you don’t need to worry about that at all. At the end of your config/environment.rb file create an instance of memcache and assign it to a constant so it’s around whenever we need it:

    CACHE = MemCache.new('127.0.0.1')
    

    Now we’ll add a simple method to our application controller so that this new caching mechanism is available to all of our controllers. Make sure this method is private:

    private
    def data_cache(key)
      unless output = CACHE.get(key)
        output = yield
        CACHE.set(key, output, 1.hour)
      end
      return output
    end
    

    memcache stores everything as simple key/value pairs. You either ask memcache if it has something for a given key, or give it a value along with a key to store. This method will attempt to get the value out of cache and only if it’s not found then will run the block you use when calling it (that’s next) and store the results of that block into cache with the given key and telling it to expire after 1.hour. Every time you ask for that key within the next hour you’ll get the same result from memory. After that memcache will store it again for another hour.

    As a very simple example, you could use this in your controllers like so:

    result = data_cache('foo') { 'Hello, world!' }
    

    So, if the cache contains a key called ‘foo’ it will return it to result. If not, then it will store Hello, world! with the key foo and also return to result. Either way, result will end up with what you want (the contents of the block). If you take a look at the output of memcache back at the terminal you’ll see it trying to get and store data by the key.

    Storing a simple string doesn’t do us much good, so let’s try a real world example. At work I’m working on a new search with a Google GSA. We get some keywords and other search parameters from the user, send them over to the GSA, parse the result, and display to the user. We only update our search index once per day, so if more than one person searches for “running san diego” there’s no reason to go to theGSA each and every time—the result hasn’t changed since it was asked for the earlier in the day. So we cache the result for 24 hours.

    A search result on our system can be uniquely identified by the URL that was generated from the user’s search parameters. We use thisURL as the key to memcache. A regular URL can be pretty long so we take the MD5 hash of it and use that as the key:

    md5 = Digest::MD5.hexdigest(request.request_uri)
    output = data_cache(md5) { SEARCH.search(keywords, options) }
    

    SEARCH is the library that talks to the GSA and parses the result (which I hope to open source soon) (available here). What did this do for our response times? Our GSA box is currently located in Australia (it’s a loaner). Between the network latency of talking to the GSA and receiving and parsing the huge XML file it returns (50kb), most requests were taking 1500 to 2000 milliseconds (not including going through the regular Rails stack to get the page back to the user). With memcache in place the same results come back in 1 millisecond. One. That’s three orders of magnitude difference!

    As you can see, adding memcache to your Rails app is stupidly simple and you can start benefiting from it right away. Don’t be scared of caching!

    Update I updated the post to use data_cache rather than cache as that’s already the name of the fragment caching method in Rails.