Echographia

making things better, making better things

Saturday, October 31, 2009

sometimes I’m not smart

You know those times when you’re looking all over the house for something and then somebody says, “Is that it in your other hand?”

Last night I spent at least an hour trying to figure out why I was getting a nil.rewrite error from Rails’s url_for method. I’ve seen hard-to-debug errors from there before, so I dug right down into it, but I couldn’t figure out why the @url variable was set in some cases and not in others… and then I determined that it actually was being set in all cases, but then it was mysteriously blank by the time url_for needed it….

And then I realized it was because I had a @url variable in my own controller action. And then I went to bed.

Most of the time I really love how dynamic and open Ruby is as a language, but sometimes private instance variables are just what you’d like to have had.

posted by erik at 11:39 am  

Monday, August 10, 2009

bugmash

This weekend RailsBridge ran its first Rails BugMash:

The idea is simple: RailsBridge has a lot of energy. The Rails Lighthouse has a lot of open tickets. With the help of some Rails Core team members, we’re going to see what we can do to cut down the number of open tickets, encourage more people to get involved with the Rails source, and have some fun.

Definitely a success – reportedly at least 120 tickets were closed, I’m sure a lot of new people got involved, and the people on #railsbridge seemed to be having fun.
(more…)

posted by erik at 10:34 am  

Friday, June 12, 2009

where it’s at

With the infrastructure in place for the suggestions feature, it’s easy to add new kinds of suggestions – especially if someone else has already done most of the work. For example, given an address, we should be able to look up the names of businesses at that address, and suggest them as venue names.

Yahoo! and Google both do this automatically if you search for something they recognize as an address. But Google doesn’t seem to provide an API. Yahoo! Local does, and the YM4R gem already provides a nice Ruby wrapper for it. So:

  def make_suggestions_based_on_address
    businesses = Ym4r::YahooMaps::BuildingBlock::LocalSearch::get(
      :location => address.block,
      :radius => 0.001,
      :results => 20,
      :query => '*'
      )
    businesses.each do |business|
      add_suggestion(:name, business.title)
      add_suggestion(:url, business.business_url) unless business.business_url.blank?
    end
  end

You might wonder about the radius parameter. Technically, Yahoo! doesn’t provide the service I want; I want “tell me what’s at this address”, it has “tell me what’s near this address”. With a radius of 0, it returns up to 10 results. After a little experimentation, it looks to me like 0.01 is a tight enough radius to get me all the businesses at an address – or at least the top 10 – and none of the ones next door.

This is actually one of two ways I’m subverting the API here. It’s intended for search, not simple lookup, which is why it’s a little awkward to get a simple address. It’s also why Yahoo! provides multiple URLs for each business. The BusinessUrl is the actual URL for the business’s web site. There’s also a BusinessClickUrl, which “contains extra information that helps [them] to optimize [their] search services. Yahoo! requests that you display the BusinessUrl, but link to the BusinessClickUrl, so they can track usage.

The latest code actually uses both URLs, but I’m going to stop here for now.

posted by erik at 12:22 am  

Wednesday, June 10, 2009

how to help

Here’s how the suggestions feature for Touring Machine works so far.

UI

  • As the user enters data in the new venue form, if we’re able to make any guesses, we pop them up in a panel to the right of the form.
  • Each suggestion is a link. If a user clicks a suggestion link, the suggestion is copied into the corresponding form field, and the field is given focus, so the user can edit it. (For example, if the “page title” suggestion has additional text around the venue name.)

There’s also an “accessible” JavaScript-free UI, but it’s bad, so I’m going to pretend it’s not there.

Client and Server

I started drawing an interaction diagram, but it’s really standard Rails stuff:

  • Model, controller, and view produce the new venue form.
  • When any form input’s value changes, we submit the whole form (as an AJAX GET) to the controller’s suggest action.
  • The server responds with an RJS view that populates and shows the suggestions panel (if there are any suggestions) or hides it (if not).
  • The suggestions are links that call a JavaScript function that copies, highlights, and focuses.
  • Once the user is done editing, the create action just works as normal.

Model

In keeping with the Skinny Controller, Fat Model approach, the only interesting code is in the model. It took me a couple of tries to get a design I liked, but eventually I went with Rails-style magic:

  def make_suggestions
    @suggestions = {}
 
    methods.grep(/^make_suggestions_based_on_/).each do |method|
      attrs = method.sub('make_suggestions_based_on_', '').split('_and_')
      values = attrs.map {|attr| send(attr)}
      send(method) unless values.any?(&:blank?)
    end
 
    suggestions
  end

When asked for suggestions:

  • We look through the Venue object for methods of the form make_suggestions_from_attr_and_other_attr. (We support multiple attributes so that, for example, given a venue name and vague address – city and state – we can look up the exact address.) Call these “suggesters”.
  • We call each suggester only if we have non-blank values for all the named attributes (because how are you going to base a suggestion on the venue’s address if you don’t know its address?). Note that although I’m saying “attributes”, this code works for attributes, associatons, and in fact any method. This is important because a venue’s address is actually a has_one association.
  • The suggesters populate @suggestions, and then we return it.

A small thing I’m pleased by: The make_suggestions method works both as “create suggestion objects” and in the idiomatic sense of “make a suggestion” as “suggest something”.

posted by erik at 1:55 pm  

Saturday, April 25, 2009

Rails 2.3 backtraces and emacs

This morning I exhumed an old Rails project and started cranking it forward from Rails 1.2.2 to the current version, 2.3.2. That’s about two years of Rails develpopment. This afternoon I got all the tests passing except for two (and I think they’re failing because Yahoo has changed its geocoder)… and then I found the other stash of tests. So, still working on it.

I spent some time tonight sidetracked by tools. In Emacs, thanks to Ryan Davis, I can shift-mouse-3 on pretty much any line in a stack trace and be taken to the right line in the right file. But under Rails 2.3 it doesn’t always work: (more…)

posted by erik at 9:54 pm  

Powered by WordPress