Skip to content

Instantly share code, notes, and snippets.

@jeffrafter
Created February 10, 2009 05:40
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jeffrafter/61257 to your computer and use it in GitHub Desktop.
Save jeffrafter/61257 to your computer and use it in GitHub Desktop.
Simple resource access using HTTParty and avoiding the weight of ActiveResource
require File.join(File.dirname(__FILE__), 'resource_party')
class Foo < ResourceParty::Base
base_uri Lokii::Config.remote
route_for 'foos'
resource_for 'foo'
end
class FoosController < ApplicationController
# GET /foo
# GET /foo.xml
def index
@foo = Foo.find(:all)
respond_to do |format|
format.html # index.rhtml
format.xml { render :xml => @foo.to_xml }
end
end
# GET /foo/1
# GET /foo/1.xml
def show
@foo = Foo.find(params[:id])
respond_to do |format|
format.html # show.rhtml
format.xml { render :xml => @foo.to_xml }
end
rescue ActiveRecord::RecordNotFound => rnf
render :text => rnf.message, :status => :not_found
rescue Exception => e
render :text => e.message, :status => :error
end
# GET /foo/new
def new
@foo = Foo.new
respond_to do |format|
format.html # new.rhtml
format.xml { render :xml => @foo.to_xml }
end
end
# GET /foo/1;edit
def edit
@foo = Foo.find(params[:id])
end
# POST /foo
# POST /foo.xml
def create
@foo = Foo.new(params[:foo])
respond_to do |format|
if @foo.save
flash[:notice] = 'Foo type was successfully created.'
format.html { redirect_to foo_url(@foo) }
format.xml { render :xml => @foo.to_xml }
else
format.html { render :action => "new" }
format.xml { render :xml => @foo.errors.to_xml }
end
end
rescue Exception => e
render :text => e.message, :status => :error
end
# PUT /foo/1
# PUT /foo/1.xml
def update
@foo = Foo.find(params[:id])
respond_to do |format|
if @foo.update_attributes(params[:foo])
flash[:notice] = 'Foo type was successfully updated.'
format.html { redirect_to foo_url(@foo) }
format.xml { render :xml => @foo.to_xml }
else
format.html { render :action => "edit" }
format.xml { render :xml => @foo.errors.to_xml }
end
end
rescue ActiveRecord::RecordNotFound => rnf
render :text => rnf.message, :status => :not_found
rescue Exception => e
render :text => e.message, :status => :error
end
# DELETE /foo/1
# DELETE /foo/1.xml
def destroy
@foo = Foo.find(params[:id])
@foo.destroy
respond_to do |format|
format.html { redirect_to foo_url }
format.xml { head :ok }
end
rescue ActiveRecord::RecordNotFound => rnf
render :text => rnf.message, :status => :not_found
rescue Exception => e
render :text => e.message, :status => :error
end
end
require 'httparty'
module ResourceParty
class ServerError < RuntimeError; end
class RecordNotFound < RuntimeError; end
class Base
include HTTParty
attr_accessor :attributes
def self.route_for(val)
class_eval("def self.route; '#{val}'; end")
end
def self.resource_for(val)
class_eval("def self.resource; '#{val}'; end")
end
def initialize(params = {}, query = {}, no_defaults = false)
return self if no_defaults
response = self.class.get("/#{self.route}/new.xml")
raise ServerError.new(response.body) if response.code != "200"
hash = Hash.from_xml(response.body).values.first
hash.merge! params
self.class.from_xml hash, self
end
def self.find(id, query = {})
response = self.get("/#{self.route}/#{id}.xml", :query => query)
raise RecordNotFound.new(response.body) if response.code == "404"
raise ServerError.new(response.body) if response.code != "200"
hash = Hash.from_xml(response.body).values.first
self.from_xml hash
end
def self.create(params = {}, query = {})
response = self.post("/#{self.route}.xml", :body => body_for(params), :query => query)
raise ServerError.new(response.body) if response.code != "200"
hash = Hash.from_xml(response.body).values.first
self.from_xml hash
end
def self.update(id, params = {}, query = {})
response = self.put("/#{self.route}/#{id}.xml", :body => body_for(params), :query => query)
raise RecordNotFound.new(response.body) if response.code == "404"
raise ServerError.new(response.body) if response.code != "200"
hash = Hash.from_xml(response.body).values.first
self.from_xml hash
end
def update(params = {}, query = {})
self.class.update(self.id, params, query)
end
def self.destroy(id, query = {})
response = self.delete("/#{self.route}/#{id}.xml", :query => query, :format => :text)
raise RecordNotFound.new(response.body) if response.code == "404"
raise ServerError.new(response.body) if response.code != "200"
true
end
def destroy(query = {})
self.class.destroy(self.id, query)
end
def self.all(query = {})
response = self.get("/#{self.route}.xml", :query => query)
raise ServerError.new(response.body) if response.code != "200"
items = response.values.first
items.map{|hash| self.from_xml hash }
end
private
def self.body_for(params)
body = {}
params.each{|n,v| body["#{self.resource}[#{n}]"] = v }
body.to_query
end
def self.from_xml(params, obj = nil)
obj ||= self.new({}, {}, true)
obj.attributes = params
mod = Module.new do
obj.attributes.keys.each do |k|
define_method(k) do
return self.attributes[k]
end
define_method("#{k}=") do |val|
self.attributes[k] = val
end
end
end
obj.send(:extend, mod)
obj
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment