MirrorMirror
A Ruby gem that allows for easier interactions and integration with external REST resources.
Installation
gem 'mirror_mirror'
Usage Example
Environment
# App controlled resource, reliant on external resource.
class Timesheet < ActiveRecord::Base
belongs_to :contractor, :auto_reflect => true
end
# Extenal Resource
class Contractor < ActiveRecord::Base
has_many :timesheets
mirror_mirror "http://api.example.com/v1/contractors",
:request => :resource_request, :find => true
def resource_request(verb, url, params)
response = RestClient.send(verb, url + '.json', params)
ActiveSupport::JSON.decode(response.to_str)["result"] if response.code == 200
end
end
# API Resource Example
{
result: [{
id: 1,
first_name: "Daniel",
last_name: "Doezema"
},
{
id: 2,
first_name: "John",
last_name: "Doe"
}]
}
External API Scenario
class ContractorsController < ApiController
# api/contractors/:id/clock_out
def clock_out
# Automatically found & created b/c of the mirror_mirror :find => true option
contractor = Contractor.find(params[:id])
timesheet = contractor.timesheets.last
result = timesheet.update_attributes(:ended_at => Time.now)
end
end
The "We've only got an id" Scenario
In this scenario a contractor_id
is present, but we don't know if the Contractor
record exists locally yet -- this is where the :auto_reflect
option helps out. If a local Contractor
record is not found then a request will automatically be made to fetch and create it.
# Controller
@timesheets = Timesheet.where("started_at > ?", Time.now.beginning_of_day)
# View
<h1>Today's Punched-In Contractors</h1>
<ul>
<% @timesheets.each do |timesheet| %>
<li><%= "#{timesheet.contractor.first_name} #{timesheet.contractor.last_name}"</li>
<% end %>
</ul>