Archive for the 'Rails' Category

What to do in Portland when you’re at RailsConf 2008

I updated last year’s post about what to do in Portland while you’re at RailsConf, adding a few places and taking some out. Just want to help all you geeks from out of town avoid Red Robin and Starbucks. Get out there and find these places!

Read about what to do in Portland while you’re at RailsConf 2008

RailsConf 2007 Starts Today!

I won’t be attending today’s tutorial sessions, but I’ll be at the conference starting tomorrow. Check out this Map at Google’s My Maps that someone put together, it has a few more things plotted out than I mentioned in my post about what to do in Portland while at RailsConf, but one small mistake I found that you may want to know about is that the Coffee People listed on the map is closed forever. Unfortunately they sold out to Starbucks and it will be replaced very soon with yet another Starbucks. The only reason I mention this is because coffee == freedom, and if you need your coffee fix and want to avoid Starbucks, you’ll be sorely disappointed when you find a closed down Coffee People.

Check out these places to grab coffee instead:

What to do in Portland while you’re at RailsConf 2007 (updated for 2008)

If you’re attending RailsConf this year and are from out of town, you might be like me when you’re in another city: I don’t really find much outside of the touristy areas, or what’s immediately around where I’m staying. But you’re in luck! I live here in Portland, Oregon and I have a list of places to go and things to do that I think are quintessential Portland.I’ve tried to pick places that are close to the convention center, but most places will require either taking Tri-Met bus, light rail or street car, or driving. Each listing has a link to directions from the convention center so you can see about how far it is.

Good places to eat lunch or dinner
The immediate area around the convention center is mostly places like Denny’s and Red Robin. I wouldn’t recommend eating there. Here are some places for getting some good food.
Good places to eat breakfast
One thing Portlanders know how to do right is make a tasty breakfast. Check out these places if you have time to get up early and eat before the conference starts for the day.
Go see a movie, and have a beer
Portland, as far as I know, is one of the very few cities that have so many movie theatres that serve beer and food. AND to top it off, most movies are $3-$6 admission. Check out one of these theatres for a magical movie and beer experience.
Coffee Shops Galore
Portland has no shortage of coffee shops. Try not to go to Starbucks and find one of these local coffee shops.
Happy Hours
Come 4pm you’ll be wanting you some drinks. There are plenty of happy hours around town, but here are a few recommended.

Find more Portland Happy Hours at Unthirsty.com

Powell’s/Powell’s Technical
Powell’s Books is one of the largest book stores in the world, and to make it even better, they have a separate store that only sells technical books (I picked up my Programming Ruby book there, among others).
Places to find gifts for your Significant Other
You might get in trouble if you go to a conference out of town and not bring back a gift. Luckily for you there are a couple areas you can check out that have unique gifts.
Relive the golden age of arcade games
The only place in Portland that has all the classic arcade games, beer, wine and DJs you can take.
See a live band
Every night you’ll find tons of bands playing in lots of clubs around Portland. Check out the Portland Mercury before you come, or pick one up while you’re here. You find all the band listings, as well as other stuff to do while you’re here. Listed below are some recommended venues.

If you know a great place to eat, drink or have fun in Portland, leave a comment below with a suggestion or link to your list. See you at the conference.

Hacking Rails HTML form helpers to add CSS classes

I really like using Rails form helpers, but one thing I found myself doing often is assigning classes to elements that I want to style a bit differently than the rest. But, I have to remember to do that for every element that I want it applied to. Luckily the nature of Ruby lets you open up classes and modules to redefine methods, so I was able to hack up the ActionView tag helpers directly in my Rails app. The result is that by default, all form elements generated by the helpers get a CSS class name based on what type of element it is.

How is this useful? Well for instance, I like to style my HTML submit buttons to be fixed width and center aligned. With CSS, I can’t style a submit button specifically because it’s an input element. There are also input elements that can be text fields, radio buttons, and checkboxes, but I don’t want it to apply to them as well. So the path of least resistance to style a submit button exclusively is to assign it a class every time I use it. It can get tedious to have to remember that every time I build a new form in my application.

So here is my solution: hacking the ActionView tag helper module to make any form element automatically have a class assigned to it based on what type of element it is. In the case of a submit element, it will have a class submit_button. Then all I have to do is define the selector for input.submit_button in my stylesheet and I’m done. All submit buttons will now be styled the way I want, and I don’t have to remember to assign them a class every time I place one in a template.

