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
suggestaction. - 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
createaction 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_oneassociation. - 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”.
[...] the infrastructure in place for the suggestions feature, it’s easy to add new kinds of suggestions – especially [...]
Pingback by Echographia » where it’s at — June 12, 2009 @ 12:22 am