I started with simple, concrete hypermedia for Objectives. For the collection I created a collection method, into which I passed the Objectives to create a collection+json object. For a single record, I loop through its associations with reflect_on_all_associations, and create links to all its associated objects.
I then moved this logic to ApplicationController and abstracted it for use with Indicators.
Namespaces in this hackery were a little tricky: self_link could theoretically mean either:
{"rel": "self", "href": "/path/to/self"}or
Link: <http://localhost:3000/path/to/self?page=1>;rel=selfI don't know Rails well enough (yet!) to create a new renderer. The Rails 3 respond_to do |format| is messy, but for my small customizations it worked:
respond_to do |format|
  format.html # index.html.erb
    format.json { render json: collection(@indicators),
                         content_type: "collection+json"
                  response.headers['Link'] = link_header(current_page, last_page) }
endI added pagination at the end. I needed a page_num util to do some calculations for the Link header, and my code for that is pretty wet (i.e. not DRY).
The billboard URL was also very un-Railsy. I explictly defined everything in root_controller.rb, as opposed to looping through the top-level models.
I'm sure I didn't form rel attributes well. I didn't have a clear idea of what a client might be expecting.
Before I go forward, I really want to extract this into a gem, and see if I can get more logic in the Model. From my experiment today it seems that a lot of this behavior is very generalizable, and could be customized easily (if it's a good gem, which I don't yet know how to write).
I imagine a 'hypermediafy' gem that:
- moves more logic to the model
- uses ActiveSupport::Concern
- can extend will_paginate and kaminari
One could implement it by doing:
# /app/models/indicator.rb
class Indicator < ActiveRecord::Base
    attr_accessible :attribute ...
    belongs_to      :objective
    has_many        :measurements, :datasets
    paginates_per   10
    
    hyperlinks_for  :objective, :measurements # whitelist relations to pass to `reflect_on_all_assocations`
    paginate_header :prev, :next # Adds rel=prev and rel=next links in the Link header
                                 # when used with a pagination gem like will_paginate or kaminari
    
end# /app/controllers/indicators_controller.rb
class IndicatorsController < ApplicationController
  # GET /indicators
  # GET /indicators.json
  def index
    @indicators = Indicator.page(params[:page])
    respond_to do |format| # responds to 'Accept' headers
      format.html # index.html.erb
      format.json { render hypermedia: @indicators } # or render collection: @indicators
                                                     # sets Content-Type to 'collection+json'
    end
  end
  
# ...
endI haven't yet done anything with authorization or PUT/POST actions. That's up next.
I also want to start defining ALPS.io semantics, and I could use help getting started there.
@beechnut
looks like you're making good progress. i'll be interested in the "gem-ification" process; esp regarding generating links.
let me know what your plans are for ALPS semantics. i'd be happy to pitch in and/or kibitz along the way.