rack-scaffold 0.2.0 → 0.2.2
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.
- checksums.yaml +4 -4
- data/Gemfile +3 -2
- data/Gemfile.lock +56 -46
- data/{LICENSE → LICENSE.md} +1 -1
- data/README.md +14 -16
- data/Rakefile +7 -5
- data/lib/rack/scaffold.rb +93 -83
- data/lib/rack/scaffold/adapters.rb +11 -9
- data/lib/rack/scaffold/adapters/active_record.rb +5 -3
- data/lib/rack/scaffold/adapters/core_data.rb +28 -23
- data/lib/rack/scaffold/adapters/sequel.rb +5 -3
- data/lib/rack/scaffold/version.rb +7 -0
- data/rack-scaffold-0.2.1.gem +0 -0
- data/rack-scaffold.gemspec +28 -26
- metadata +66 -65
- data/rack-scaffold-0.2.0.gem +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e439b7397a2e885e9fca4ff87f0757b498c9b1b8
|
4
|
+
data.tar.gz: cdc05f86c46005766d06079d8bddc08db44c21a5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 18db2b0769fbad97121e6fabe094f5eb84845a4243d4376f3ffcd50c1fcd384859da27ffa3cf652917bb08d4a817f3278abf94d7ddb2768472acf308531c047b
|
7
|
+
data.tar.gz: 4d74cc44f1db3bd96b3635048e1a7591c419d1e9a47107ff2baebf3a38c39a5f2ceb3638293892aa592f4de69a1d365cde39f9a018d833be9dd76e220086f1cb
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
rack-scaffold (0.2.
|
5
|
-
activesupport (>=
|
4
|
+
rack-scaffold (0.2.2)
|
5
|
+
activesupport (>= 4.1.11)
|
6
6
|
rack (~> 1.4)
|
7
7
|
rack-contrib (~> 1.1)
|
8
8
|
sinatra (~> 1.4)
|
@@ -12,62 +12,69 @@ PATH
|
|
12
12
|
GEM
|
13
13
|
remote: https://rubygems.org/
|
14
14
|
specs:
|
15
|
-
|
16
|
-
|
17
|
-
|
15
|
+
ParseTree (3.0.9)
|
16
|
+
RubyInline (~> 3.9.0)
|
17
|
+
sexp_processor (~> 3.2.0)
|
18
|
+
RubyInline (3.9.0)
|
19
|
+
ZenTest (~> 4.3)
|
20
|
+
ZenTest (4.11.2)
|
21
|
+
activesupport (5.2.3)
|
22
|
+
concurrent-ruby (~> 1.0, >= 1.0.2)
|
23
|
+
i18n (>= 0.7, < 2)
|
18
24
|
minitest (~> 5.1)
|
19
|
-
thread_safe (~> 0.1)
|
20
25
|
tzinfo (~> 1.1)
|
21
|
-
backports (3.
|
22
|
-
|
26
|
+
backports (3.15.0)
|
27
|
+
concurrent-ruby (1.1.5)
|
28
|
+
core_data (0.1.2)
|
23
29
|
nokogiri (~> 1.4)
|
24
|
-
database_cleaner (
|
25
|
-
|
26
|
-
i18n (
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
rack
|
35
|
-
|
36
|
-
rack-protection (1.5.3)
|
37
|
-
rack
|
38
|
-
rack-test (0.6.2)
|
39
|
-
rack (>= 1.0)
|
40
|
-
rake (10.3.2)
|
41
|
-
rspec (3.0.0)
|
42
|
-
rspec-core (~> 3.0.0)
|
43
|
-
rspec-expectations (~> 3.0.0)
|
44
|
-
rspec-mocks (~> 3.0.0)
|
45
|
-
rspec-core (3.0.4)
|
46
|
-
rspec-support (~> 3.0.0)
|
47
|
-
rspec-expectations (3.0.4)
|
48
|
-
diff-lcs (>= 1.2.0, < 2.0)
|
49
|
-
rspec-support (~> 3.0.0)
|
50
|
-
rspec-mocks (3.0.4)
|
51
|
-
rspec-support (~> 3.0.0)
|
52
|
-
rspec-support (3.0.4)
|
53
|
-
sequel (4.13.0)
|
54
|
-
sinatra (1.4.5)
|
30
|
+
database_cleaner (0.9.1)
|
31
|
+
ffi (1.11.1)
|
32
|
+
i18n (1.6.0)
|
33
|
+
concurrent-ruby (~> 1.0)
|
34
|
+
metaid (1.0)
|
35
|
+
mini_portile2 (2.4.0)
|
36
|
+
minitest (5.11.3)
|
37
|
+
multi_json (1.13.1)
|
38
|
+
nokogiri (1.10.3)
|
39
|
+
mini_portile2 (~> 2.4.0)
|
40
|
+
rack (1.6.11)
|
41
|
+
rack-contrib (1.8.0)
|
55
42
|
rack (~> 1.4)
|
43
|
+
rack-protection (1.5.5)
|
44
|
+
rack
|
45
|
+
rack-test (0.8.3)
|
46
|
+
rack (>= 1.0, < 3)
|
47
|
+
rake (0.9.6)
|
48
|
+
rspec (0.9.4)
|
49
|
+
ruby2ruby (1.3.1)
|
50
|
+
ruby_parser (~> 2.0)
|
51
|
+
sexp_processor (~> 3.0)
|
52
|
+
ruby_parser (2.3.1)
|
53
|
+
sexp_processor (~> 3.0)
|
54
|
+
sequel (0.5.0.2)
|
55
|
+
ParseTree (>= 2.1.1)
|
56
|
+
RubyInline (>= 3.6.6)
|
57
|
+
metaid
|
58
|
+
ruby2ruby
|
59
|
+
sexp_processor (3.2.0)
|
60
|
+
sinatra (1.4.8)
|
61
|
+
rack (~> 1.5)
|
56
62
|
rack-protection (~> 1.4)
|
57
|
-
tilt (
|
58
|
-
sinatra-contrib (1.4.
|
63
|
+
tilt (>= 1.3, < 3)
|
64
|
+
sinatra-contrib (1.4.7)
|
59
65
|
backports (>= 2.0)
|
60
66
|
multi_json
|
61
67
|
rack-protection
|
62
68
|
rack-test
|
63
69
|
sinatra (~> 1.4.0)
|
64
|
-
tilt (
|
70
|
+
tilt (>= 1.3, < 3)
|
65
71
|
sinatra-param (0.1.3)
|
66
72
|
sinatra (~> 1.3)
|
67
|
-
sqlite3 (1.
|
68
|
-
|
69
|
-
|
70
|
-
|
73
|
+
sqlite3 (0.1.1)
|
74
|
+
ffi (>= 0.6.3)
|
75
|
+
thread_safe (0.3.6)
|
76
|
+
tilt (2.0.9)
|
77
|
+
tzinfo (1.2.5)
|
71
78
|
thread_safe (~> 0.1)
|
72
79
|
|
73
80
|
PLATFORMS
|
@@ -82,3 +89,6 @@ DEPENDENCIES
|
|
82
89
|
rspec
|
83
90
|
sequel
|
84
91
|
sqlite3
|
92
|
+
|
93
|
+
BUNDLED WITH
|
94
|
+
2.0.1
|
data/{LICENSE → LICENSE.md}
RENAMED
data/README.md
CHANGED
@@ -1,15 +1,10 @@
|
|
1
1
|
# Rack::Scaffold
|
2
|
+
|
2
3
|
**Automatically generate RESTful CRUD services**
|
3
4
|
|
4
|
-
> This project
|
5
|
+
> This project is no longer maintained.
|
5
6
|
|
6
|
-
|
7
|
-
|
8
|
-
- [Core Data Model](https://github.com/mattt/core_data/) (`.xcdatamodeld`)
|
9
|
-
- [Sequel](https://github.com/jeremyevans/sequel)
|
10
|
-
- [ActiveRecord](https://github.com/rails/rails)
|
11
|
-
|
12
|
-
## Usage
|
7
|
+
## Installation
|
13
8
|
|
14
9
|
### Gemfile
|
15
10
|
|
@@ -25,6 +20,10 @@ gem 'unicorn'
|
|
25
20
|
gem 'pg'
|
26
21
|
```
|
27
22
|
|
23
|
+
## Usage
|
24
|
+
|
25
|
+
An example web API using a Core Data model can be found the `/example` directory.
|
26
|
+
|
28
27
|
### config.ru
|
29
28
|
|
30
29
|
```ruby
|
@@ -47,18 +46,17 @@ By default, `Rack::Scaffold` will enable all of the actions described below. Act
|
|
47
46
|
- `delete` (`DELETE /resources/123`): Deletes the specified resource.
|
48
47
|
- `susbscribe` (`SUBSCRIBE` or `GET /resources` with `Accept: text/event-stream`): Subscribes to create, update, and delete actions performed, streaming corresponding JSON Patch diffs. You can read more about the Rocket technique for streaming REST resources at http://rocket.github.io.
|
49
48
|
|
50
|
-
|
49
|
+
### Supported Data Models
|
51
50
|
|
52
|
-
|
51
|
+
- [Core Data Model](https://github.com/mattt/core_data/) (`.xcdatamodeld`)
|
52
|
+
- [Sequel](https://github.com/jeremyevans/sequel)
|
53
|
+
- [ActiveRecord](https://github.com/rails/rails)
|
53
54
|
|
54
55
|
## Contact
|
55
56
|
|
56
|
-
Mattt
|
57
|
-
|
58
|
-
- http://github.com/mattt
|
59
|
-
- http://twitter.com/mattt
|
60
|
-
- m@mattt.me
|
57
|
+
[Mattt](https://twitter.com/mattt)
|
61
58
|
|
62
59
|
## License
|
63
60
|
|
64
|
-
Rack::Scaffold is available under the MIT license.
|
61
|
+
Rack::Scaffold is available under the MIT license.
|
62
|
+
See the LICENSE file for more info.
|
data/Rakefile
CHANGED
@@ -1,10 +1,12 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'bundler'
|
2
4
|
Bundler.setup
|
3
5
|
|
4
|
-
gemspec = eval(File.read(
|
6
|
+
gemspec = eval(File.read('rack-scaffold.gemspec'))
|
5
7
|
|
6
|
-
task :
|
8
|
+
task build: "#{gemspec.full_name}.gem"
|
7
9
|
|
8
|
-
file "#{gemspec.full_name}.gem" => gemspec.files + [
|
9
|
-
system
|
10
|
+
file "#{gemspec.full_name}.gem" => gemspec.files + ['rack-scaffold.gemspec'] do
|
11
|
+
system 'gem build rack-scaffold.gemspec'
|
10
12
|
end
|
data/lib/rack/scaffold.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'rack'
|
2
4
|
require 'rack/contrib'
|
3
5
|
require 'sinatra/base'
|
@@ -10,13 +12,13 @@ require 'pathname'
|
|
10
12
|
|
11
13
|
module Rack
|
12
14
|
class Scaffold
|
13
|
-
ACTIONS = [
|
15
|
+
ACTIONS = %i[subscribe create read update destroy].freeze
|
14
16
|
|
15
17
|
def initialize(options = {})
|
16
|
-
raise ArgumentError,
|
18
|
+
raise ArgumentError, 'Missing option: :model or :models' unless options[:model] || options[:models]
|
17
19
|
|
18
|
-
if options[:models]
|
19
|
-
@app = Rack::Cascade.new(options.delete(:models).collect{|model| self.class.new(options.dup.merge(
|
20
|
+
if options[:models]&.is_a?(Array)
|
21
|
+
(@app = Rack::Cascade.new(options.delete(:models).collect { |model| self.class.new(options.dup.merge(model: model)) })) && return
|
20
22
|
end
|
21
23
|
|
22
24
|
@app = Class.new(Sinatra::Base) do
|
@@ -29,9 +31,7 @@ module Rack
|
|
29
31
|
end
|
30
32
|
|
31
33
|
disable :raise_errors, :show_exceptions
|
32
|
-
if ENV[
|
33
|
-
set :raise_errors, true
|
34
|
-
end
|
34
|
+
set :raise_errors, true if ENV['RACK_ENV'] == 'test'
|
35
35
|
|
36
36
|
def last_modified_time(resource, resources)
|
37
37
|
update_timestamp_field = resource.update_timestamp_field.to_sym
|
@@ -48,7 +48,7 @@ module Rack
|
|
48
48
|
pathname = Pathname.new(request.path)
|
49
49
|
|
50
50
|
lines = []
|
51
|
-
lines <<
|
51
|
+
lines << 'event: patch'
|
52
52
|
|
53
53
|
op = case status
|
54
54
|
when 201 then :add
|
@@ -57,7 +57,7 @@ module Rack
|
|
57
57
|
:update
|
58
58
|
end
|
59
59
|
|
60
|
-
data = [{op: op, path: record.url, value: record}].to_json
|
60
|
+
data = [{ op: op, path: record.url, value: record }].to_json
|
61
61
|
|
62
62
|
@@connections[pathname.dirname].each do |out|
|
63
63
|
out << "event: patch\ndata: #{data}\n\n"
|
@@ -67,114 +67,124 @@ module Rack
|
|
67
67
|
|
68
68
|
@actions = (options[:only] || ACTIONS) - (options[:except] || [])
|
69
69
|
|
70
|
-
@adapter = Rack::Scaffold.adapters.detect{|adapter| adapter === options[:model]}
|
70
|
+
@adapter = Rack::Scaffold.adapters.detect { |adapter| adapter === options[:model] }
|
71
71
|
raise "No suitable adapters found for #{options[:model]} in #{Rack::Scaffold.adapters}" unless @adapter
|
72
72
|
|
73
73
|
resources = Array(@adapter.resources(options[:model], options))
|
74
74
|
resources.each do |resource|
|
75
|
-
@
|
76
|
-
|
75
|
+
if @actions.include?(:subscribe)
|
76
|
+
@app.instance_eval do
|
77
|
+
@@connections = Hash.new([])
|
77
78
|
|
78
|
-
|
79
|
-
|
79
|
+
route :get, :subscribe, "/#{resource.plural}/?" do
|
80
|
+
pass unless request.accept.include? 'text/event-stream'
|
80
81
|
|
81
|
-
|
82
|
+
content_type 'text/event-stream'
|
82
83
|
|
83
|
-
|
84
|
-
|
84
|
+
stream :keep_open do |out|
|
85
|
+
@@connections[request.path] << out
|
85
86
|
|
86
|
-
|
87
|
-
|
87
|
+
out.callback do
|
88
|
+
@@connections[request.path].delete(out)
|
89
|
+
end
|
88
90
|
end
|
89
91
|
end
|
90
92
|
end
|
91
|
-
end
|
93
|
+
end
|
92
94
|
|
93
|
-
@
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
95
|
+
if @actions.include?(:create)
|
96
|
+
@app.instance_eval do
|
97
|
+
post "/#{resource.plural}/?" do
|
98
|
+
record = resource.klass.new(params)
|
99
|
+
if record.save
|
100
|
+
status 201
|
101
|
+
notify!(record)
|
102
|
+
{ resource.singular.to_s => record }.to_json
|
103
|
+
else
|
104
|
+
status 406
|
105
|
+
{ errors: record.errors }.to_json
|
106
|
+
end
|
103
107
|
end
|
104
108
|
end
|
105
|
-
end
|
106
|
-
|
107
|
-
@app.instance_eval do
|
108
|
-
get "/#{resource.plural}/?" do
|
109
|
-
if params[:page] or params[:per_page]
|
110
|
-
param :page, Integer, default: 1, min: 1
|
111
|
-
param :per_page, Integer, default: 100, in: (1..100)
|
112
|
-
|
113
|
-
resources = resource.paginate(params[:per_page], (params[:page] - 1) * params[:per_page])
|
114
|
-
last_modified(last_modified_time(resource, resources)) if resource.timestamps?
|
115
|
-
|
116
|
-
{
|
117
|
-
"#{resource.plural}" => resources,
|
118
|
-
page: params[:page],
|
119
|
-
total: resource.count
|
120
|
-
}.to_json
|
121
|
-
else
|
122
|
-
param :limit, Integer, default: 100, in: (1..100)
|
123
|
-
param :offset, Integer, default: 0, min: 0
|
124
|
-
|
125
|
-
resources = resource.paginate(params[:limit], params[:offset])
|
126
|
-
last_modified(last_modified_time(resource, resources)) if resource.timestamps?
|
109
|
+
end
|
127
110
|
|
128
|
-
|
129
|
-
|
130
|
-
|
111
|
+
if @actions.include?(:read)
|
112
|
+
@app.instance_eval do
|
113
|
+
get "/#{resource.plural}/?" do
|
114
|
+
if params[:page] || params[:per_page]
|
115
|
+
param :page, Integer, default: 1, min: 1
|
116
|
+
param :per_page, Integer, default: 100, in: (1..100)
|
117
|
+
|
118
|
+
resources = resource.paginate(params[:per_page], (params[:page] - 1) * params[:per_page])
|
119
|
+
last_modified(last_modified_time(resource, resources)) if resource.timestamps?
|
120
|
+
|
121
|
+
{
|
122
|
+
resource.plural.to_s => resources,
|
123
|
+
page: params[:page],
|
124
|
+
total: resource.count
|
125
|
+
}.to_json
|
126
|
+
else
|
127
|
+
param :limit, Integer, default: 100, in: (1..100)
|
128
|
+
param :offset, Integer, default: 0, min: 0
|
129
|
+
|
130
|
+
resources = resource.paginate(params[:limit], params[:offset])
|
131
|
+
last_modified(last_modified_time(resource, resources)) if resource.timestamps?
|
132
|
+
|
133
|
+
{
|
134
|
+
resource.plural.to_s => resources
|
135
|
+
}.to_json
|
136
|
+
end
|
131
137
|
end
|
132
|
-
end
|
133
138
|
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
+
get "/#{resource.plural}/:id/?" do
|
140
|
+
(record = resource[params[:id]]) || halt(404)
|
141
|
+
last_modified(last_modified_time(resource, record)) if resource.timestamps?
|
142
|
+
{ resource.singular.to_s => record }.to_json
|
143
|
+
end
|
139
144
|
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
145
|
+
resource.one_to_many_associations.each do |association|
|
146
|
+
get "/#{resource.plural}/:id/#{association}/?" do
|
147
|
+
(record = resource[params[:id]]) || halt(404)
|
148
|
+
associations = record.send(association)
|
144
149
|
|
145
|
-
|
146
|
-
|
147
|
-
|
150
|
+
{
|
151
|
+
association.to_s => associations
|
152
|
+
}.to_json
|
153
|
+
end
|
148
154
|
end
|
149
155
|
end
|
150
|
-
end
|
156
|
+
end
|
151
157
|
|
152
|
-
@
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
158
|
+
if @actions.include?(:update)
|
159
|
+
@app.instance_eval do
|
160
|
+
route :put, :patch, "/#{resource.plural}/:id/?" do
|
161
|
+
(record = resource[params[:id]]) || halt(404)
|
162
|
+
if record.update!(params)
|
163
|
+
status 200
|
164
|
+
notify!(record)
|
165
|
+
{ resource.singular.to_s => record }.to_json
|
166
|
+
else
|
167
|
+
status 406
|
168
|
+
{ errors: record.errors }.to_json
|
169
|
+
end
|
162
170
|
end
|
163
171
|
end
|
164
|
-
end
|
172
|
+
end
|
173
|
+
|
174
|
+
next unless @actions.include?(:destroy)
|
165
175
|
|
166
176
|
@app.instance_eval do
|
167
177
|
delete "/#{resource.plural}/:id/?" do
|
168
|
-
record = resource[params[:id]]
|
178
|
+
(record = resource[params[:id]]) || halt(404)
|
169
179
|
if record.destroy
|
170
180
|
status 204
|
171
181
|
notify!(record)
|
172
182
|
else
|
173
183
|
status 406
|
174
|
-
{errors: record.errors}.to_json
|
184
|
+
{ errors: record.errors }.to_json
|
175
185
|
end
|
176
186
|
end
|
177
|
-
end
|
187
|
+
end
|
178
188
|
end
|
179
189
|
end
|
180
190
|
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Rack
|
2
4
|
class Scaffold
|
3
5
|
def self.adapters
|
@@ -16,11 +18,11 @@ module Rack
|
|
16
18
|
super
|
17
19
|
end
|
18
20
|
|
19
|
-
def ===(
|
21
|
+
def ===(_model)
|
20
22
|
raise NotImplementedError
|
21
23
|
end
|
22
24
|
|
23
|
-
def resources(
|
25
|
+
def resources(_model, _options = {})
|
24
26
|
raise NotImplementedError
|
25
27
|
end
|
26
28
|
end
|
@@ -45,11 +47,11 @@ module Rack
|
|
45
47
|
raise NotImplementedError
|
46
48
|
end
|
47
49
|
|
48
|
-
def paginate(
|
50
|
+
def paginate(_offset, _limit)
|
49
51
|
raise NotImplementedError
|
50
52
|
end
|
51
53
|
|
52
|
-
def [](
|
54
|
+
def [](_id)
|
53
55
|
raise NotImplementedError
|
54
56
|
end
|
55
57
|
|
@@ -57,15 +59,15 @@ module Rack
|
|
57
59
|
raise NotImplementedError
|
58
60
|
end
|
59
61
|
|
60
|
-
def find(
|
62
|
+
def find(_options = {})
|
61
63
|
raise NotImplementedError
|
62
64
|
end
|
63
65
|
|
64
|
-
def create!(
|
66
|
+
def create!(_attributes = {})
|
65
67
|
raise NotImplementedError
|
66
68
|
end
|
67
69
|
|
68
|
-
def update!(
|
70
|
+
def update!(_attributes = {})
|
69
71
|
raise NotImplementedError
|
70
72
|
end
|
71
73
|
|
@@ -81,7 +83,7 @@ module Rack
|
|
81
83
|
raise NotImplementedError
|
82
84
|
end
|
83
85
|
|
84
|
-
def method_missing(method, *
|
86
|
+
def method_missing(method, *_args)
|
85
87
|
@klass.send(method)
|
86
88
|
end
|
87
89
|
end
|
@@ -91,4 +93,4 @@ end
|
|
91
93
|
|
92
94
|
require 'rack/scaffold/adapters/active_record' if defined?(ActiveRecord::Base)
|
93
95
|
require 'rack/scaffold/adapters/sequel' if defined?(Sequel)
|
94
|
-
require 'rack/scaffold/adapters/core_data' if defined?(Sequel)
|
96
|
+
require 'rack/scaffold/adapters/core_data' if defined?(Sequel) && defined?(CoreData)
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'active_record'
|
2
4
|
require 'forwardable'
|
3
5
|
|
@@ -12,7 +14,7 @@ module Rack::Scaffold::Adapters
|
|
12
14
|
::ActiveRecord::Base === model
|
13
15
|
end
|
14
16
|
|
15
|
-
def resources(model,
|
17
|
+
def resources(model, _options = {})
|
16
18
|
model
|
17
19
|
end
|
18
20
|
|
@@ -34,7 +36,7 @@ module Rack::Scaffold::Adapters
|
|
34
36
|
end
|
35
37
|
|
36
38
|
def [](id)
|
37
|
-
|
39
|
+
find(id)
|
38
40
|
end
|
39
41
|
|
40
42
|
def one_to_many_associations
|
@@ -42,7 +44,7 @@ module Rack::Scaffold::Adapters
|
|
42
44
|
end
|
43
45
|
|
44
46
|
def update_timestamp_field
|
45
|
-
|
47
|
+
attribute_names.include?('updated_at') ? 'updated_at' : 'updated_on'
|
46
48
|
end
|
47
49
|
end
|
48
50
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'core_data'
|
2
4
|
require 'sequel'
|
3
5
|
require 'active_support/inflector'
|
@@ -7,16 +9,21 @@ module Rack::Scaffold::Adapters
|
|
7
9
|
class << self
|
8
10
|
def ===(model)
|
9
11
|
return true if ::CoreData::DataModel === model
|
10
|
-
|
12
|
+
|
13
|
+
begin
|
14
|
+
!!::CoreData::DataModel.new(model)
|
15
|
+
rescue StandardError
|
16
|
+
false
|
17
|
+
end
|
11
18
|
end
|
12
19
|
|
13
20
|
def resources(xcdatamodel, options = {})
|
14
21
|
model = ::CoreData::DataModel.new(xcdatamodel)
|
15
22
|
model.entities.each do |entity|
|
16
|
-
|
23
|
+
const_set(entity.name.capitalize, Class.new(::Sequel::Model)) unless const_defined?(entity.name.capitalize)
|
17
24
|
end
|
18
25
|
|
19
|
-
model.entities.collect{|entity| new(entity, options)}
|
26
|
+
model.entities.collect { |entity| new(entity, options) }
|
20
27
|
end
|
21
28
|
end
|
22
29
|
|
@@ -26,8 +33,8 @@ module Rack::Scaffold::Adapters
|
|
26
33
|
klass.dataset = entity.name.downcase.pluralize.to_sym
|
27
34
|
|
28
35
|
klass.class_eval do
|
29
|
-
|
30
|
-
|
36
|
+
alias_method :update!, :update
|
37
|
+
alias_method :destroy!, :destroy
|
31
38
|
|
32
39
|
self.strict_param_setting = false
|
33
40
|
self.raise_on_save_failure = false
|
@@ -44,16 +51,14 @@ module Rack::Scaffold::Adapters
|
|
44
51
|
end
|
45
52
|
end
|
46
53
|
|
47
|
-
if options[:nested_attributes]
|
48
|
-
plugin :nested_attributes
|
49
|
-
end
|
54
|
+
plugin :nested_attributes if options[:nested_attributes]
|
50
55
|
|
51
56
|
def url
|
52
57
|
"/#{self.class.table_name}/#{self[primary_key]}"
|
53
58
|
end
|
54
59
|
|
55
60
|
entity.relationships.each do |relationship|
|
56
|
-
entity_options = {class: adapter.const_get(relationship.destination.capitalize)}
|
61
|
+
entity_options = { class: adapter.const_get(relationship.destination.capitalize) }
|
57
62
|
|
58
63
|
if relationship.to_many?
|
59
64
|
one_to_many relationship.name.to_sym, entity_options
|
@@ -78,15 +83,15 @@ module Rack::Scaffold::Adapters
|
|
78
83
|
}
|
79
84
|
|
80
85
|
type = case attribute.type
|
81
|
-
when
|
82
|
-
when
|
83
|
-
when
|
84
|
-
when
|
85
|
-
when
|
86
|
-
when
|
87
|
-
when
|
88
|
-
when
|
89
|
-
when
|
86
|
+
when 'Integer 16' then :int2
|
87
|
+
when 'Integer 32' then :int4
|
88
|
+
when 'Integer 64' then :int8
|
89
|
+
when 'Float' then :float4
|
90
|
+
when 'Double' then :float8
|
91
|
+
when 'Decimal' then :float8
|
92
|
+
when 'Date' then :timestamp
|
93
|
+
when 'Boolean' then :boolean
|
94
|
+
when 'Binary' then :bytea
|
90
95
|
else :varchar
|
91
96
|
end
|
92
97
|
|
@@ -99,14 +104,14 @@ module Rack::Scaffold::Adapters
|
|
99
104
|
null: relationship.optional?
|
100
105
|
}
|
101
106
|
|
102
|
-
|
107
|
+
unless relationship.to_many?
|
103
108
|
column "#{relationship.name}_id".to_sym, :integer, options
|
104
109
|
end
|
105
110
|
end
|
106
111
|
end
|
107
112
|
|
108
113
|
if table_exists?
|
109
|
-
missing_columns = schema.columns.reject{|c| columns.include?(c[:name])}
|
114
|
+
missing_columns = schema.columns.reject { |c| columns.include?(c[:name]) }
|
110
115
|
db.alter_table table_name do
|
111
116
|
missing_columns.each do |options|
|
112
117
|
add_column options.delete(:name), options.delete(:type), options
|
@@ -120,11 +125,11 @@ module Rack::Scaffold::Adapters
|
|
120
125
|
klass.send :define_method, :validate do
|
121
126
|
entity.attributes.each do |attribute|
|
122
127
|
case attribute.type
|
123
|
-
when
|
128
|
+
when 'Integer 16', 'Integer 32', 'Integer 64'
|
124
129
|
validates_integer attribute.name
|
125
|
-
when
|
130
|
+
when 'Float', 'Double', 'Decimal'
|
126
131
|
validates_numeric attribute.name
|
127
|
-
when
|
132
|
+
when 'String'
|
128
133
|
validates_min_length attribute.minimum_value, attribute.name if attribute.minimum_value
|
129
134
|
validates_max_length attribute.maximum_value, attribute.name if attribute.maximum_value
|
130
135
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'sequel'
|
2
4
|
require 'forwardable'
|
3
5
|
|
@@ -15,7 +17,7 @@ module Rack::Scaffold::Adapters
|
|
15
17
|
::Sequel::Model === model
|
16
18
|
end
|
17
19
|
|
18
|
-
def resources(model,
|
20
|
+
def resources(model, _options = {})
|
19
21
|
model
|
20
22
|
end
|
21
23
|
end
|
@@ -33,11 +35,11 @@ module Rack::Scaffold::Adapters
|
|
33
35
|
end
|
34
36
|
|
35
37
|
def one_to_many_associations
|
36
|
-
@klass.all_association_reflections.select{|association| association[:type] == :one_to_many}.collect{|association| association[:name]}
|
38
|
+
@klass.all_association_reflections.select { |association| association[:type] == :one_to_many }.collect { |association| association[:name] }
|
37
39
|
end
|
38
40
|
|
39
41
|
def timestamps?
|
40
|
-
defined?(::Sequel::Plugins::Timestamps)
|
42
|
+
defined?(::Sequel::Plugins::Timestamps) && @klass.plugins.include?(::Sequel::Plugins::Timestamps)
|
41
43
|
end
|
42
44
|
end
|
43
45
|
end
|
Binary file
|
data/rack-scaffold.gemspec
CHANGED
@@ -1,34 +1,36 @@
|
|
1
|
-
#
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
$LOAD_PATH.push File.expand_path('lib', __dir__)
|
4
|
+
require 'rack/scaffold/version'
|
3
5
|
|
4
6
|
Gem::Specification.new do |s|
|
5
|
-
s.name =
|
6
|
-
s.authors = [
|
7
|
-
s.email =
|
8
|
-
s.homepage =
|
9
|
-
s.license =
|
10
|
-
s.version =
|
7
|
+
s.name = 'rack-scaffold'
|
8
|
+
s.authors = ['Mattt']
|
9
|
+
s.email = 'mattt@me.com'
|
10
|
+
s.homepage = 'https://mat.tt'
|
11
|
+
s.license = 'MIT'
|
12
|
+
s.version = Rack::Scaffold::VERSION
|
11
13
|
s.platform = Gem::Platform::RUBY
|
12
|
-
s.summary =
|
13
|
-
s.description =
|
14
|
+
s.summary = 'Rack::Scaffold'
|
15
|
+
s.description = 'Automatically generate RESTful CRUD services'
|
14
16
|
|
15
|
-
s.add_dependency
|
16
|
-
s.add_dependency
|
17
|
-
s.add_dependency
|
18
|
-
s.add_dependency
|
19
|
-
s.add_dependency
|
20
|
-
s.add_dependency
|
17
|
+
s.add_dependency 'activesupport', '>= 4.1.11'
|
18
|
+
s.add_dependency 'rack', '~> 1.4'
|
19
|
+
s.add_dependency 'rack-contrib', '~> 1.1'
|
20
|
+
s.add_dependency 'sinatra', '~> 1.4'
|
21
|
+
s.add_dependency 'sinatra-contrib', '~> 1.4'
|
22
|
+
s.add_dependency 'sinatra-param', '~> 0.1'
|
21
23
|
|
22
|
-
s.add_development_dependency
|
23
|
-
s.add_development_dependency
|
24
|
-
s.add_development_dependency
|
25
|
-
s.add_development_dependency
|
26
|
-
s.add_development_dependency
|
27
|
-
s.add_development_dependency
|
28
|
-
s.add_development_dependency
|
24
|
+
s.add_development_dependency 'core_data'
|
25
|
+
s.add_development_dependency 'database_cleaner'
|
26
|
+
s.add_development_dependency 'rack-test'
|
27
|
+
s.add_development_dependency 'rake'
|
28
|
+
s.add_development_dependency 'rspec'
|
29
|
+
s.add_development_dependency 'sequel'
|
30
|
+
s.add_development_dependency 'sqlite3'
|
29
31
|
|
30
|
-
s.files = Dir[
|
32
|
+
s.files = Dir['./**/*'].reject { |file| file =~ %r{\./(bin|example|log|pkg|script|spec|test|vendor)} }
|
31
33
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
32
|
-
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
33
|
-
s.require_paths = [
|
34
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
|
35
|
+
s.require_paths = ['lib']
|
34
36
|
end
|
metadata
CHANGED
@@ -1,220 +1,221 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rack-scaffold
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
|
-
- Mattt
|
7
|
+
- Mattt
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2019-07-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: activesupport
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 4.1.11
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 4.1.11
|
13
27
|
- !ruby/object:Gem::Dependency
|
14
28
|
name: rack
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|
16
30
|
requirements:
|
17
|
-
- - ~>
|
31
|
+
- - "~>"
|
18
32
|
- !ruby/object:Gem::Version
|
19
33
|
version: '1.4'
|
20
34
|
type: :runtime
|
21
35
|
prerelease: false
|
22
36
|
version_requirements: !ruby/object:Gem::Requirement
|
23
37
|
requirements:
|
24
|
-
- - ~>
|
38
|
+
- - "~>"
|
25
39
|
- !ruby/object:Gem::Version
|
26
40
|
version: '1.4'
|
27
41
|
- !ruby/object:Gem::Dependency
|
28
42
|
name: rack-contrib
|
29
43
|
requirement: !ruby/object:Gem::Requirement
|
30
44
|
requirements:
|
31
|
-
- - ~>
|
45
|
+
- - "~>"
|
32
46
|
- !ruby/object:Gem::Version
|
33
47
|
version: '1.1'
|
34
48
|
type: :runtime
|
35
49
|
prerelease: false
|
36
50
|
version_requirements: !ruby/object:Gem::Requirement
|
37
51
|
requirements:
|
38
|
-
- - ~>
|
52
|
+
- - "~>"
|
39
53
|
- !ruby/object:Gem::Version
|
40
54
|
version: '1.1'
|
41
55
|
- !ruby/object:Gem::Dependency
|
42
56
|
name: sinatra
|
43
57
|
requirement: !ruby/object:Gem::Requirement
|
44
58
|
requirements:
|
45
|
-
- - ~>
|
59
|
+
- - "~>"
|
46
60
|
- !ruby/object:Gem::Version
|
47
61
|
version: '1.4'
|
48
62
|
type: :runtime
|
49
63
|
prerelease: false
|
50
64
|
version_requirements: !ruby/object:Gem::Requirement
|
51
65
|
requirements:
|
52
|
-
- - ~>
|
66
|
+
- - "~>"
|
53
67
|
- !ruby/object:Gem::Version
|
54
68
|
version: '1.4'
|
55
69
|
- !ruby/object:Gem::Dependency
|
56
70
|
name: sinatra-contrib
|
57
71
|
requirement: !ruby/object:Gem::Requirement
|
58
72
|
requirements:
|
59
|
-
- - ~>
|
73
|
+
- - "~>"
|
60
74
|
- !ruby/object:Gem::Version
|
61
75
|
version: '1.4'
|
62
76
|
type: :runtime
|
63
77
|
prerelease: false
|
64
78
|
version_requirements: !ruby/object:Gem::Requirement
|
65
79
|
requirements:
|
66
|
-
- - ~>
|
80
|
+
- - "~>"
|
67
81
|
- !ruby/object:Gem::Version
|
68
82
|
version: '1.4'
|
69
83
|
- !ruby/object:Gem::Dependency
|
70
84
|
name: sinatra-param
|
71
85
|
requirement: !ruby/object:Gem::Requirement
|
72
86
|
requirements:
|
73
|
-
- - ~>
|
87
|
+
- - "~>"
|
74
88
|
- !ruby/object:Gem::Version
|
75
89
|
version: '0.1'
|
76
90
|
type: :runtime
|
77
91
|
prerelease: false
|
78
92
|
version_requirements: !ruby/object:Gem::Requirement
|
79
93
|
requirements:
|
80
|
-
- - ~>
|
94
|
+
- - "~>"
|
81
95
|
- !ruby/object:Gem::Version
|
82
96
|
version: '0.1'
|
83
97
|
- !ruby/object:Gem::Dependency
|
84
|
-
name:
|
85
|
-
requirement: !ruby/object:Gem::Requirement
|
86
|
-
requirements:
|
87
|
-
- - '>='
|
88
|
-
- !ruby/object:Gem::Version
|
89
|
-
version: '3.0'
|
90
|
-
type: :runtime
|
91
|
-
prerelease: false
|
92
|
-
version_requirements: !ruby/object:Gem::Requirement
|
93
|
-
requirements:
|
94
|
-
- - '>='
|
95
|
-
- !ruby/object:Gem::Version
|
96
|
-
version: '3.0'
|
97
|
-
- !ruby/object:Gem::Dependency
|
98
|
-
name: rake
|
98
|
+
name: core_data
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
100
100
|
requirements:
|
101
|
-
- -
|
101
|
+
- - ">="
|
102
102
|
- !ruby/object:Gem::Version
|
103
103
|
version: '0'
|
104
104
|
type: :development
|
105
105
|
prerelease: false
|
106
106
|
version_requirements: !ruby/object:Gem::Requirement
|
107
107
|
requirements:
|
108
|
-
- -
|
108
|
+
- - ">="
|
109
109
|
- !ruby/object:Gem::Version
|
110
110
|
version: '0'
|
111
111
|
- !ruby/object:Gem::Dependency
|
112
|
-
name:
|
112
|
+
name: database_cleaner
|
113
113
|
requirement: !ruby/object:Gem::Requirement
|
114
114
|
requirements:
|
115
|
-
- -
|
115
|
+
- - ">="
|
116
116
|
- !ruby/object:Gem::Version
|
117
117
|
version: '0'
|
118
118
|
type: :development
|
119
119
|
prerelease: false
|
120
120
|
version_requirements: !ruby/object:Gem::Requirement
|
121
121
|
requirements:
|
122
|
-
- -
|
122
|
+
- - ">="
|
123
123
|
- !ruby/object:Gem::Version
|
124
124
|
version: '0'
|
125
125
|
- !ruby/object:Gem::Dependency
|
126
|
-
name:
|
126
|
+
name: rack-test
|
127
127
|
requirement: !ruby/object:Gem::Requirement
|
128
128
|
requirements:
|
129
|
-
- -
|
129
|
+
- - ">="
|
130
130
|
- !ruby/object:Gem::Version
|
131
131
|
version: '0'
|
132
132
|
type: :development
|
133
133
|
prerelease: false
|
134
134
|
version_requirements: !ruby/object:Gem::Requirement
|
135
135
|
requirements:
|
136
|
-
- -
|
136
|
+
- - ">="
|
137
137
|
- !ruby/object:Gem::Version
|
138
138
|
version: '0'
|
139
139
|
- !ruby/object:Gem::Dependency
|
140
|
-
name:
|
140
|
+
name: rake
|
141
141
|
requirement: !ruby/object:Gem::Requirement
|
142
142
|
requirements:
|
143
|
-
- -
|
143
|
+
- - ">="
|
144
144
|
- !ruby/object:Gem::Version
|
145
145
|
version: '0'
|
146
146
|
type: :development
|
147
147
|
prerelease: false
|
148
148
|
version_requirements: !ruby/object:Gem::Requirement
|
149
149
|
requirements:
|
150
|
-
- -
|
150
|
+
- - ">="
|
151
151
|
- !ruby/object:Gem::Version
|
152
152
|
version: '0'
|
153
153
|
- !ruby/object:Gem::Dependency
|
154
|
-
name:
|
154
|
+
name: rspec
|
155
155
|
requirement: !ruby/object:Gem::Requirement
|
156
156
|
requirements:
|
157
|
-
- -
|
157
|
+
- - ">="
|
158
158
|
- !ruby/object:Gem::Version
|
159
159
|
version: '0'
|
160
160
|
type: :development
|
161
161
|
prerelease: false
|
162
162
|
version_requirements: !ruby/object:Gem::Requirement
|
163
163
|
requirements:
|
164
|
-
- -
|
164
|
+
- - ">="
|
165
165
|
- !ruby/object:Gem::Version
|
166
166
|
version: '0'
|
167
167
|
- !ruby/object:Gem::Dependency
|
168
|
-
name:
|
168
|
+
name: sequel
|
169
169
|
requirement: !ruby/object:Gem::Requirement
|
170
170
|
requirements:
|
171
|
-
- -
|
171
|
+
- - ">="
|
172
172
|
- !ruby/object:Gem::Version
|
173
173
|
version: '0'
|
174
174
|
type: :development
|
175
175
|
prerelease: false
|
176
176
|
version_requirements: !ruby/object:Gem::Requirement
|
177
177
|
requirements:
|
178
|
-
- -
|
178
|
+
- - ">="
|
179
179
|
- !ruby/object:Gem::Version
|
180
180
|
version: '0'
|
181
181
|
- !ruby/object:Gem::Dependency
|
182
|
-
name:
|
182
|
+
name: sqlite3
|
183
183
|
requirement: !ruby/object:Gem::Requirement
|
184
184
|
requirements:
|
185
|
-
- -
|
185
|
+
- - ">="
|
186
186
|
- !ruby/object:Gem::Version
|
187
187
|
version: '0'
|
188
188
|
type: :development
|
189
189
|
prerelease: false
|
190
190
|
version_requirements: !ruby/object:Gem::Requirement
|
191
191
|
requirements:
|
192
|
-
- -
|
192
|
+
- - ">="
|
193
193
|
- !ruby/object:Gem::Version
|
194
194
|
version: '0'
|
195
195
|
description: Automatically generate RESTful CRUD services
|
196
|
-
email:
|
196
|
+
email: mattt@me.com
|
197
197
|
executables: []
|
198
198
|
extensions: []
|
199
199
|
extra_rdoc_files: []
|
200
200
|
files:
|
201
|
-
- ./Gemfile
|
202
|
-
- ./Gemfile.lock
|
203
|
-
- ./
|
204
|
-
- ./
|
205
|
-
- ./
|
206
|
-
- ./lib/rack/scaffold
|
207
|
-
- ./lib/rack/scaffold.rb
|
208
|
-
- ./
|
209
|
-
- ./rack
|
210
|
-
- ./rack
|
211
|
-
- ./
|
212
|
-
- ./
|
201
|
+
- "./Gemfile"
|
202
|
+
- "./Gemfile.lock"
|
203
|
+
- "./LICENSE.md"
|
204
|
+
- "./README.md"
|
205
|
+
- "./Rakefile"
|
206
|
+
- "./lib/rack/scaffold.rb"
|
207
|
+
- "./lib/rack/scaffold/adapters.rb"
|
208
|
+
- "./lib/rack/scaffold/adapters/active_record.rb"
|
209
|
+
- "./lib/rack/scaffold/adapters/core_data.rb"
|
210
|
+
- "./lib/rack/scaffold/adapters/sequel.rb"
|
211
|
+
- "./lib/rack/scaffold/version.rb"
|
212
|
+
- "./rack-scaffold-0.2.1.gem"
|
213
|
+
- "./rack-scaffold.gemspec"
|
213
214
|
- spec/scaffold/adapters/core_data_spec.rb
|
214
215
|
- spec/scaffold/adapters_spec.rb
|
215
216
|
- spec/scaffold_spec.rb
|
216
217
|
- spec/spec_helper.rb
|
217
|
-
homepage:
|
218
|
+
homepage: https://mat.tt
|
218
219
|
licenses:
|
219
220
|
- MIT
|
220
221
|
metadata: {}
|
@@ -224,17 +225,17 @@ require_paths:
|
|
224
225
|
- lib
|
225
226
|
required_ruby_version: !ruby/object:Gem::Requirement
|
226
227
|
requirements:
|
227
|
-
- -
|
228
|
+
- - ">="
|
228
229
|
- !ruby/object:Gem::Version
|
229
230
|
version: '0'
|
230
231
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
231
232
|
requirements:
|
232
|
-
- -
|
233
|
+
- - ">="
|
233
234
|
- !ruby/object:Gem::Version
|
234
235
|
version: '0'
|
235
236
|
requirements: []
|
236
237
|
rubyforge_project:
|
237
|
-
rubygems_version: 2.
|
238
|
+
rubygems_version: 2.6.14
|
238
239
|
signing_key:
|
239
240
|
specification_version: 4
|
240
241
|
summary: Rack::Scaffold
|
data/rack-scaffold-0.2.0.gem
DELETED
Binary file
|