I’ve Moved!

January 17, 2010

WordPress was very nice to let me use their servers for a while, but I’ve decided to stretch my legs a bit and move to my own host. You can find this blog (and more!) at http://trydionel.com. Come say hi!

Links! (v2)

December 28, 2009

Okay, I promise I’m not trying to start a link blog (I think). My browsers have just found themselves buried in tabs this month.


December 19, 2009

While I certainly don’t intend to create another link blog (there are enough of those floating around these days), I need somewhere to unload these few that have cluttered my iPhone for the last week.

RSpec Rails Flash Matcher

November 26, 2009

I just started using Shoulda’s very nice RSpec custom matchers. They do a great job of trimming the fat off your specs. One thing I found missing though was a simple matcher to handle the Rails flash. A quick googling didn’t turn up any simple matchers for this, so I put one together and pushed it to github — rspec-flash-matcher.

It’s a pretty straightforward matcher, and lets you reduce

it "should set the error flash" do
  flash[:error].should_not be_nil


it { should set_flash(:error) }

If you like to test actual flash output, you can use

it { should set_flash(:error).to("OMG u broked it") }

I plan to add regex support soon. Also, I have a suspicion that this won’t work under Ruby 1.9 because of changes in how send handles protected methods.

A Few SunSpot Tips

November 19, 2009

I started playing with SunSpot yesterday with the intent of using it as my full-text search provider in a Rails application. The few how-tos I found show the beautiful DSL it provides, but unfortunately not much more. Below are a few gotchas I ran into while getting it to work on my setup.

1. Sunspot includes a development version of Solr

There’s no need to download an official Solr release from Apache for development work. Just install sunspot and you get Solr for free, complete with some nice Rake tasks.

gem install sunspot
rake sunspot:solr:start --starts the solr server
rake sunspot:solr:stop --stops the solr server

2. Using Sunspot in Rails requires the sunspot_rails gem

This one was easy to solve, but still surprised me a bit. The sunspot gem only provides the base interaction with the Solr server. In order to get ActiveRecord integration, you need to add the sunspot_rails gem:

# config/environment.rb
config.gem 'sunspot', :lib => 'sunspot'
config.gem 'sunspot_rails', :lib => 'sunspot/rails'

$ rake gems:install

3. Text Analysis is setup in Solr, not in Sunspot

It seems there’s not much written in the Sunspot documentation/groups about text analysis (such as word stemming, stop word filters, synonyms analysis, etc), and for good reason. These settings are defined in Solr’s setup via the schema.xml file. More details on Solr’s text analysis abilities can be found on Apache’s website. If you’re using the install you get with Sunspot, you can find this in RAILS_ROOT/solr/conf/schema.xml.

4. Sunspot executes its search DSL in a new scope

This one took me forever to figure out. By default, any details passed into Sunspot.search are not evaluated in the current context. This means that trying to search directly from the controller just doesn’t work as I expected. There’s no mention of this in sunspot_rails’ documentation, but there’s a brief snippet in sunspot’s:

If the block passed to search takes an argument, that argument will present the DSL, and the block will be evaluated in the calling context. This will come in handy for building searches using instance data or methods

So, in order to search from the controller (or rather in the model, like you should), you’ll need to pass an argument to the Sunspot.search block:

@search = Sunspot.search(Post) do |query|
query.keywords params[:query]

Using Paperclip with Amazon S3

November 8, 2009

I recently launched the website for my wedding on Heroku. I opted to use Thoughtbot’s popular Paperclip gem to manage photo attachments for the site. It’s a snap to use with filesystem storage (the default), but Heroku doesn’t allow applications to have access to the filesystem. Plan B then is to use Paperclip’s ability to manage files over Amazon’s Simple Storage Service (aka Amazon S3). S3 is cloud storage for ground people. It offers super cheap storage and huge bandwidth, allowing small websites to use it as a simple CDN. Initial setup is simple, albeit a bit unusual.

Basic S3 Setup

After registering for the service at Amazon’s site, you’ll need to collect your access credentials to allow Rails to connect to your account. You can find this in the Security Credentials link under the Your Account menu. Create a simple yaml file in your config directory with the following details:

# config/s3.yml
access_key_id: <your access key here>
secret_code: <your secret code here>

