resource_mapper 0.0.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/.autotest +23 -0
- data/.document +5 -0
- data/.gitignore +21 -0
- data/LICENSE +20 -0
- data/README.rdoc +17 -0
- data/Rakefile +84 -0
- data/VERSION +1 -0
- data/examples/example_helper.rb +42 -0
- data/examples/lib/sinatra/resource_example.rb +150 -0
- data/examples/models.rb +77 -0
- data/lib/resource_mapper.rb +31 -0
- data/lib/resource_mapper/accessors.rb +77 -0
- data/lib/resource_mapper/action_options.rb +35 -0
- data/lib/resource_mapper/actions.rb +56 -0
- data/lib/resource_mapper/class_methods.rb +65 -0
- data/lib/resource_mapper/controller.rb +56 -0
- data/lib/resource_mapper/failable_action_options.rb +25 -0
- data/lib/resource_mapper/helpers/current_objects.rb +82 -0
- data/lib/resource_mapper/helpers/internal.rb +58 -0
- data/lib/resource_mapper/helpers/nested.rb +67 -0
- data/lib/resource_mapper/response_collector.rb +27 -0
- data/lib/sinatra/resource.rb +104 -0
- data/resource_mapper.gemspec +80 -0
- metadata +170 -0
@@ -0,0 +1,67 @@
|
|
1
|
+
# Nested and Polymorphic Resource Helpers
|
2
|
+
#
|
3
|
+
module ResourceMapper
|
4
|
+
module Helpers
|
5
|
+
module Nested
|
6
|
+
protected
|
7
|
+
# Returns the relevant association proxy of the parent. (i.e. /posts/1/comments # => @post.comments)
|
8
|
+
#
|
9
|
+
def parent_association
|
10
|
+
@parent_association ||= parent_object.send(model_name.to_s.pluralize.to_sym)
|
11
|
+
end
|
12
|
+
|
13
|
+
# Returns the type of the current parent
|
14
|
+
#
|
15
|
+
def parent_type
|
16
|
+
@parent_type ||= parent_type_from_params || parent_type_from_request
|
17
|
+
end
|
18
|
+
|
19
|
+
# Returns the type of the current parent extracted from params
|
20
|
+
#
|
21
|
+
def parent_type_from_params
|
22
|
+
[*belongs_to].find { |parent| !params["#{parent}_id".to_sym].nil? }
|
23
|
+
end
|
24
|
+
|
25
|
+
# Returns the type of the current parent extracted form a request path
|
26
|
+
#
|
27
|
+
def parent_type_from_request
|
28
|
+
[*belongs_to].find { |parent| request.path.split('/').include? parent.to_s }
|
29
|
+
end
|
30
|
+
|
31
|
+
# Returns true/false based on whether or not a parent is present.
|
32
|
+
#
|
33
|
+
def parent?
|
34
|
+
!parent_type.nil?
|
35
|
+
end
|
36
|
+
|
37
|
+
# Returns true/false based on whether or not a parent is a singleton.
|
38
|
+
#
|
39
|
+
def parent_singleton?
|
40
|
+
!parent_type_from_request.nil? && parent_type_from_params.nil?
|
41
|
+
end
|
42
|
+
|
43
|
+
# Returns the current parent param, if there is a parent. (i.e. params[:post_id])
|
44
|
+
def parent_param
|
45
|
+
params["#{parent_type}_id".to_sym]
|
46
|
+
end
|
47
|
+
|
48
|
+
# Like the model method, but for a parent relationship.
|
49
|
+
#
|
50
|
+
def parent_model
|
51
|
+
parent_type.to_s.camelize.constantize
|
52
|
+
end
|
53
|
+
|
54
|
+
# Returns the current parent object if a parent object is present.
|
55
|
+
#
|
56
|
+
def parent_object
|
57
|
+
parent? && !parent_singleton? ? parent_model.find(parent_param) : nil
|
58
|
+
end
|
59
|
+
|
60
|
+
# If there is a parent, returns the relevant association proxy. Otherwise returns model.
|
61
|
+
#
|
62
|
+
def end_of_association_chain
|
63
|
+
parent? ? parent_association : model
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module ResourceMapper
|
2
|
+
class ResponseCollector
|
3
|
+
|
4
|
+
attr_reader :responses
|
5
|
+
|
6
|
+
delegate :clear, :to => :responses
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
@responses = []
|
10
|
+
end
|
11
|
+
|
12
|
+
def method_missing(method_name, &block)
|
13
|
+
@responses.delete self[method_name]
|
14
|
+
@responses << [method_name, block || nil]
|
15
|
+
end
|
16
|
+
|
17
|
+
def [](symbol)
|
18
|
+
@responses.find { |method, block| method == symbol }
|
19
|
+
end
|
20
|
+
|
21
|
+
def dup
|
22
|
+
returning ResponseCollector.new do |duplicate|
|
23
|
+
duplicate.instance_variable_set(:@responses, responses.dup)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
require 'sinatra/base'
|
2
|
+
require 'active_support/inflector'
|
3
|
+
|
4
|
+
module Sinatra
|
5
|
+
module Resource
|
6
|
+
DEFAULT_FORMAT = :json
|
7
|
+
|
8
|
+
def get_with_formats(path, options = {}, &block)
|
9
|
+
route_method_for_formats :get, path, options, &block
|
10
|
+
end
|
11
|
+
|
12
|
+
def post_with_formats(path, options = {}, &block)
|
13
|
+
route_method_for_formats :post, path, options, &block
|
14
|
+
end
|
15
|
+
|
16
|
+
def put_with_formats(path, options = {}, &block)
|
17
|
+
route_method_for_formats :put, path, options, &block
|
18
|
+
end
|
19
|
+
|
20
|
+
def delete_with_formats(path, options = {}, &block)
|
21
|
+
route_method_for_formats :delete, path, options, &block
|
22
|
+
end
|
23
|
+
|
24
|
+
def resource(model, options = {}, &block)
|
25
|
+
klass = Class.new
|
26
|
+
|
27
|
+
klass.class_eval <<-"end_eval", __FILE__, __LINE__
|
28
|
+
attr_accessor :app, :wants
|
29
|
+
delegate :request, :response, :params, :session, :to => :app
|
30
|
+
|
31
|
+
def self.controller_name
|
32
|
+
"#{model.to_s.demodulize.downcase.pluralize}"
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.model_name
|
36
|
+
"#{model.to_s.demodulize.downcase}"
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.model
|
40
|
+
model
|
41
|
+
end
|
42
|
+
|
43
|
+
def respond_to
|
44
|
+
yield wants
|
45
|
+
end
|
46
|
+
|
47
|
+
include ResourceMapper::Controller
|
48
|
+
end_eval
|
49
|
+
klass.class_eval &block if block_given?
|
50
|
+
setup_routes(model, klass)
|
51
|
+
end
|
52
|
+
|
53
|
+
private
|
54
|
+
def route_method_for_formats(method, path, options = {}, &block)
|
55
|
+
handler = method_with_format_handler(&block)
|
56
|
+
self.method(method).call "#{path}.:format", options, &handler
|
57
|
+
self.method(method).call "#{path}", options, &handler
|
58
|
+
end
|
59
|
+
|
60
|
+
def method_with_format_handler(&block)
|
61
|
+
lambda do
|
62
|
+
wants = {}
|
63
|
+
format = (params[:format] || DEFAULT_FORMAT).to_sym
|
64
|
+
def wants.method_missing(type, *args, &handler)
|
65
|
+
self[type] = handler
|
66
|
+
end
|
67
|
+
|
68
|
+
block.bind(self).call(wants)
|
69
|
+
halt 404 if wants[format].nil?
|
70
|
+
|
71
|
+
wants[format].call
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def route_handler(resource_klass, method)
|
76
|
+
lambda do |wants|
|
77
|
+
resource = resource_klass.new
|
78
|
+
resource.app = self
|
79
|
+
resource.wants = wants
|
80
|
+
resource.method(method).call
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def setup_routes(model, resource)
|
85
|
+
name = model.to_s.demodulize.downcase
|
86
|
+
|
87
|
+
get_with_formats "/#{name.pluralize}", {}, &route_handler(resource, :index) unless resource.instance_methods.index(:index).nil?
|
88
|
+
get_with_formats "/#{name}/:id", {}, &route_handler(resource, :show) unless resource.instance_methods.index(:show).nil?
|
89
|
+
post_with_formats "/#{name}", {}, &route_handler(resource, :create) unless resource.instance_methods.index(:create).nil?
|
90
|
+
put_with_formats "/#{name}/:id", {}, &route_handler(resource, :update) unless resource.instance_methods.index(:update).nil?
|
91
|
+
delete_with_formats "/#{name}/:id", {}, &route_handler(resource, :destroy) unless resource.instance_methods.index(:destroy).nil?
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
class Base
|
96
|
+
class << self
|
97
|
+
alias_method :orig_helpers, :helpers
|
98
|
+
def helpers(*extensions, &block)
|
99
|
+
ResourceMapper::Helpers.class_eval(&block) if block_given?
|
100
|
+
orig_helpers *extensions, &block
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{resource_mapper}
|
8
|
+
s.version = "0.0.1"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Adam Elliot"]
|
12
|
+
s.date = %q{2010-06-24}
|
13
|
+
s.description = %q{Creates a resource for a model in sinatra}
|
14
|
+
s.email = %q{adam@adamelliot.com}
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"LICENSE",
|
17
|
+
"README.rdoc"
|
18
|
+
]
|
19
|
+
s.files = [
|
20
|
+
".autotest",
|
21
|
+
".document",
|
22
|
+
".gitignore",
|
23
|
+
"LICENSE",
|
24
|
+
"README.rdoc",
|
25
|
+
"Rakefile",
|
26
|
+
"VERSION",
|
27
|
+
"examples/example_helper.rb",
|
28
|
+
"examples/lib/sinatra/resource_example.rb",
|
29
|
+
"examples/models.rb",
|
30
|
+
"lib/resource_mapper.rb",
|
31
|
+
"lib/resource_mapper/accessors.rb",
|
32
|
+
"lib/resource_mapper/action_options.rb",
|
33
|
+
"lib/resource_mapper/actions.rb",
|
34
|
+
"lib/resource_mapper/class_methods.rb",
|
35
|
+
"lib/resource_mapper/controller.rb",
|
36
|
+
"lib/resource_mapper/failable_action_options.rb",
|
37
|
+
"lib/resource_mapper/helpers/current_objects.rb",
|
38
|
+
"lib/resource_mapper/helpers/internal.rb",
|
39
|
+
"lib/resource_mapper/helpers/nested.rb",
|
40
|
+
"lib/resource_mapper/response_collector.rb",
|
41
|
+
"lib/sinatra/resource.rb",
|
42
|
+
"resource_mapper.gemspec"
|
43
|
+
]
|
44
|
+
s.homepage = %q{http://github.com/adamelliot/resource_mapper}
|
45
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
46
|
+
s.require_paths = ["lib"]
|
47
|
+
s.rubygems_version = %q{1.3.7}
|
48
|
+
s.summary = %q{A resource_controller derivate that brings similar functionality to Sinatra, but provides a simple way to create restful APIs}
|
49
|
+
s.test_files = [
|
50
|
+
"examples/example_helper.rb",
|
51
|
+
"examples/lib/sinatra/resource_example.rb",
|
52
|
+
"examples/models.rb"
|
53
|
+
]
|
54
|
+
|
55
|
+
if s.respond_to? :specification_version then
|
56
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
57
|
+
s.specification_version = 3
|
58
|
+
|
59
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
60
|
+
s.add_runtime_dependency(%q<sinatra>, [">= 1.0"])
|
61
|
+
s.add_runtime_dependency(%q<activesupport>, [">= 2.3.5"])
|
62
|
+
s.add_runtime_dependency(%q<mongo_mapper>, [">= 0.7.6"])
|
63
|
+
s.add_development_dependency(%q<micronaut>, [">= 0.3.0"])
|
64
|
+
s.add_development_dependency(%q<rack-test>, [">= 0.5.3"])
|
65
|
+
else
|
66
|
+
s.add_dependency(%q<sinatra>, [">= 1.0"])
|
67
|
+
s.add_dependency(%q<activesupport>, [">= 2.3.5"])
|
68
|
+
s.add_dependency(%q<mongo_mapper>, [">= 0.7.6"])
|
69
|
+
s.add_dependency(%q<micronaut>, [">= 0.3.0"])
|
70
|
+
s.add_dependency(%q<rack-test>, [">= 0.5.3"])
|
71
|
+
end
|
72
|
+
else
|
73
|
+
s.add_dependency(%q<sinatra>, [">= 1.0"])
|
74
|
+
s.add_dependency(%q<activesupport>, [">= 2.3.5"])
|
75
|
+
s.add_dependency(%q<mongo_mapper>, [">= 0.7.6"])
|
76
|
+
s.add_dependency(%q<micronaut>, [">= 0.3.0"])
|
77
|
+
s.add_dependency(%q<rack-test>, [">= 0.5.3"])
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
metadata
ADDED
@@ -0,0 +1,170 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: resource_mapper
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 29
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
- 1
|
10
|
+
version: 0.0.1
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Adam Elliot
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2010-06-24 00:00:00 -06:00
|
19
|
+
default_executable:
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
name: sinatra
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
hash: 15
|
30
|
+
segments:
|
31
|
+
- 1
|
32
|
+
- 0
|
33
|
+
version: "1.0"
|
34
|
+
type: :runtime
|
35
|
+
version_requirements: *id001
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: activesupport
|
38
|
+
prerelease: false
|
39
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
40
|
+
none: false
|
41
|
+
requirements:
|
42
|
+
- - ">="
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
hash: 9
|
45
|
+
segments:
|
46
|
+
- 2
|
47
|
+
- 3
|
48
|
+
- 5
|
49
|
+
version: 2.3.5
|
50
|
+
type: :runtime
|
51
|
+
version_requirements: *id002
|
52
|
+
- !ruby/object:Gem::Dependency
|
53
|
+
name: mongo_mapper
|
54
|
+
prerelease: false
|
55
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
56
|
+
none: false
|
57
|
+
requirements:
|
58
|
+
- - ">="
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
hash: 15
|
61
|
+
segments:
|
62
|
+
- 0
|
63
|
+
- 7
|
64
|
+
- 6
|
65
|
+
version: 0.7.6
|
66
|
+
type: :runtime
|
67
|
+
version_requirements: *id003
|
68
|
+
- !ruby/object:Gem::Dependency
|
69
|
+
name: micronaut
|
70
|
+
prerelease: false
|
71
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
72
|
+
none: false
|
73
|
+
requirements:
|
74
|
+
- - ">="
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
hash: 19
|
77
|
+
segments:
|
78
|
+
- 0
|
79
|
+
- 3
|
80
|
+
- 0
|
81
|
+
version: 0.3.0
|
82
|
+
type: :development
|
83
|
+
version_requirements: *id004
|
84
|
+
- !ruby/object:Gem::Dependency
|
85
|
+
name: rack-test
|
86
|
+
prerelease: false
|
87
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
88
|
+
none: false
|
89
|
+
requirements:
|
90
|
+
- - ">="
|
91
|
+
- !ruby/object:Gem::Version
|
92
|
+
hash: 13
|
93
|
+
segments:
|
94
|
+
- 0
|
95
|
+
- 5
|
96
|
+
- 3
|
97
|
+
version: 0.5.3
|
98
|
+
type: :development
|
99
|
+
version_requirements: *id005
|
100
|
+
description: Creates a resource for a model in sinatra
|
101
|
+
email: adam@adamelliot.com
|
102
|
+
executables: []
|
103
|
+
|
104
|
+
extensions: []
|
105
|
+
|
106
|
+
extra_rdoc_files:
|
107
|
+
- LICENSE
|
108
|
+
- README.rdoc
|
109
|
+
files:
|
110
|
+
- .autotest
|
111
|
+
- .document
|
112
|
+
- .gitignore
|
113
|
+
- LICENSE
|
114
|
+
- README.rdoc
|
115
|
+
- Rakefile
|
116
|
+
- VERSION
|
117
|
+
- examples/example_helper.rb
|
118
|
+
- examples/lib/sinatra/resource_example.rb
|
119
|
+
- examples/models.rb
|
120
|
+
- lib/resource_mapper.rb
|
121
|
+
- lib/resource_mapper/accessors.rb
|
122
|
+
- lib/resource_mapper/action_options.rb
|
123
|
+
- lib/resource_mapper/actions.rb
|
124
|
+
- lib/resource_mapper/class_methods.rb
|
125
|
+
- lib/resource_mapper/controller.rb
|
126
|
+
- lib/resource_mapper/failable_action_options.rb
|
127
|
+
- lib/resource_mapper/helpers/current_objects.rb
|
128
|
+
- lib/resource_mapper/helpers/internal.rb
|
129
|
+
- lib/resource_mapper/helpers/nested.rb
|
130
|
+
- lib/resource_mapper/response_collector.rb
|
131
|
+
- lib/sinatra/resource.rb
|
132
|
+
- resource_mapper.gemspec
|
133
|
+
has_rdoc: true
|
134
|
+
homepage: http://github.com/adamelliot/resource_mapper
|
135
|
+
licenses: []
|
136
|
+
|
137
|
+
post_install_message:
|
138
|
+
rdoc_options:
|
139
|
+
- --charset=UTF-8
|
140
|
+
require_paths:
|
141
|
+
- lib
|
142
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
143
|
+
none: false
|
144
|
+
requirements:
|
145
|
+
- - ">="
|
146
|
+
- !ruby/object:Gem::Version
|
147
|
+
hash: 3
|
148
|
+
segments:
|
149
|
+
- 0
|
150
|
+
version: "0"
|
151
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
152
|
+
none: false
|
153
|
+
requirements:
|
154
|
+
- - ">="
|
155
|
+
- !ruby/object:Gem::Version
|
156
|
+
hash: 3
|
157
|
+
segments:
|
158
|
+
- 0
|
159
|
+
version: "0"
|
160
|
+
requirements: []
|
161
|
+
|
162
|
+
rubyforge_project:
|
163
|
+
rubygems_version: 1.3.7
|
164
|
+
signing_key:
|
165
|
+
specification_version: 3
|
166
|
+
summary: A resource_controller derivate that brings similar functionality to Sinatra, but provides a simple way to create restful APIs
|
167
|
+
test_files:
|
168
|
+
- examples/example_helper.rb
|
169
|
+
- examples/lib/sinatra/resource_example.rb
|
170
|
+
- examples/models.rb
|