Add this code to your application.rb file (or anywhere you’d like) and your form elements will get nice CSS classes by default. It will even keep any class names you assign to your tags and append the default one at the end. I’ve verified it working using ActionPack-1.12.5 and later (Rails 1.1.6 – 1.2.3).

  module ActionView
    module Helpers
      module TagHelper        def tag(name, options = nil, open = false)
          add_default_class(name,options)
          "<#{name}#{tag_options(options) if options}" + (open ? ">" : " />")
        end        def content_tag(name, content_or_options_with_block = nil, options = nil, &block)
          if block_given?
            options = content_or_options_with_block if content_or_options_with_block.is_a?(Hash)
            add_default_class(name,options)
            content = capture(&block)
            concat(content_tag_string(name, content, options), block.binding)
          else
            add_default_class(name,options)
            content = content_or_options_with_block
            content_tag_string(name, content, options)
          end
        end        private        def add_default_class(name,options)
          options = Hash.new if options.nil?
          class_name = case name.to_s
          when 'textarea'
            'text_area'
          when 'select'
            'select'
          else
            nil
          end          if class_name.nil? && options.has_key?('type')
            class_name = case options['type']
            when 'text'
              'text_field'
            when 'password'
              'password_field'
            when 'file'
              'file_field'
            when 'radio'
              'radio_button'
            when 'checkbox'
              'check_box'
            when 'submit'
              'submit_button'
            when 'image'
              'submit_image'
            when 'button'
              'button'
            else
              nil
            end
          end
          return options if class_name.nil?
          if options.has_key?('class')
            options['class'] += " #{class_name}"
          else
            options['class'] = "#{class_name}"
          end
        end
      end
    end
  end

Make Graticule failover to other geocoding services

The Graticule Ruby gem makes it super easy to geocode addresses using multiple services. One thing I’ve found in developing Unthirsty is that sometimes a geocoding service either fails to be reached or the address couldn’t be found. So as a precaution, I’ve set up a way for Graticule to failover to another service if a lookup fails. Here’s how.

First, set up a list of your preferred geocoding services. Graticule expects a service name and optionally an access key. Some geocoding services like Ontok don’t require a key. However Google does, and it’s probably the one you’ll want to use over the others. Order your geocoders so your preferred geocoders are listed first.

  PREFERRED_GEOCODERS = [
    {:name => :google, :key => '[your key here]'},
    {:name => :yahoo, :key => 'My Service'}, # yahoo will take any string for a key
    {:name => :geocoder_us, :key => 'My Service'} # same with geocoder.us
  ]

Take your pick of geocoding services. Graticule supports quite a few:

Now it’s time to put those geocoders to use. This method loops through your PREFERRED_GEOCODERS array and sets up a new Graticule instance with the service name and key you provided. It will then try to locate it with a lookup to that service. Calling the locate method on a service instance will raise an exception if an error occurs, so it’s possible to rescue all the different errors you can get while doing a lookup.

Note that this was used in a Rails project, so I’m using logger, a built in Rails logging facility. You may want to substitute your own logging method if you’re not using Rails.

  def geocode(query)
    PREFERRED_GEOCODERS.each{|service|
      begin
        geocoder = Graticule.service(service[:name]).new(service[:key])
        result = geocoder.locate(query)
        logger.info("Found address [#{query}] with service [#{service[:name]}]")
        return result unless result.precision == :country # probably not worth keeping
      rescue Graticule::AddressError => detail
        logger.error("Nothing found [#{query}] with service [#{service[:name]}] (#{detail})")
      rescue Graticule::Error => detail
        logger.error("Nothing found [#{query}] with service [#{service[:name]}] (#{detail})")
      rescue Graticule::CredentialsError => detail
        logger.error("Invalid credentials [#{service[:name]}] with [#{service[:key]}] (#{detail})")
      rescue Errno::ECONNREFUSED
        logger.error("Connection refused to #{service}")
      end
    }
    raise Graticule::AddressError.new("Couldn't find address [#{query}] with any service")
  end

The failover works because since we are in a begin..rescue block, a raised exception will cause it to skip over the return result line, log the exception, then move on to the next service. But if a lookup succeeds, it will return a new Graticule::Location instance that contains the results, and not go any further. If no lookups are successful, it will raise a new Graticule::AddressError exception that you can trap while calling the method in your code.

Also notice I don’t return a result if the :precision attribute is :country There’s pretty much no use for it if you’re going for specific addresses. You may want to adjust it based on your needs. Maybe you only want results that have :address precision.

You now have a failsafe method for geocoding locations in your Rails app. Leave a comment if you found this useful, or if you have any improvements. Enjoy!