Note that this file can be configured to support multiple environments as well:

# config/s3.yml
  access_key_id: <your development access key here>
  secret_code: <your development secret code here>
  access_key_id: <your production access key here>
  secret_code: <your production secret code here>

S3 Buckets

I found that the tricky part in setting up Paperclip was dealing with S3 buckets. Buckets are something like file folders in the cloud, with the unusual stipulation that each bucket name must be unique across the entire service. Paperclip requires that you specify an S3 bucket to store your files in; unfortunately it doesn’t handle the creation of the buckets for you. That’s where the aws-s3 gem comes into play. Install it with gem install aws-s3, drop into the Rails console and execute the following:

# load the aws-s3 gem
>> require 'aws/s3'
=> []
# connect to your account
>> AWS::S3::Base.establish_connection!(YAML.load_file('config/s3.yml').symbolize_keys!)
=> <AWS::S3::Connection:0x2236d90 @secret_access_key=<your secret key>, @http=#<Net::HTTP s3.amazonaws.com:80 open=false>, @access_key_id=<your access id>, @options={:access_key_id=><your access id>, :secret_access_key=><your secret key>, :server=>"s3.amazonaws.com", :port=>80}>
# create your unique bucket
>> AWS::S3::Bucket.create('your_unique_s3_bucket')
=> true

Paperclip with S3

Once you’ve got your configuration file set and bucket created, it’s time to set up your model. Paperclip’s RDOC is really great at describing all the various options for their model and is well worth the time to read through. On top of that, there are several great tutorials on getting Paperclip running. The basics though, with the important S3 bits added, look like this:

# models/photo.rb
has_attached_file :image,
  :styles => { :thumbnail => "100x100>" },
  :storage => :s3,
  :s3_credentials => "#{Rails.root}/config/s3.yml",
  :bucket => "your_unique_s3_bucket";

Note that you can specify the :bucket option in your config/s3.yml file instead.

Using ImageMagick to Auto-Orient Images

With the above, you’ll have a functional S3-backed Paperclip-powered model. I quickly ran into an annoying problem though. Modern digital cameras add special metadata to their photos that indicates the orientation of the camera when a photo is taken. Unfortunately, most web browsers aren’t smart enough yet to handle that extra info, so whereas the photo appears as intended on the desktop, it appears flopped onto its side on the web. Some developers have taken to using RMagick to properly orient their photo uploads, but I’ve found that there’s a simpler way. Paperclip exposes a hook to send custom conversion flags straight to ImageMagick when a photo is uploaded. Even better, ImageMagick has a simple flag -auto-orient to handle automatically orient images according to their metadata. Simply change the model above to:

# models/photo.rb
has_attached_file :image,
  :styles => { :thumbnail => "100x100>" },
  :storage => :s3,
  :s3_credentials => "#{Rails.root}/config/s3.yml",
  :bucket => "your_unique_s3_bucket",
  :convert_options => { :all => "-auto-orient" }

You’ll now have a modern-camera-friendly, cloud-hosted image attachment system for your app. Enjoy!

List Comprehensions in Ruby

October 27, 2009

I think list comprehensions are one of the neatest features of Python. They’re extremely readable, and are pretty simple to learn. They take verbose, loop-based array handlers and compact them into one elegant line. As an example, the list comprehension below produces the primes between 1 and 10:

# suppose isPrime(n) returns the primality of n
[x for x in range(1,10) if isPrime(x)]
# => [2, 3, 5, 7]

When I migrated from Python to Ruby recently, I was disappointed to find that there was no simple replacement for list comprehensions. Top that with everyone in the Ruby community saying “Ruby doesn’t do list comprehensions,” and I basically gave up on my hope of finding a suitable analogue. Fortunately though, I stumbled upon a thread in Ruby-Forum recently showing how to quickly add the capability onto any array!

The meat of the trick is this:

module Enumerable
  def comprehend( &amp;block )
    block ? map( &amp;block ).compact : self

With this monkey patch, I’m now able to write:

# Likewise, is_prime?(n) returns primality of n
(1..9).comprehend { |x| x if is_prime?(x) }
# => [2, 3, 5, 7]

While this isn’t a direct replacement of Python’s implementation, it’s at least enough to prove that Ruby is surprisingly powerful!


Get every new post delivered to your Inbox.