standardapi 6.0.0.27 → 6.0.0.29
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/README.md +15 -6
- data/lib/standard_api.rb +1 -0
- data/lib/standard_api/active_record/connection_adapters/postgresql/schema_statements.rb +21 -0
- data/lib/standard_api/controller.rb +35 -20
- data/lib/standard_api/helpers.rb +20 -10
- data/lib/standard_api/test_case/calculate_tests.rb +2 -2
- data/lib/standard_api/test_case/create_tests.rb +0 -3
- data/lib/standard_api/test_case/schema_tests.rb +19 -3
- data/lib/standard_api/version.rb +1 -1
- data/lib/standard_api/views/application/_schema.json.jbuilder +68 -0
- data/lib/standard_api/views/application/_schema.streamer +78 -0
- data/lib/standard_api/views/application/schema.json.jbuilder +1 -12
- data/lib/standard_api/views/application/schema.streamer +1 -16
- data/test/standard_api/test_app.rb +1 -0
- data/test/standard_api/test_app/models.rb +6 -1
- data/test/standard_api/test_app/views/photos/_photo.streamer +17 -0
- data/test/standard_api/test_app/views/photos/_schema.json.jbuilder +1 -0
- data/test/standard_api/test_app/views/photos/_schema.streamer +3 -0
- data/test/standard_api/test_app/views/photos/schema.json.jbuilder +1 -1
- data/test/standard_api/test_app/views/photos/schema.streamer +1 -0
- metadata +9 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3670132e90418137f095c8e7741310e2911bfde21e78579e27ea6c54ae88d0f1
|
4
|
+
data.tar.gz: 205778759e7188eda509e289495a383d6a5ff037116fd5043a519f95c5b7222d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2d4a009d0ea47b18ebc5088d81bdf4518e9a22749b1ea0a17e8f7b5504be42dbeea60945ad75eeb5a4cdfda866f39edc12391262ff64b2a5cc3748011cb0c4bc
|
7
|
+
data.tar.gz: 49a638815647e3fbe6d63dc4eda87eda4703425b2c36e4565763cc0aad1abf0934d54d8f18858d00ac733f1e4662873f5ff586e1cdf27aafdaebfbc825703b71
|
data/README.md
CHANGED
@@ -105,11 +105,12 @@ including the author, the photos that the author took can also be included.
|
|
105
105
|
# API Usage
|
106
106
|
Resources can be queried via REST style end points
|
107
107
|
```
|
108
|
-
GET /records/:id
|
109
|
-
PATCH /records/:id
|
110
|
-
GET /records
|
111
|
-
|
112
|
-
|
108
|
+
GET /records/:id fetch record
|
109
|
+
PATCH /records/:id update record
|
110
|
+
GET /records/ fetch records
|
111
|
+
GET /records/calculate apply count and other functions on record(s)
|
112
|
+
POST /records create record
|
113
|
+
DELETE /records destroy record
|
113
114
|
```
|
114
115
|
|
115
116
|
All resource end points can be filtered, ordered, limited, offset, and have includes. All options are passed via query string in a nested URI encoded format.
|
@@ -163,8 +164,16 @@ location: {within: 0106000020e6...} WHERE ST_Within("listings"."location
|
|
163
164
|
|
164
165
|
// On Relationships
|
165
166
|
property: {size: 10000} JOIN properties WHERE properties.size = 10000"
|
167
|
+
```
|
168
|
+
## Calculations
|
169
|
+
|
170
|
+
The only change on calculate routes is the `selects` paramater contains the functions to apply. Currently just `minimum`, `maximum`, `average`, `sum`, and `count`.
|
166
171
|
|
167
|
-
|
172
|
+
```
|
173
|
+
{ count: '*' } SELECT COUNT(*)
|
174
|
+
[{ count: '*' }] SELECT COUNT(*)
|
175
|
+
[{ count: '*', maximum: :id, minimum: :id }] SELECT COUNT(*), MAXIMUM(id), MINIMUM(id)
|
176
|
+
[{ maximum: :id }, { maximum: :count }] SELECT MAXIMUM(id), MAXIMUM(count)
|
168
177
|
```
|
169
178
|
|
170
179
|
# Testing
|
data/lib/standard_api.rb
CHANGED
@@ -0,0 +1,21 @@
|
|
1
|
+
module ActiveRecord
|
2
|
+
module ConnectionAdapters
|
3
|
+
class PostgreSQLAdapter < AbstractAdapter
|
4
|
+
|
5
|
+
# Returns a comment stored in database for given table
|
6
|
+
def database_comment(database_name=nil) # :nodoc:
|
7
|
+
database_name ||= current_database
|
8
|
+
|
9
|
+
scope = quoted_scope(database_name, type: "BASE TABLE")
|
10
|
+
if scope[:name]
|
11
|
+
query_value(<<~SQL, "SCHEMA")
|
12
|
+
SELECT pg_catalog.shobj_description(d.oid, 'pg_database')
|
13
|
+
FROM pg_catalog.pg_database d
|
14
|
+
WHERE datname = #{scope[:name]};
|
15
|
+
SQL
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -4,7 +4,7 @@ module StandardAPI
|
|
4
4
|
delegate :preloadables, to: :helpers
|
5
5
|
|
6
6
|
def self.included(klass)
|
7
|
-
klass.helper_method :includes, :orders, :model, :resource_limit,
|
7
|
+
klass.helper_method :includes, :orders, :model, :models, :resource_limit,
|
8
8
|
:default_limit
|
9
9
|
klass.before_action :set_standardapi_headers
|
10
10
|
klass.rescue_from StandardAPI::UnpermittedParameters, with: :bad_request
|
@@ -15,11 +15,17 @@ module StandardAPI
|
|
15
15
|
def tables
|
16
16
|
Rails.application.eager_load! if !Rails.application.config.eager_load
|
17
17
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
render json:
|
18
|
+
tables = ApplicationController.descendants
|
19
|
+
tables.select! { |c| c.ancestors.include?(self.class) && c != self.class }
|
20
|
+
tables.map!(&:model).compact!
|
21
|
+
tables.map!(&:table_name)
|
22
|
+
render json: tables
|
23
|
+
end
|
24
|
+
|
25
|
+
if Rails.env == 'development'
|
26
|
+
def schema
|
27
|
+
Rails.application.eager_load! if !Rails.application.config.eager_load
|
28
|
+
end
|
23
29
|
end
|
24
30
|
|
25
31
|
def index
|
@@ -36,7 +42,7 @@ module StandardAPI
|
|
36
42
|
end
|
37
43
|
end
|
38
44
|
@calculations = Hash[@calculations] if @calculations[0].is_a?(Array) && params[:group_by]
|
39
|
-
|
45
|
+
|
40
46
|
render json: @calculations
|
41
47
|
end
|
42
48
|
|
@@ -97,12 +103,12 @@ module StandardAPI
|
|
97
103
|
resources.find(params[:id]).destroy!
|
98
104
|
head :no_content
|
99
105
|
end
|
100
|
-
|
106
|
+
|
101
107
|
def remove_resource
|
102
108
|
resource = resources.find(params[:id])
|
103
109
|
subresource_class = resource.association(params[:relationship]).klass
|
104
110
|
subresource = subresource_class.find_by_id(params[:resource_id])
|
105
|
-
|
111
|
+
|
106
112
|
if(subresource)
|
107
113
|
result = resource.send(params[:relationship]).delete(subresource)
|
108
114
|
head result ? :no_content : :bad_request
|
@@ -110,10 +116,10 @@ module StandardAPI
|
|
110
116
|
head :not_found
|
111
117
|
end
|
112
118
|
end
|
113
|
-
|
119
|
+
|
114
120
|
def add_resource
|
115
121
|
resource = resources.find(params[:id])
|
116
|
-
|
122
|
+
|
117
123
|
subresource_class = resource.association(params[:relationship]).klass
|
118
124
|
subresource = subresource_class.find_by_id(params[:resource_id])
|
119
125
|
if(subresource)
|
@@ -122,7 +128,7 @@ module StandardAPI
|
|
122
128
|
else
|
123
129
|
head :not_found
|
124
130
|
end
|
125
|
-
|
131
|
+
|
126
132
|
end
|
127
133
|
|
128
134
|
# Override if you want to support masking
|
@@ -131,7 +137,7 @@ module StandardAPI
|
|
131
137
|
end
|
132
138
|
|
133
139
|
module ClassMethods
|
134
|
-
|
140
|
+
|
135
141
|
def model
|
136
142
|
return @model if defined?(@model)
|
137
143
|
@model = name.sub(/Controller\z/, '').singularize.camelize.safe_constantize
|
@@ -153,6 +159,15 @@ module StandardAPI
|
|
153
159
|
self.class.model
|
154
160
|
end
|
155
161
|
|
162
|
+
def models
|
163
|
+
return @models if defined?(@models)
|
164
|
+
Rails.application.eager_load! if !Rails.application.config.eager_load
|
165
|
+
|
166
|
+
@models = ApplicationController.descendants
|
167
|
+
@models.select! { |c| c.ancestors.include?(self.class) && c != self.class }
|
168
|
+
@models.map!(&:model).compact!
|
169
|
+
end
|
170
|
+
|
156
171
|
def model_includes
|
157
172
|
if self.respond_to?("#{model.model_name.singular}_includes", true)
|
158
173
|
self.send("#{model.model_name.singular}_includes")
|
@@ -192,21 +207,21 @@ module StandardAPI
|
|
192
207
|
|
193
208
|
def resources
|
194
209
|
query = model.filter(params['where']).filter(current_mask[model.table_name])
|
195
|
-
|
210
|
+
|
196
211
|
if params[:distinct_on]
|
197
212
|
query = query.distinct_on(params[:distinct_on])
|
198
213
|
elsif params[:distinct]
|
199
214
|
query = query.distinct
|
200
215
|
end
|
201
|
-
|
216
|
+
|
202
217
|
if params[:join]
|
203
218
|
query = query.joins(params[:join].to_sym)
|
204
219
|
end
|
205
|
-
|
220
|
+
|
206
221
|
if params[:group_by]
|
207
222
|
query = query.group(params[:group_by])
|
208
223
|
end
|
209
|
-
|
224
|
+
|
210
225
|
query
|
211
226
|
end
|
212
227
|
|
@@ -224,7 +239,7 @@ module StandardAPI
|
|
224
239
|
|
225
240
|
def orders
|
226
241
|
exluded_required_orders = required_orders.map(&:to_s)
|
227
|
-
|
242
|
+
|
228
243
|
case params[:order]
|
229
244
|
when Hash, ActionController::Parameters
|
230
245
|
exluded_required_orders -= params[:order].keys.map(&:to_s)
|
@@ -240,7 +255,7 @@ module StandardAPI
|
|
240
255
|
when String
|
241
256
|
exluded_required_orders.delete(params[:order])
|
242
257
|
end
|
243
|
-
|
258
|
+
|
244
259
|
if !exluded_required_orders.empty?
|
245
260
|
params[:order] = exluded_required_orders.unshift(params[:order])
|
246
261
|
end
|
@@ -298,7 +313,7 @@ module StandardAPI
|
|
298
313
|
@model = parts[0].singularize.camelize.constantize
|
299
314
|
column = parts[1]
|
300
315
|
end
|
301
|
-
|
316
|
+
|
302
317
|
column = column == '*' ? Arel.star : column.to_sym
|
303
318
|
if functions.include?(func.to_s.downcase)
|
304
319
|
node = (defined?(@model) ? @model : model).arel_table[column].send(func)
|
data/lib/standard_api/helpers.rb
CHANGED
@@ -18,7 +18,7 @@ module StandardAPI
|
|
18
18
|
end
|
19
19
|
end
|
20
20
|
end
|
21
|
-
|
21
|
+
|
22
22
|
preloads.empty? ? record : record.preload(preloads)
|
23
23
|
end
|
24
24
|
|
@@ -26,7 +26,7 @@ module StandardAPI
|
|
26
26
|
preloads = {}
|
27
27
|
|
28
28
|
iclds.each do |key, value|
|
29
|
-
if reflection = klass.reflections[key]
|
29
|
+
if reflection = klass.reflections[key]
|
30
30
|
case value
|
31
31
|
when true
|
32
32
|
preloads[key] = value
|
@@ -39,10 +39,20 @@ module StandardAPI
|
|
39
39
|
end
|
40
40
|
end
|
41
41
|
end
|
42
|
-
|
42
|
+
|
43
43
|
preloads
|
44
44
|
end
|
45
45
|
|
46
|
+
def schema_partial(model)
|
47
|
+
path = model.model_name.plural
|
48
|
+
|
49
|
+
if lookup_context.exists?("schema", path, true)
|
50
|
+
[path, "schema"].join('/')
|
51
|
+
else
|
52
|
+
'application/schema'
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
46
56
|
def model_partial(record)
|
47
57
|
if lookup_context.exists?(record.model_name.element, record.model_name.plural, true)
|
48
58
|
[record.model_name.plural, record.model_name.element].join('/')
|
@@ -59,7 +69,7 @@ module StandardAPI
|
|
59
69
|
false
|
60
70
|
end
|
61
71
|
end
|
62
|
-
|
72
|
+
|
63
73
|
def cache_key(record, includes)
|
64
74
|
timestamp_keys = ['cached_at'] + record.class.column_names.select{|x| x.ends_with? "_cached_at"}
|
65
75
|
if includes.empty?
|
@@ -69,7 +79,7 @@ module StandardAPI
|
|
69
79
|
"#{record.model_name.cache_key}/#{record.id}-#{digest_hash(sort_hash(includes))}-#{timestamp.utc.to_s(record.cache_timestamp_format)}"
|
70
80
|
end
|
71
81
|
end
|
72
|
-
|
82
|
+
|
73
83
|
def can_cache_relation?(klass, relation, subincludes)
|
74
84
|
cache_columns = ["#{relation}_cached_at"] + cached_at_columns_for_includes(subincludes).map {|c| "#{relation}_#{c}"}
|
75
85
|
if (cache_columns - klass.column_names).empty?
|
@@ -78,12 +88,12 @@ module StandardAPI
|
|
78
88
|
false
|
79
89
|
end
|
80
90
|
end
|
81
|
-
|
91
|
+
|
82
92
|
def association_cache_key(record, relation, subincludes)
|
83
93
|
timestamp = ["#{relation}_cached_at"] + cached_at_columns_for_includes(subincludes).map {|c| "#{relation}_#{c}"}
|
84
94
|
timestamp.map! { |col| record.send(col) }
|
85
95
|
timestamp = timestamp.max
|
86
|
-
|
96
|
+
|
87
97
|
case association = record.class.reflect_on_association(relation)
|
88
98
|
when ActiveRecord::Reflection::HasManyReflection, ActiveRecord::Reflection::HasAndBelongsToManyReflection, ActiveRecord::Reflection::HasOneReflection, ActiveRecord::Reflection::ThroughReflection
|
89
99
|
"#{record.model_name.cache_key}/#{record.id}/#{includes_to_cache_key(relation, subincludes)}-#{timestamp.utc.to_s(record.cache_timestamp_format)}"
|
@@ -112,7 +122,7 @@ module StandardAPI
|
|
112
122
|
"#{relation}-#{digest_hash(sort_hash(subincludes))}"
|
113
123
|
end
|
114
124
|
end
|
115
|
-
|
125
|
+
|
116
126
|
def sort_hash(hash)
|
117
127
|
hash.keys.sort.reduce({}) do |seed, key|
|
118
128
|
if seed[key].is_a?(Hash)
|
@@ -123,7 +133,7 @@ module StandardAPI
|
|
123
133
|
seed
|
124
134
|
end
|
125
135
|
end
|
126
|
-
|
136
|
+
|
127
137
|
def digest_hash(*hashes)
|
128
138
|
hashes.compact!
|
129
139
|
hashes.map! { |h| sort_hash(h) }
|
@@ -183,4 +193,4 @@ module StandardAPI
|
|
183
193
|
end
|
184
194
|
|
185
195
|
end
|
186
|
-
end
|
196
|
+
end
|
@@ -12,7 +12,7 @@ module StandardAPI
|
|
12
12
|
create_model
|
13
13
|
|
14
14
|
math_column = model.columns.find { |x| CALCULATE_COLUMN_TYPES.include?(x.sql_type) }
|
15
|
-
|
15
|
+
|
16
16
|
if math_column
|
17
17
|
column = math_column
|
18
18
|
selects = [{ count: column.name }, { maximum: column.name }, { minimum: column.name }, { average: column.name }]
|
@@ -35,7 +35,7 @@ module StandardAPI
|
|
35
35
|
create_model
|
36
36
|
|
37
37
|
math_column = model.columns.find { |x| CALCULATE_COLUMN_TYPES.include?(x.sql_type) }
|
38
|
-
|
38
|
+
|
39
39
|
if math_column
|
40
40
|
column = math_column
|
41
41
|
selects = [{ count: column.name}, { maximum: column.name }, { minimum: column.name }, { average: column.name }]
|
@@ -91,9 +91,6 @@ module StandardAPI
|
|
91
91
|
mask.each { |k, v| attrs[k] = v }
|
92
92
|
create_webmocks(attrs)
|
93
93
|
|
94
|
-
file_upload = attrs.any? { |k, v| v.is_a?(Rack::Test::UploadedFile) }
|
95
|
-
as = file_upload ? nil : :json
|
96
|
-
|
97
94
|
assert_difference("#{model.name}.count") do
|
98
95
|
post resource_path(:create), params: { singular_name => attrs }, as: :html
|
99
96
|
assert_response :redirect
|
@@ -9,13 +9,29 @@ module StandardAPI
|
|
9
9
|
get resource_path(:schema, format: :json)
|
10
10
|
assert_response :ok
|
11
11
|
json = JSON(@response.body)
|
12
|
-
assert json['
|
12
|
+
assert json['attributes']
|
13
|
+
|
13
14
|
model.columns.map do |column|
|
14
|
-
|
15
|
+
actual_column = json['attributes'][column.name]
|
16
|
+
assert_not_nil actual_column['type'], "Missing `type` for \"#{model}\" attribute \"#{column.name}\""
|
17
|
+
assert_equal_or_nil model.primary_key == column.name, actual_column['primary_key']
|
18
|
+
assert_equal_or_nil column.null, actual_column['null']
|
19
|
+
assert_equal_or_nil column.array, actual_column['array']
|
20
|
+
assert_equal_or_nil column.comment, actual_column['comment']
|
21
|
+
assert_equal_or_nil (column.default || column.default_function), actual_column['default']
|
15
22
|
end
|
23
|
+
|
16
24
|
assert json['limit']
|
25
|
+
assert_equal_or_nil model.connection.table_comment(model.table_name), json['comment']
|
17
26
|
end
|
18
27
|
|
28
|
+
def assert_equal_or_nil(expected, actual, msg=nil)
|
29
|
+
if expected.nil?
|
30
|
+
assert_nil actual, msg
|
31
|
+
else
|
32
|
+
assert_equal expected, actual, msg
|
33
|
+
end
|
34
|
+
end
|
19
35
|
end
|
20
36
|
end
|
21
|
-
end
|
37
|
+
end
|
data/lib/standard_api/version.rb
CHANGED
@@ -0,0 +1,68 @@
|
|
1
|
+
if model.nil? && controller_name == "application"
|
2
|
+
routes = Rails.application.routes.routes.reject(&:internal).collect do |route|
|
3
|
+
{ name: route.name,
|
4
|
+
verb: route.verb,
|
5
|
+
path: route.path.spec.to_s.gsub(/\(\.format\)\Z/, ''),
|
6
|
+
controller: route.requirements[:controller],
|
7
|
+
action: route.requirements[:action],
|
8
|
+
array: ['index'].include?(route.requirements[:action]) }
|
9
|
+
end
|
10
|
+
|
11
|
+
json.set! 'comment', ActiveRecord::Base.connection.database_comment
|
12
|
+
|
13
|
+
json.set! 'routes' do
|
14
|
+
json.array!(routes) do |route|
|
15
|
+
controller = if controller_name = route[:controller]
|
16
|
+
begin
|
17
|
+
controller_param = controller_name.underscore
|
18
|
+
const_name = "#{controller_param.camelize}Controller"
|
19
|
+
const = ActiveSupport::Dependencies.constantize(const_name)
|
20
|
+
if const.ancestors.include?(StandardAPI::Controller)
|
21
|
+
const
|
22
|
+
else
|
23
|
+
nil
|
24
|
+
end
|
25
|
+
rescue NameError
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
next if controller.nil?
|
30
|
+
|
31
|
+
resource_limit = controller.resource_limit if controller.respond_to?(:resource_limit)
|
32
|
+
|
33
|
+
json.set! 'path', route[:path]
|
34
|
+
json.set! 'method', route[:verb]
|
35
|
+
json.set! 'model', controller.model&.name
|
36
|
+
json.set! 'array', route[:array]
|
37
|
+
json.set! 'limit', resource_limit
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
json.set! 'models' do
|
42
|
+
models.each do |model|
|
43
|
+
json.set! model.name do
|
44
|
+
json.partial! partial: schema_partial(model), model: model
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
else
|
50
|
+
|
51
|
+
json.set! 'attributes' do
|
52
|
+
model.columns.each do |column|
|
53
|
+
json.set! column.name, {
|
54
|
+
type: json_column_type(column.sql_type),
|
55
|
+
default: column.default || column.default_function,
|
56
|
+
primary_key: column.name == model.primary_key,
|
57
|
+
null: column.null,
|
58
|
+
array: column.array,
|
59
|
+
comment: column.comment
|
60
|
+
}
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
json.set! 'limit', resource_limit # This should be removed?
|
65
|
+
json.set! 'comment', model.connection.table_comment(model.table_name)
|
66
|
+
|
67
|
+
end
|
68
|
+
|
@@ -0,0 +1,78 @@
|
|
1
|
+
if model.nil? && controller_name == "application"
|
2
|
+
routes = Rails.application.routes.routes.reject(&:internal).collect do |route|
|
3
|
+
{ name: route.name,
|
4
|
+
verb: route.verb,
|
5
|
+
path: route.path.spec.to_s.gsub(/\(\.:format\)\Z/, ''),
|
6
|
+
controller: route.requirements[:controller],
|
7
|
+
action: route.requirements[:action],
|
8
|
+
array: ['index'].include?(route.requirements[:action]) }
|
9
|
+
end
|
10
|
+
|
11
|
+
json.object! do
|
12
|
+
json.set! 'comment', ActiveRecord::Base.connection.database_comment
|
13
|
+
|
14
|
+
json.set! 'routes' do
|
15
|
+
json.array!(routes) do |route|
|
16
|
+
controller = if controller_name = route[:controller]
|
17
|
+
begin
|
18
|
+
controller_param = controller_name.underscore
|
19
|
+
const_name = "#{controller_param.camelize}Controller"
|
20
|
+
const = ActiveSupport::Dependencies.constantize(const_name)
|
21
|
+
if const.ancestors.include?(StandardAPI::Controller)
|
22
|
+
const
|
23
|
+
else
|
24
|
+
nil
|
25
|
+
end
|
26
|
+
rescue NameError
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
next if controller.nil?
|
31
|
+
|
32
|
+
resource_limit = controller.resource_limit if controller.respond_to?(:resource_limit)
|
33
|
+
|
34
|
+
json.object! do
|
35
|
+
json.set! 'path', route[:path]
|
36
|
+
json.set! 'method', route[:verb]
|
37
|
+
json.set! 'model', controller.model&.name
|
38
|
+
json.set! 'array', route[:array]
|
39
|
+
json.set! 'limit', resource_limit
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
|
45
|
+
json.set! 'models' do
|
46
|
+
json.object! do
|
47
|
+
models.each do |model|
|
48
|
+
json.set! model.name do
|
49
|
+
json.partial!(schema_partial(model), model: model)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
else
|
57
|
+
|
58
|
+
json.object! do
|
59
|
+
json.set! 'attributes' do
|
60
|
+
json.object! do
|
61
|
+
model.columns.each do |column|
|
62
|
+
json.set! column.name, {
|
63
|
+
type: json_column_type(column.sql_type),
|
64
|
+
default: column.default || column.default_function,
|
65
|
+
primary_key: column.name == model.primary_key,
|
66
|
+
null: column.null,
|
67
|
+
array: column.array,
|
68
|
+
comment: column.comment
|
69
|
+
}
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
json.set! 'limit', resource_limit
|
75
|
+
json.set! 'comment', model.connection.table_comment(model.table_name)
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
@@ -1,12 +1 @@
|
|
1
|
-
json.
|
2
|
-
model.columns.each do |column|
|
3
|
-
json.set! column.name, {
|
4
|
-
type: json_column_type(column.sql_type),
|
5
|
-
primary_key: column.name == model.primary_key,
|
6
|
-
null: column.null,
|
7
|
-
array: column.array
|
8
|
-
}
|
9
|
-
end
|
10
|
-
end
|
11
|
-
|
12
|
-
json.set! 'limit', resource_limit
|
1
|
+
json.partial!('schema', model: model)
|
@@ -1,16 +1 @@
|
|
1
|
-
json.
|
2
|
-
json.set! 'columns' do
|
3
|
-
json.object! do
|
4
|
-
model.columns.each do |column|
|
5
|
-
json.set! column.name, {
|
6
|
-
type: json_column_type(column.sql_type),
|
7
|
-
primary_key: column.name == model.primary_key,
|
8
|
-
null: column.null,
|
9
|
-
array: column.array
|
10
|
-
}
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
json.set! 'limit', resource_limit
|
16
|
-
end
|
1
|
+
json.partial!('schema', model: model)
|
@@ -37,6 +37,7 @@ require 'standard_api/test_app/controllers'
|
|
37
37
|
# Test Application Routes
|
38
38
|
Rails.application.routes.draw do
|
39
39
|
get :tables, to: 'application#tables', as: :tables
|
40
|
+
get :schema, to: 'application#schema', as: :schema
|
40
41
|
|
41
42
|
[:properties, :photos, :documents, :references, :sessions, :unlimited, :default_limit].each do |r|
|
42
43
|
standard_resources r
|
@@ -36,10 +36,15 @@ end
|
|
36
36
|
|
37
37
|
# = Migration
|
38
38
|
|
39
|
-
class CreateModelTables < ActiveRecord::Migration[
|
39
|
+
class CreateModelTables < ActiveRecord::Migration[6.0]
|
40
40
|
|
41
41
|
def self.up
|
42
42
|
|
43
|
+
comment = "test comment"
|
44
|
+
exec_query(<<-SQL, "SQL")
|
45
|
+
COMMENT ON DATABASE #{quote_column_name(current_database)} IS #{quote(comment)};
|
46
|
+
SQL
|
47
|
+
|
43
48
|
create_table "accounts", force: :cascade do |t|
|
44
49
|
t.string 'name', limit: 255
|
45
50
|
t.integer 'property_id'
|
@@ -0,0 +1,17 @@
|
|
1
|
+
json.object! do
|
2
|
+
json.set! :id, photo.id
|
3
|
+
json.set! :account_id, photo.account_id
|
4
|
+
json.set! :property_id, photo.property_id
|
5
|
+
json.set! :format, photo.format
|
6
|
+
json.set! :template, 'photos/_photo'
|
7
|
+
|
8
|
+
if includes[:account]
|
9
|
+
json.set! :account do
|
10
|
+
if photo.account
|
11
|
+
json.partial! 'application/record', record: photo.account, includes: includes[:account]
|
12
|
+
else
|
13
|
+
json.null!
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
json.set! 'template', 'photos/schema'
|
@@ -1 +1 @@
|
|
1
|
-
json.
|
1
|
+
json.partial! 'schema'
|
@@ -0,0 +1 @@
|
|
1
|
+
json.partial! 'schema'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: standardapi
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 6.0.0.
|
4
|
+
version: 6.0.0.29
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- James Bracy
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-
|
11
|
+
date: 2019-12-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -245,6 +245,7 @@ extra_rdoc_files:
|
|
245
245
|
files:
|
246
246
|
- README.md
|
247
247
|
- lib/standard_api.rb
|
248
|
+
- lib/standard_api/active_record/connection_adapters/postgresql/schema_statements.rb
|
248
249
|
- lib/standard_api/controller.rb
|
249
250
|
- lib/standard_api/errors.rb
|
250
251
|
- lib/standard_api/helpers.rb
|
@@ -265,6 +266,8 @@ files:
|
|
265
266
|
- lib/standard_api/version.rb
|
266
267
|
- lib/standard_api/views/application/_record.json.jbuilder
|
267
268
|
- lib/standard_api/views/application/_record.streamer
|
269
|
+
- lib/standard_api/views/application/_schema.json.jbuilder
|
270
|
+
- lib/standard_api/views/application/_schema.streamer
|
268
271
|
- lib/standard_api/views/application/index.json.jbuilder
|
269
272
|
- lib/standard_api/views/application/index.streamer
|
270
273
|
- lib/standard_api/views/application/new.json.jbuilder
|
@@ -280,7 +283,11 @@ files:
|
|
280
283
|
- test/standard_api/test_app/test/factories.rb
|
281
284
|
- test/standard_api/test_app/test/fixtures/photo.png
|
282
285
|
- test/standard_api/test_app/views/photos/_photo.json.jbuilder
|
286
|
+
- test/standard_api/test_app/views/photos/_photo.streamer
|
287
|
+
- test/standard_api/test_app/views/photos/_schema.json.jbuilder
|
288
|
+
- test/standard_api/test_app/views/photos/_schema.streamer
|
283
289
|
- test/standard_api/test_app/views/photos/schema.json.jbuilder
|
290
|
+
- test/standard_api/test_app/views/photos/schema.streamer
|
284
291
|
- test/standard_api/test_app/views/properties/edit.html.erb
|
285
292
|
- test/standard_api/test_app/views/sessions/new.html.erb
|
286
293
|
homepage: https://github.com/waratuman/standardapi
|