rack-autocrud 0.1.7 → 0.1.8
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/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
|