jeffrafter-resource_party 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/LICENSE +20 -0
- data/README +150 -0
- data/Rakefile +35 -0
- data/VERSION.yml +4 -0
- data/lib/resource_party.rb +99 -0
- data/test/resource_party_test.rb +7 -0
- data/test/test_helper.rb +9 -0
- metadata +67 -0
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2008 Jeff Rafter
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README
ADDED
@@ -0,0 +1,150 @@
|
|
1
|
+
resource_party
|
2
|
+
==============
|
3
|
+
|
4
|
+
ResourceParty is a simple wrapper around HTTParty that allows you to do basic
|
5
|
+
operations with a restful resource (presumably implemented in rails). It
|
6
|
+
assumes a scaffolded resource in the following form:
|
7
|
+
|
8
|
+
class FoosController < ApplicationController
|
9
|
+
# GET /foo
|
10
|
+
# GET /foo.xml
|
11
|
+
def index
|
12
|
+
@foo = Foo.find(:all)
|
13
|
+
respond_to do |format|
|
14
|
+
format.html # index.rhtml
|
15
|
+
format.xml { render :xml => @foo.to_xml }
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
# GET /foo/1
|
20
|
+
# GET /foo/1.xml
|
21
|
+
def show
|
22
|
+
@foo = Foo.find(params[:id])
|
23
|
+
respond_to do |format|
|
24
|
+
format.html # show.rhtml
|
25
|
+
format.xml { render :xml => @foo.to_xml }
|
26
|
+
end
|
27
|
+
rescue ActiveRecord::RecordNotFound => rnf
|
28
|
+
render :text => rnf.message, :status => :not_found
|
29
|
+
rescue Exception => e
|
30
|
+
render :text => e.message, :status => :error
|
31
|
+
end
|
32
|
+
|
33
|
+
# GET /foo/new
|
34
|
+
def new
|
35
|
+
@foo = Foo.new
|
36
|
+
respond_to do |format|
|
37
|
+
format.html # new.rhtml
|
38
|
+
format.xml { render :xml => @foo.to_xml }
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
# GET /foo/1;edit
|
43
|
+
def edit
|
44
|
+
@foo = Foo.find(params[:id])
|
45
|
+
end
|
46
|
+
|
47
|
+
# POST /foo
|
48
|
+
# POST /foo.xml
|
49
|
+
def create
|
50
|
+
@foo = Foo.new(params[:foo])
|
51
|
+
respond_to do |format|
|
52
|
+
if @foo.save
|
53
|
+
flash[:notice] = 'Foo type was successfully created.'
|
54
|
+
format.html { redirect_to foo_url(@foo) }
|
55
|
+
format.xml { render :xml => @foo.to_xml }
|
56
|
+
else
|
57
|
+
format.html { render :action => "new" }
|
58
|
+
format.xml { render :xml => @foo.errors.to_xml }
|
59
|
+
end
|
60
|
+
end
|
61
|
+
rescue Exception => e
|
62
|
+
render :text => e.message, :status => :error
|
63
|
+
end
|
64
|
+
|
65
|
+
# PUT /foo/1
|
66
|
+
# PUT /foo/1.xml
|
67
|
+
def update
|
68
|
+
@foo = Foo.find(params[:id])
|
69
|
+
respond_to do |format|
|
70
|
+
if @foo.update_attributes(params[:foo])
|
71
|
+
flash[:notice] = 'Foo type was successfully updated.'
|
72
|
+
format.html { redirect_to foo_url(@foo) }
|
73
|
+
format.xml { render :xml => @foo.to_xml }
|
74
|
+
else
|
75
|
+
format.html { render :action => "edit" }
|
76
|
+
format.xml { render :xml => @foo.errors.to_xml }
|
77
|
+
end
|
78
|
+
end
|
79
|
+
rescue ActiveRecord::RecordNotFound => rnf
|
80
|
+
render :text => rnf.message, :status => :not_found
|
81
|
+
rescue Exception => e
|
82
|
+
render :text => e.message, :status => :error
|
83
|
+
end
|
84
|
+
|
85
|
+
# DELETE /foo/1
|
86
|
+
# DELETE /foo/1.xml
|
87
|
+
def destroy
|
88
|
+
@foo = Foo.find(params[:id])
|
89
|
+
@foo.destroy
|
90
|
+
respond_to do |format|
|
91
|
+
format.html { redirect_to foo_url }
|
92
|
+
format.xml { head :ok }
|
93
|
+
end
|
94
|
+
rescue ActiveRecord::RecordNotFound => rnf
|
95
|
+
render :text => rnf.message, :status => :not_found
|
96
|
+
rescue Exception => e
|
97
|
+
render :text => e.message, :status => :error
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
Returning head :ok for create and update is permissable (though I find returning
|
102
|
+
the actual resource is potentially more helpful as there may have been changes
|
103
|
+
made in the model before_create or before_update).
|
104
|
+
|
105
|
+
Notice that there is explicit exception handling which improves the
|
106
|
+
communication. This will hopefully be expanded to include better validation
|
107
|
+
error handling.
|
108
|
+
|
109
|
+
To make your models join the party:
|
110
|
+
|
111
|
+
require 'resource_party'
|
112
|
+
|
113
|
+
class Foo < ResourceParty::Base
|
114
|
+
base_uri 'http://localhost:3000'
|
115
|
+
route_for 'foos'
|
116
|
+
resource_for 'foo'
|
117
|
+
end
|
118
|
+
|
119
|
+
+route_for+ will be used to generate the path, i.e. "/{route_for}/4.xml"
|
120
|
+
+resource_for+ will be used when building params (like form_for)
|
121
|
+
|
122
|
+
I know both of these are automatic if you are already using active_support by
|
123
|
+
using class.to_s.downcase.singularize and friends. But hey.
|
124
|
+
|
125
|
+
Once this is built you should be able to
|
126
|
+
|
127
|
+
Foo.all
|
128
|
+
=> returns an array of Foos (from the index)
|
129
|
+
|
130
|
+
Foo.find(id)
|
131
|
+
=> returns a foo or a ResourceParty::RecordNotFound
|
132
|
+
|
133
|
+
Foo.destroy(id) or foo.destroy
|
134
|
+
=> Deletes the foo, returns true if successful
|
135
|
+
|
136
|
+
Foo.update(id, {:my_field => "this is the change!"}) or foo.update(...)
|
137
|
+
=> Updates the foo with the params, returns true if the controller
|
138
|
+
=> responds with :head, otherwise returns the foo
|
139
|
+
|
140
|
+
Foo.create({:my_field => "this is the new stuff"})
|
141
|
+
=> Creates the foo with the params, returns true if the controller
|
142
|
+
=> responds with :head, otherwise returns the foo
|
143
|
+
|
144
|
+
Foo.new
|
145
|
+
=> Fetches a blank foo so that defaulted params are possible
|
146
|
+
|
147
|
+
COPYRIGHT
|
148
|
+
=========
|
149
|
+
|
150
|
+
Copyright (c) 2008 Jeff Rafter. See LICENSE for details.
|
data/Rakefile
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'rake/testtask'
|
3
|
+
require 'rake/rdoctask'
|
4
|
+
|
5
|
+
begin
|
6
|
+
require 'jeweler'
|
7
|
+
Jeweler::Tasks.new do |s|
|
8
|
+
s.name = "resource_party"
|
9
|
+
s.summary = "Simplified resource interaction using HTTParty"
|
10
|
+
s.email = "jeff@baobabhealth.org"
|
11
|
+
s.homepage = "http://github.com/jeffrafter/resource_party"
|
12
|
+
s.description = "Simple wrapper for HTTParty for basic operations with a restful resource"
|
13
|
+
s.authors = ["Jeff Rafter"]
|
14
|
+
s.add_dependency "jnunemaker-httparty"
|
15
|
+
s.files = FileList["[A-Z]*", "{lib,test}/**/*"]
|
16
|
+
end
|
17
|
+
rescue LoadError
|
18
|
+
puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
|
19
|
+
end
|
20
|
+
|
21
|
+
Rake::TestTask.new do |t|
|
22
|
+
t.libs << 'lib'
|
23
|
+
t.pattern = 'test/**/*_test.rb'
|
24
|
+
t.verbose = false
|
25
|
+
end
|
26
|
+
|
27
|
+
Rake::RDocTask.new do |rdoc|
|
28
|
+
rdoc.rdoc_dir = 'rdoc'
|
29
|
+
rdoc.title = 'resource_party'
|
30
|
+
rdoc.options << '--line-numbers' << '--inline-source'
|
31
|
+
rdoc.rdoc_files.include('README*')
|
32
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
33
|
+
end
|
34
|
+
|
35
|
+
task :default => :test
|
data/VERSION.yml
ADDED
@@ -0,0 +1,99 @@
|
|
1
|
+
require 'httparty'
|
2
|
+
|
3
|
+
module ResourceParty
|
4
|
+
class ServerError < RuntimeError; end
|
5
|
+
class RecordNotFound < RuntimeError; end
|
6
|
+
class Base
|
7
|
+
include HTTParty
|
8
|
+
|
9
|
+
attr_accessor :attributes
|
10
|
+
|
11
|
+
def self.route_for(val)
|
12
|
+
class_eval("def self.route; '#{val}'; end")
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.resource_for(val)
|
16
|
+
class_eval("def self.resource; '#{val}'; end")
|
17
|
+
end
|
18
|
+
|
19
|
+
def initialize(params = {}, query = {}, no_defaults = false)
|
20
|
+
return self if no_defaults
|
21
|
+
response = self.class.get("/#{self.route}/new.xml")
|
22
|
+
raise ServerError.new(response.body) if response.code != "200"
|
23
|
+
hash = Hash.from_xml(response.body).values.first
|
24
|
+
hash.merge! params
|
25
|
+
self.class.from_xml hash, self
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.find(id, query = {})
|
29
|
+
response = self.get("/#{self.route}/#{id}.xml", :query => query)
|
30
|
+
raise RecordNotFound.new(response.body) if response.code == "404"
|
31
|
+
raise ServerError.new(response.body) if response.code != "200"
|
32
|
+
hash = Hash.from_xml(response.body).values.first
|
33
|
+
self.from_xml hash
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.create(params = {}, query = {})
|
37
|
+
response = self.post("/#{self.route}.xml", :body => body_for(params), :query => query)
|
38
|
+
raise ServerError.new(response.body) if response.code != "200"
|
39
|
+
hash = Hash.from_xml(response.body).values.first
|
40
|
+
self.from_xml hash
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.update(id, params = {}, query = {})
|
44
|
+
response = self.put("/#{self.route}/#{id}.xml", :body => body_for(params), :query => query)
|
45
|
+
raise RecordNotFound.new(response.body) if response.code == "404"
|
46
|
+
raise ServerError.new(response.body) if response.code != "200"
|
47
|
+
hash = Hash.from_xml(response.body).values.first
|
48
|
+
self.from_xml hash
|
49
|
+
end
|
50
|
+
|
51
|
+
def update(params = {}, query = {})
|
52
|
+
self.class.update(self.id, params, query)
|
53
|
+
end
|
54
|
+
|
55
|
+
def self.destroy(id, query = {})
|
56
|
+
response = self.delete("/#{self.route}/#{id}.xml", :query => query, :format => :text)
|
57
|
+
raise RecordNotFound.new(response.body) if response.code == "404"
|
58
|
+
raise ServerError.new(response.body) if response.code != "200"
|
59
|
+
true
|
60
|
+
end
|
61
|
+
|
62
|
+
def destroy(query = {})
|
63
|
+
self.class.destroy(self.id, query)
|
64
|
+
end
|
65
|
+
|
66
|
+
def self.all(query = {})
|
67
|
+
response = self.get("/#{self.route}.xml", :query => query)
|
68
|
+
raise ServerError.new(response.body) if response.code != "200"
|
69
|
+
items = response.values.first
|
70
|
+
items.map{|hash| self.from_xml hash }
|
71
|
+
end
|
72
|
+
|
73
|
+
private
|
74
|
+
|
75
|
+
def self.body_for(params)
|
76
|
+
body = {}
|
77
|
+
params.each{|n,v| body["#{self.resource}[#{n}]"] = v }
|
78
|
+
body.to_query
|
79
|
+
end
|
80
|
+
|
81
|
+
def self.from_xml(params, obj = nil)
|
82
|
+
obj ||= self.new({}, {}, true)
|
83
|
+
obj.attributes = params
|
84
|
+
mod = Module.new do
|
85
|
+
obj.attributes.keys.each do |k|
|
86
|
+
define_method(k) do
|
87
|
+
return self.attributes[k]
|
88
|
+
end
|
89
|
+
|
90
|
+
define_method("#{k}=") do |val|
|
91
|
+
self.attributes[k] = val
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
obj.send(:extend, mod)
|
96
|
+
obj
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
data/test/test_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: jeffrafter-resource_party
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Jeff Rafter
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-02-10 00:00:00 -08:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: jnunemaker-httparty
|
17
|
+
version_requirement:
|
18
|
+
version_requirements: !ruby/object:Gem::Requirement
|
19
|
+
requirements:
|
20
|
+
- - ">="
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: "0"
|
23
|
+
version:
|
24
|
+
description: Simple wrapper for HTTParty for basic operations with a restful resource
|
25
|
+
email: jeff@baobabhealth.org
|
26
|
+
executables: []
|
27
|
+
|
28
|
+
extensions: []
|
29
|
+
|
30
|
+
extra_rdoc_files: []
|
31
|
+
|
32
|
+
files:
|
33
|
+
- LICENSE
|
34
|
+
- Rakefile
|
35
|
+
- README
|
36
|
+
- VERSION.yml
|
37
|
+
- lib/resource_party.rb
|
38
|
+
- test/resource_party_test.rb
|
39
|
+
- test/test_helper.rb
|
40
|
+
has_rdoc: false
|
41
|
+
homepage: http://github.com/jeffrafter/resource_party
|
42
|
+
post_install_message:
|
43
|
+
rdoc_options: []
|
44
|
+
|
45
|
+
require_paths:
|
46
|
+
- lib
|
47
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
48
|
+
requirements:
|
49
|
+
- - ">="
|
50
|
+
- !ruby/object:Gem::Version
|
51
|
+
version: "0"
|
52
|
+
version:
|
53
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
54
|
+
requirements:
|
55
|
+
- - ">="
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
version: "0"
|
58
|
+
version:
|
59
|
+
requirements: []
|
60
|
+
|
61
|
+
rubyforge_project:
|
62
|
+
rubygems_version: 1.2.0
|
63
|
+
signing_key:
|
64
|
+
specification_version: 2
|
65
|
+
summary: Simplified resource interaction using HTTParty
|
66
|
+
test_files: []
|
67
|
+
|