rack-autocrud 0.1.7 → 0.1.8
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +45 -2
- data/lib/rack/autocrud.rb +18 -5
- metadata +2 -2
data/README.md
CHANGED
@@ -63,9 +63,9 @@ _config.ru_. This middleware will dynamically create a _Sinatra::Base_ subclass
|
|
63
63
|
| Route | Action | HTTP Response Code |
|
64
64
|
| ----------- | -------------------------------| ------------------ |
|
65
65
|
| get / | List all _Person_ entries | 403 |
|
66
|
-
| post / | Create a new _Person_ | 201 /
|
66
|
+
| post / | Create a new _Person_ | 201 / 402 |
|
67
67
|
| get /:id | Retrieve a _Person_ | 200 |
|
68
|
-
| put /:id | Update a _Person_ | 201 /
|
68
|
+
| put /:id | Update a _Person_ | 201 / 402 |
|
69
69
|
| delete /:id | Destroy a _Person_ | 204 |
|
70
70
|
|
71
71
|
The middleware will route based on the URI. Thus, _/person_ would correspond to *Endpoints::Person*'s _get /_ route.
|
@@ -118,6 +118,49 @@ Parameters:
|
|
118
118
|
If any of these hooks returns anything other than _nil_, it is assumed to be a response object, which
|
119
119
|
is returned immediately, and no further processing is performed.
|
120
120
|
|
121
|
+
Selective Exposure
|
122
|
+
==================
|
123
|
+
|
124
|
+
All models in the namespace passed to _Rack::AutoCRUD_ are exposed by default.
|
125
|
+
|
126
|
+
You can selectively hide models by defining a constant called _EXPOSE_ in your model definition.
|
127
|
+
A value of 0 will cause _Rack::AutoCRUD_ to *not* create and endpoint for that particular model.
|
128
|
+
|
129
|
+
Example:
|
130
|
+
```ruby
|
131
|
+
module Models
|
132
|
+
class Person
|
133
|
+
include DataMapper::Resource
|
134
|
+
|
135
|
+
property :id, Serial
|
136
|
+
property :name, String
|
137
|
+
|
138
|
+
# Don't expose this model via AutoCRUD
|
139
|
+
EXPOSE = 0
|
140
|
+
end
|
141
|
+
end
|
142
|
+
```
|
143
|
+
|
144
|
+
If you want to *not* expose all models by default, simply define the constant as part of the _Models_ module:
|
145
|
+
|
146
|
+
```ruby
|
147
|
+
module Models
|
148
|
+
# Hide all models by default
|
149
|
+
EXPOSE = 0
|
150
|
+
end
|
151
|
+
|
152
|
+
module Models
|
153
|
+
class ExposeMe
|
154
|
+
include DataMapper::Resource
|
155
|
+
|
156
|
+
property :id, Serial
|
157
|
+
|
158
|
+
# Expose this model
|
159
|
+
EXPOSE = 1
|
160
|
+
end
|
161
|
+
end
|
162
|
+
```
|
163
|
+
|
121
164
|
Helper Functions
|
122
165
|
================
|
123
166
|
|
data/lib/rack/autocrud.rb
CHANGED
@@ -22,6 +22,7 @@ module Rack
|
|
22
22
|
@endpoint_namespace = options[:endpoint_namespace]
|
23
23
|
@includes = options[:includes]
|
24
24
|
@endpoint_mod = nil
|
25
|
+
@model_mod = nil
|
25
26
|
end
|
26
27
|
|
27
28
|
def call(env)
|
@@ -43,15 +44,27 @@ module Rack
|
|
43
44
|
endpoint_klass = klass if String(klass.name).downcase == String(@endpoint_namespace + '::' + endpoint).downcase
|
44
45
|
}
|
45
46
|
|
47
|
+
# Lazily locate the model namespace module (if we haven't already)
|
48
|
+
if @model_mod.nil?
|
49
|
+
ObjectSpace.each_object(Module) { |klass|
|
50
|
+
@model_mod = klass if String(klass.name).downcase == @model_namespace.downcase
|
51
|
+
}
|
52
|
+
end
|
53
|
+
|
46
54
|
# Lazily locate the endpoint namespace module (if we haven't already)
|
47
55
|
if endpoint_klass.nil? && @endpoint_mod.nil?
|
48
56
|
ObjectSpace.each_object(Module) { |klass|
|
49
|
-
@endpoint_mod = klass if String(klass.name).downcase == @endpoint_namespace.downcase
|
57
|
+
@endpoint_mod = klass if String(klass.name).downcase == @endpoint_namespace.downcase
|
50
58
|
}
|
51
59
|
end
|
52
60
|
|
61
|
+
# Make sure we copy the :EXPOSE constant if it's defined upstream
|
62
|
+
if !model_klass.const_defined?(:EXPOSE) && @model_mod.const_defined?(:EXPOSE)
|
63
|
+
model_klass.const_set(:EXPOSE,@model_mod.const_get(:EXPOSE))
|
64
|
+
end
|
65
|
+
|
53
66
|
# Now, if we've got something, do our magic.
|
54
|
-
if !model_klass.nil?
|
67
|
+
if !model_klass.nil? && (!model_klass.const_defined?(:EXPOSE) || model_klass.const_get(:EXPOSE))
|
55
68
|
# If we don't have an endpoint class, make one
|
56
69
|
if endpoint_klass.nil?
|
57
70
|
endpoint_klass = Class.new(Sinatra::Base)
|
@@ -87,8 +100,8 @@ module Rack
|
|
87
100
|
# Attempt to create the model object
|
88
101
|
obj = nil
|
89
102
|
begin
|
90
|
-
obj = model.
|
91
|
-
halt [
|
103
|
+
obj = model.new(JSON.parse(request.body.read))
|
104
|
+
halt [ 402, '{ "error": "Failed to save ' + endpoint + '" }' ] unless obj && obj.saved?
|
92
105
|
rescue JSON::ParserError
|
93
106
|
halt [ 400, { 'error' => 'Invalid JSON in request body.', 'details' => $! }.to_json ]
|
94
107
|
end
|
@@ -133,7 +146,7 @@ module Rack
|
|
133
146
|
# Attempt to update the model
|
134
147
|
begin
|
135
148
|
saved = model.update(JSON.parse(request.body.read).merge(:id => params[:id]))
|
136
|
-
halt [
|
149
|
+
halt [ 402, '{ "error": "Access Denied" }' ] unless saved
|
137
150
|
rescue JSON::ParserError
|
138
151
|
halt [ 400, { 'error' => 'Invalid JSON in request body.', 'details' => $! }.to_json ]
|
139
152
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rack-autocrud
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.8
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -93,7 +93,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
93
93
|
version: '0'
|
94
94
|
requirements: []
|
95
95
|
rubyforge_project:
|
96
|
-
rubygems_version: 1.8.
|
96
|
+
rubygems_version: 1.8.24
|
97
97
|
signing_key:
|
98
98
|
specification_version: 3
|
99
99
|
summary: Rack middleware that automagically handles basic CRUD operations
|