standardapi 7.1.1 → 7.1.3
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/lib/standard_api/version.rb +1 -1
- data/lib/standard_api/views/application/_schema.json.jbuilder +11 -1
- data/lib/standard_api/views/application/_schema.streamer +10 -0
- data/lib/standard_api/visitors/validations.rb +73 -0
- data/lib/standard_api.rb +1 -0
- data/test/standard_api/standard_api_test.rb +27 -0
- data/test/standard_api/test_app/app/controllers/acl/property_acl.rb +13 -2
- data/test/standard_api/test_app/models.rb +19 -4
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 692542999da28b20821233c6649dcc8e4b66bdf76183b44ab665ff2452cd0cfd
|
4
|
+
data.tar.gz: 92cf5184a56a2695f34478bd29895d5aa6ba01181548eb77a990da5b8e62f28b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 99356387601124215ce2d86926cdb98d04b38c3141d4a6affa7ba6464c2f0d6342fe506ce34859a284499e626eb1cc0c2573364cf13cb4d8d9216210b24a8120
|
7
|
+
data.tar.gz: b54933f7376b9f672f2a37ef8c2fd21893c37650907b906b6ccfdc2f489a0b37a6bc3fa639e3e374d023a8645557c33b408a0024763d2ae8f24a9bc822154975
|
data/lib/standard_api/version.rb
CHANGED
@@ -69,7 +69,17 @@ else
|
|
69
69
|
# TODO: it would be nice if rails responded with a true or false here
|
70
70
|
# instead of the function itself
|
71
71
|
json.set! 'auto_populated', !!column.auto_populated? if column.respond_to?(:auto_populated?)
|
72
|
-
|
72
|
+
|
73
|
+
json.set! 'readonly', (if controller.respond_to?("#{ model.model_name.singular }_attributes")
|
74
|
+
!controller.send("#{ model.model_name.singular }_attributes").include?(column.name)
|
75
|
+
else
|
76
|
+
model.readonly_attribute?(column.name)
|
77
|
+
end)
|
78
|
+
|
79
|
+
visitor = StandardAPI::Visitors::Validator.new
|
80
|
+
validations = model.validators.select { |v| v.attributes.include?(column.name.to_sym) }.map { |v| visitor.accept(v, {}) }.compact
|
81
|
+
json.set! 'validations', validations
|
82
|
+
end
|
73
83
|
end
|
74
84
|
end
|
75
85
|
|
@@ -79,6 +79,16 @@ else
|
|
79
79
|
# TODO: it would be nice if rails responded with a true or false here
|
80
80
|
# instead of the function itself
|
81
81
|
json.set! 'auto_populated', !!column.auto_populated? if column.respond_to?(:auto_populated?)
|
82
|
+
|
83
|
+
json.set! 'readonly', (if controller.respond_to?("#{ model.model_name.singular }_attributes")
|
84
|
+
!controller.send("#{ model.model_name.singular }_attributes").include?(column.name)
|
85
|
+
else
|
86
|
+
true
|
87
|
+
end)
|
88
|
+
|
89
|
+
visitor = StandardAPI::Visitors::Validator.new
|
90
|
+
validations = model.validators.select { |v| v.attributes.include?(column.name.to_sym) }.map { |v| visitor.accept(v, {}) }.compact
|
91
|
+
json.set! 'validations', validations
|
82
92
|
end
|
83
93
|
end
|
84
94
|
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
module StandardAPI
|
2
|
+
module Visitors
|
3
|
+
|
4
|
+
class Validator < Arel::Visitors::Visitor
|
5
|
+
|
6
|
+
def visit_ActiveRecord_Validations_AbsenceValidator(o, col)
|
7
|
+
visit_validator(:absence, o.options)
|
8
|
+
end
|
9
|
+
|
10
|
+
def visit_ActiveRecord_Validations_AcceptanceValidator(o, col)
|
11
|
+
visit_validator(:acceptance, o.options)
|
12
|
+
end
|
13
|
+
|
14
|
+
def visit_ActiveRecord_Validations_ComparisonValidator(o, col)
|
15
|
+
visit_validator(:comparison, o.options)
|
16
|
+
end
|
17
|
+
|
18
|
+
def visit_ActiveRecord_Validations_ConfirmationValidator(o, col)
|
19
|
+
visit_validator(:confirmation, o.options)
|
20
|
+
end
|
21
|
+
|
22
|
+
def visit_ActiveRecord_Validations_ExclusionValidator(o, col)
|
23
|
+
visit_validator(:exclusion, o.options)
|
24
|
+
end
|
25
|
+
|
26
|
+
def visit_ActiveRecord_Validations_FormatValidator(o, col)
|
27
|
+
visit_validator(:format, o.options)
|
28
|
+
end
|
29
|
+
|
30
|
+
def visit_ActiveRecord_Validations_InclusionValidator(o, col)
|
31
|
+
visit_validator(:inclusion, o.options)
|
32
|
+
end
|
33
|
+
|
34
|
+
def visit_ActiveRecord_Validations_LengthValidator(o, col)
|
35
|
+
visit_validator(:length, o.options)
|
36
|
+
end
|
37
|
+
|
38
|
+
def visit_ActiveRecord_Validations_NumericalityValidator(o, col)
|
39
|
+
visit_validator(:numericality, o.options)
|
40
|
+
end
|
41
|
+
|
42
|
+
def visit_ActiveRecord_Validations_PresenceValidator(o, col)
|
43
|
+
visit_validator(:presence, o.options)
|
44
|
+
end
|
45
|
+
|
46
|
+
def visit_ActiveRecord_Validations_WithValidator(o, col)
|
47
|
+
visit_validator(:with, o.options)
|
48
|
+
end
|
49
|
+
|
50
|
+
def visit_ActiveModel_Validations_FormatValidator(o, col)
|
51
|
+
visit_validator(:format, o.options)
|
52
|
+
end
|
53
|
+
|
54
|
+
private
|
55
|
+
|
56
|
+
def visit_validator(name, options)
|
57
|
+
{ name => options.empty? ? true : options.as_json }
|
58
|
+
end
|
59
|
+
|
60
|
+
def visit(object, collector = nil)
|
61
|
+
dispatch_method = dispatch[object.class]
|
62
|
+
if collector
|
63
|
+
send dispatch_method, object, collector
|
64
|
+
else
|
65
|
+
send dispatch_method, object
|
66
|
+
end
|
67
|
+
rescue NoMethodError => e
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
end
|
data/lib/standard_api.rb
CHANGED
@@ -16,6 +16,7 @@ require 'standard_api/helpers'
|
|
16
16
|
require 'standard_api/route_helpers'
|
17
17
|
require 'standard_api/active_record/connection_adapters/postgresql/schema_statements'
|
18
18
|
require 'standard_api/railtie'
|
19
|
+
require 'standard_api/visitors/validations'
|
19
20
|
|
20
21
|
module StandardAPI
|
21
22
|
autoload :AccessControlList, 'standard_api/access_control_list'
|
@@ -161,6 +161,31 @@ class PropertiesControllerTest < ActionDispatch::IntegrationTest
|
|
161
161
|
end
|
162
162
|
end
|
163
163
|
|
164
|
+
assert_equal true, schema['models']['Account']['attributes']['id']['readonly']
|
165
|
+
assert_equal false, schema['models']['Account']['attributes']['name']['readonly']
|
166
|
+
|
167
|
+
assert_equal [
|
168
|
+
{"format"=>{"allow_nil"=>true, "with"=>"(?-mix:.+@.+)"}}
|
169
|
+
], schema['models']['Account']['attributes']['email']['validations']
|
170
|
+
|
171
|
+
assert_equal [
|
172
|
+
{ "presence" => true }
|
173
|
+
], schema['models']['Property']['attributes']['name']['validations']
|
174
|
+
|
175
|
+
assert_equal [
|
176
|
+
{ "numericality" => {
|
177
|
+
"greater_than" => 1,
|
178
|
+
"greater_than_or_equal_to" => 2,
|
179
|
+
"equal_to" => 2,
|
180
|
+
"less_than_or_equal_to" => 2,
|
181
|
+
"less_than" => 3,
|
182
|
+
"other_than" => 0,
|
183
|
+
"even" => true,
|
184
|
+
"in" => "1..3"
|
185
|
+
}
|
186
|
+
}
|
187
|
+
], schema['models']['Property']['attributes']['numericality']['validations']
|
188
|
+
|
164
189
|
assert_equal 'test comment', schema['comment']
|
165
190
|
end
|
166
191
|
|
@@ -756,4 +781,6 @@ class PropertiesControllerTest < ActionDispatch::IntegrationTest
|
|
756
781
|
end
|
757
782
|
end
|
758
783
|
|
784
|
+
|
785
|
+
|
759
786
|
end
|
@@ -7,7 +7,8 @@ module PropertyACL
|
|
7
7
|
:description,
|
8
8
|
:constructed,
|
9
9
|
:size,
|
10
|
-
:active
|
10
|
+
:active,
|
11
|
+
:numericality
|
11
12
|
# :photos_attributes,
|
12
13
|
# { photos_attributes: [ :id, :account_id, :property_id, :format] }
|
13
14
|
]
|
@@ -15,7 +16,17 @@ module PropertyACL
|
|
15
16
|
|
16
17
|
# Orderings allowed
|
17
18
|
def orders
|
18
|
-
[
|
19
|
+
[
|
20
|
+
"id",
|
21
|
+
"name",
|
22
|
+
"aliases",
|
23
|
+
"description",
|
24
|
+
"constructed",
|
25
|
+
"size",
|
26
|
+
"created_at",
|
27
|
+
"active",
|
28
|
+
"numericality"
|
29
|
+
]
|
19
30
|
end
|
20
31
|
|
21
32
|
# Sub resources allowed to be included in the response
|
@@ -1,6 +1,7 @@
|
|
1
1
|
# = Models
|
2
2
|
|
3
3
|
class Account < ActiveRecord::Base
|
4
|
+
validates :email, format: /.+@.+/, allow_nil: true
|
4
5
|
has_many :photos, -> { order(:created_at) }
|
5
6
|
belongs_to :property
|
6
7
|
belongs_to :subject, polymorphic: true
|
@@ -14,7 +15,7 @@ end
|
|
14
15
|
|
15
16
|
class Document < ActiveRecord::Base
|
16
17
|
attr_accessor :file
|
17
|
-
|
18
|
+
|
18
19
|
enum level: { public: 0, secret: 1 }, _suffix: true
|
19
20
|
enum rating: { poor: 0, ok: 1, good: 2 }
|
20
21
|
end
|
@@ -29,13 +30,25 @@ class Property < ActiveRecord::Base
|
|
29
30
|
has_one :document_attachments, class_name: "Attachment", as: :record, inverse_of: :record
|
30
31
|
has_one :document, through: "document_attachments"
|
31
32
|
|
32
|
-
|
33
33
|
validates :name, presence: true
|
34
34
|
accepts_nested_attributes_for :photos
|
35
35
|
|
36
36
|
def english_name
|
37
37
|
'A Name'
|
38
38
|
end
|
39
|
+
|
40
|
+
# Numericality Validation
|
41
|
+
validates :numericality, numericality: {
|
42
|
+
greater_than: 1,
|
43
|
+
greater_than_or_equal_to: 2,
|
44
|
+
equal_to: 2,
|
45
|
+
less_than_or_equal_to: 2,
|
46
|
+
less_than: 3,
|
47
|
+
other_than: 0,
|
48
|
+
even: true,
|
49
|
+
in: 1..3
|
50
|
+
}
|
51
|
+
|
39
52
|
end
|
40
53
|
|
41
54
|
class LSNType < ActiveRecord::Type::Value
|
@@ -101,6 +114,7 @@ class CreateModelTables < ActiveRecord::Migration[6.0]
|
|
101
114
|
|
102
115
|
create_table "accounts", force: :cascade do |t|
|
103
116
|
t.string 'name', limit: 255
|
117
|
+
t.string 'email', limit: 255
|
104
118
|
t.integer 'property_id'
|
105
119
|
t.integer "subject_id"
|
106
120
|
t.string "subject_type"
|
@@ -129,6 +143,7 @@ class CreateModelTables < ActiveRecord::Migration[6.0]
|
|
129
143
|
t.decimal "size"
|
130
144
|
t.datetime "created_at", null: false
|
131
145
|
t.boolean "active", default: false
|
146
|
+
t.integer "numericality", default: 2
|
132
147
|
end
|
133
148
|
|
134
149
|
create_table "references", force: :cascade do |t|
|
@@ -167,12 +182,12 @@ class CreateModelTables < ActiveRecord::Migration[6.0]
|
|
167
182
|
t.integer 'record_id'
|
168
183
|
t.integer 'document_id'
|
169
184
|
end
|
170
|
-
|
185
|
+
|
171
186
|
create_table "uuid_models", id: :uuid, force: :cascade do |t|
|
172
187
|
t.string 'title', default: 'recruit'
|
173
188
|
t.string 'name', default: -> { 'round(random() * 1000)' }
|
174
189
|
end
|
175
|
-
|
190
|
+
|
176
191
|
end
|
177
192
|
|
178
193
|
end
|
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: 7.1.
|
4
|
+
version: 7.1.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- James Bracy
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-10-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -306,6 +306,7 @@ files:
|
|
306
306
|
- lib/standard_api/views/application/schema.streamer
|
307
307
|
- lib/standard_api/views/application/show.json.jbuilder
|
308
308
|
- lib/standard_api/views/application/show.streamer
|
309
|
+
- lib/standard_api/visitors/validations.rb
|
309
310
|
- test/standard_api/caching_test.rb
|
310
311
|
- test/standard_api/controller/include_test.rb
|
311
312
|
- test/standard_api/controller/subresource_test.rb
|
@@ -361,7 +362,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
361
362
|
- !ruby/object:Gem::Version
|
362
363
|
version: '0'
|
363
364
|
requirements: []
|
364
|
-
rubygems_version: 3.5.
|
365
|
+
rubygems_version: 3.5.15
|
365
366
|
signing_key:
|
366
367
|
specification_version: 4
|
367
368
|
summary: StandardAPI makes it easy to expose a query interface for your Rails models
|