In the past few years, many companies have been embedding machine-readable metadata in their web pages. Among these is Best Buy, which provides extensive RDFa data describing their products, prices and user reviews.

The following 20-minute screencast shows how to use Ruby 1.9.2, Rails 3.1rc1, RDF.rb and my rdf-agraph gem to compare user ratings of the iPad and various Android Honeycomb tablets.

Screencast

Formats: Ogg Theora, MP4

If you're at SemTech 2011 this coming week, and you'd like to learn more about Ruby and RDF, you're welcome attend my talk on Wednesday afternoon. I'll discuss some great tools from the RDF.rb maintainers, and suggest ideas on where to go from here.

Screenshot

Here's what the final output looks like:

Code snippets from the video

Add the following lines to your Gemfile and rerun bundle install:

gem 'rdf', '~> 0.3.3'
gem 'rdf-rdfa', '~> 0.3.3'
gem 'rdf-agraph', '~> 0.3.1'

Create config/initializers/rdf.rb to set up our RDF repository and vocabulary:

require 'rdf/rdfa'

REPO_URL =
  "http://test:test@0.0.0.0:10035/repositories/product_comparison_#{Rails.env}"
REPO = RDF::AllegroGraph::Repository.new(REPO_URL)

DV = RDF::Vocabulary.new("http://rdf.data-vocabulary.org/#")

Run the following code under rails console to download the RDFa data and store it in AllegroGraph:

graph = RDF::Graph.load("http://www.bestbuy.com/shop/ipad+xoom+-windows*")
REPO.insert(graph)

Create app/controllers/reviews_controller.rb to perform the query and bind @reviews for use in our view:

class ReviewsController < ApplicationController
  def index
    @reviews = REPO.build_query do |q|
      q << [:review, RDF.type, DV['Review-aggregate']]
      q << [:review, DV.itemreviewed, :name]
      q << [:review, DV.rating, :rating]
      q << [:rating, DV.rating, :stars]
    end.run.sort_by do |review|
      review.stars
    end.reverse
  end
end

Create app/views/reviews/index.html.erb to display the product ratings:

<table>
  <% @reviews.each do |review| %>
    <tr>
      <td><%= stars(review.stars) %></td>
      <td><%= sanitize(review.name.to_s) %></td>
    </tr>
  <% end %>
</table>

And add a helper function in app/helpers/application_helper.rb to display the stars:

module ApplicationHelper
  def stars(literal)
    image_tag("stars#{literal.to_s.to_f*1.0}.png",
              :width => 100, :height => 20)
  end
end