activerecord_json_validator 0.5.1 → 1.0.0
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/.travis.yml +0 -1
- data/README.md +49 -64
- data/activerecord_json_validator.gemspec +1 -1
- data/lib/active_record/json_validator/validator.rb +13 -13
- data/lib/active_record/json_validator/version.rb +1 -1
- data/spec/json_validator_spec.rb +32 -0
- metadata +5 -6
- data/gemfiles/Gemfile.activerecord-4.1.x +0 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 53b4aea1bc7007643f31d936e12b78804f96ab9f
|
4
|
+
data.tar.gz: 70f49f4c9bc9930dec7cdaede3d612cd387fd00b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c360ce94176ec1471287f51ad23224a4cd6fe8caeee92d62df27d04df6fa518af18cd92969167282a6e6886aca46ec0221196e825db5ad8758f657165c85f4c9
|
7
|
+
data.tar.gz: f1586c5cca10f3eef4dbb31d602b29f633daf2a778557642816026092db2bfc9c3ed54b672c39e9835bea877280129580d30bb55d9754a3ed47c70f6b2cac589
|
data/.travis.yml
CHANGED
data/README.md
CHANGED
@@ -1,9 +1,15 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
1
|
+
<p align="center">
|
2
|
+
<a href="https://github.com/mirego/activerecord_json_validator">
|
3
|
+
<img src="https://cloud.githubusercontent.com/assets/11348/6099354/cffcf35e-afc3-11e4-9a4d-d872941bbcf6.png" alt="" />
|
4
|
+
</a>
|
5
|
+
<br />
|
6
|
+
<code>ActiveRecord::JSONValidator</code> makes it easy to validate<br /> JSON attributes against a <a href="http://json-schema.org/">JSON schema</a>.
|
7
|
+
<br /><br />
|
8
|
+
<a href="https://rubygems.org/gems/activerecord_json_validator"><img src="http://img.shields.io/gem/v/activerecord_json_validator.svg" /></a>
|
9
|
+
<a href="https://travis-ci.org/mirego/activerecord_json_validator"><img src="http://img.shields.io/travis/mirego/activerecord_json_validator.svg" /></a>
|
10
|
+
</p>
|
11
|
+
|
12
|
+
---
|
7
13
|
|
8
14
|
## Installation
|
9
15
|
|
@@ -20,11 +26,12 @@ gem 'activerecord_json_validator'
|
|
20
26
|
```json
|
21
27
|
{
|
22
28
|
"type": "object",
|
23
|
-
"$schema": "http://json-schema.org/draft-
|
29
|
+
"$schema": "http://json-schema.org/draft-04/schema",
|
24
30
|
"properties": {
|
25
|
-
"city": { "type": "string"
|
26
|
-
"country": { "type": "string"
|
27
|
-
}
|
31
|
+
"city": { "type": "string" },
|
32
|
+
"country": { "type": "string" }
|
33
|
+
},
|
34
|
+
"required": ["country"]
|
28
35
|
}
|
29
36
|
```
|
30
37
|
|
@@ -60,86 +67,64 @@ user.profile_invalid_json # => '{invalid JSON":}'
|
|
60
67
|
|
61
68
|
| Option | Description
|
62
69
|
|------------|-----------------------------------------------------
|
63
|
-
| `:schema` | The JSON schema to validate the data against (see **
|
64
|
-
| `:message` | The ActiveRecord message added to the record errors (
|
70
|
+
| `:schema` | The JSON schema to validate the data against (see **Schema** section)
|
71
|
+
| `:message` | The ActiveRecord message added to the record errors (see **Message** section)
|
65
72
|
|
66
|
-
#####
|
73
|
+
##### Schema
|
67
74
|
|
68
|
-
|
75
|
+
`ActiveRecord::JSONValidator` uses the `json-schema` gem to validate the JSON
|
76
|
+
data against a JSON schema. You can use [any value](https://github.com/ruby-json-schema/json-schema/tree/master#usage) that
|
77
|
+
`JSON::Validator.validate` would take as the `schema` argument.
|
69
78
|
|
70
|
-
|
79
|
+
Additionally, you can use a `Symbol` or a `Proc`. Both will be executed in the
|
80
|
+
context of the validated record (`Symbol` will be sent as a method and the
|
81
|
+
`Proc` will be `instance_exec`ed)
|
71
82
|
|
72
83
|
```ruby
|
73
84
|
class User < ActiveRecord::Base
|
74
85
|
# Constants
|
75
|
-
|
86
|
+
PROFILE_REGULAR_JSON_SCHEMA = Rails.root.join('config', 'schemas', 'profile.json_schema').to_s
|
87
|
+
PROFILE_ADMIN_JSON_SCHEMA = Rails.root.join('config', 'schemas', 'profile_admin.json_schema').to_s
|
76
88
|
|
77
89
|
# Validations
|
78
|
-
validates :profile, presence: true, json: { schema:
|
79
|
-
end
|
80
|
-
```
|
90
|
+
validates :profile, presence: true, json: { schema: lambda { dynamic_profile_schema } } # `schema: :dynamic_profile_schema` would also work
|
81
91
|
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
class User < ActiveRecord::Base
|
86
|
-
# Constants
|
87
|
-
PROFILE_JSON_SCHEMA = {
|
88
|
-
type: 'object',
|
89
|
-
:'$schema' => 'http://json-schema.org/draft-03/schema',
|
90
|
-
properties: {
|
91
|
-
city: { type: 'string', required: false },
|
92
|
-
country: { type: 'string', required: true }
|
93
|
-
}
|
94
|
-
}
|
95
|
-
|
96
|
-
# Validations
|
97
|
-
validates :profile, presence: true, json: { schema: PROFILE_JSON_SCHEMA }
|
92
|
+
def dynamic_profile_schema
|
93
|
+
admin? ? PROFILE_ADMIN_JSON_SCHEMA : PROFILE_REGULAR_JSON_SCHEMA
|
94
|
+
end
|
98
95
|
end
|
99
96
|
```
|
100
97
|
|
101
|
-
|
98
|
+
##### Message
|
102
99
|
|
103
|
-
|
104
|
-
|
105
|
-
# Constants
|
106
|
-
PROFILE_JSON_SCHEMA = '{
|
107
|
-
"type": "object",
|
108
|
-
"$schema": "http://json-schema.org/draft-03/schema",
|
109
|
-
"properties": {
|
110
|
-
"city": { "type": "string", "required": false },
|
111
|
-
"country": { "type": "string", "required": true }
|
112
|
-
}
|
113
|
-
}'
|
100
|
+
Like any other ActiveModel validation, you can specify either a `Symbol` or
|
101
|
+
`String` value for the `:message` option. The default value is `:invalid_json`.
|
114
102
|
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
###### A lambda that will get evaluated in the context of the validated record
|
121
|
-
|
122
|
-
The lambda must return a valid value for the `:schema` option (file path, JSON `String` or Ruby `Hash`).
|
103
|
+
However, you can also specify a `Proc` that returns an array of errors. The
|
104
|
+
`Proc` will be called with a single argument — an array of errors returned by
|
105
|
+
the JSON schema validator. So, if you’d like to add each of these errors as
|
106
|
+
a first-level error for the record, you can do this:
|
123
107
|
|
124
108
|
```ruby
|
125
109
|
class User < ActiveRecord::Base
|
126
|
-
# Constants
|
127
|
-
PROFILE_REGULAR_JSON_SCHEMA = Rails.root.join('config', 'schemas', 'profile.json_schema').to_s
|
128
|
-
PROFILE_ADMIN_JSON_SCHEMA = Rails.root.join('config', 'schemas', 'profile_admin.json_schema').to_s
|
129
|
-
|
130
110
|
# Validations
|
131
|
-
validates :profile, presence: true, json: {
|
132
|
-
|
133
|
-
def dynamic_profile_schema
|
134
|
-
admin? ? PROFILE_ADMIN_JSON_SCHEMA : PROFILE_REGULAR_JSON_SCHEMA
|
135
|
-
end
|
111
|
+
validates :profile, presence: true, json: { message: ->(errors) { errors }, schema: 'foo.json_schema' }
|
136
112
|
end
|
113
|
+
|
114
|
+
user = User.new.tap(&:valid?)
|
115
|
+
user.errors.full_messages
|
116
|
+
# => [
|
117
|
+
# 'The property '#/email' of type Fixnum did not match the following type: string in schema 2d44293f-cd9d-5dca-8a6a-fb9db1de722b#',
|
118
|
+
# 'The property '#/full_name' of type Fixnum did not match the following type: string in schema 2d44293f-cd9d-5dca-8a6a-fb9db1de722b#',
|
119
|
+
# ]
|
137
120
|
```
|
138
121
|
|
139
122
|
## License
|
140
123
|
|
141
124
|
`ActiveRecord::JSONValidator` is © 2013-2015 [Mirego](http://www.mirego.com) and may be freely distributed under the [New BSD license](http://opensource.org/licenses/BSD-3-Clause). See the [`LICENSE.md`](https://github.com/mirego/activerecord_json_validator/blob/master/LICENSE.md) file.
|
142
125
|
|
126
|
+
The tree logo is based on [this lovely icon](http://thenounproject.com/term/tree/51004/) by [Sara Quintana](http://thenounproject.com/sara.quintana.75), from The Noun Project. Used under a [Creative Commons BY 3.0](http://creativecommons.org/licenses/by/3.0/) license.
|
127
|
+
|
143
128
|
## About Mirego
|
144
129
|
|
145
130
|
[Mirego](http://mirego.com) is a team of passionate people who believe that work is a place where you can innovate and have fun. We're a team of [talented people](http://life.mirego.com) who imagine and build beautiful Web and mobile applications. We come together to share ideas and [change the world](http://mirego.org).
|
@@ -7,18 +7,7 @@ class JsonValidator < ActiveModel::EachValidator
|
|
7
7
|
|
8
8
|
super
|
9
9
|
|
10
|
-
|
11
|
-
if options[:class]
|
12
|
-
inject_setter_method(options[:class], @attributes)
|
13
|
-
|
14
|
-
# Rails 4.0 and below calls a `#setup` method
|
15
|
-
elsif !respond_to?(:setup)
|
16
|
-
class_eval do
|
17
|
-
define_method :setup do |model|
|
18
|
-
inject_setter_method(model, @attributes)
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
10
|
+
inject_setter_method(options[:class], @attributes)
|
22
11
|
end
|
23
12
|
|
24
13
|
# Validate the JSON value with a JSON schema path or String
|
@@ -30,7 +19,9 @@ class JsonValidator < ActiveModel::EachValidator
|
|
30
19
|
return if errors.empty? && record.send(:"#{attribute}_invalid_json").blank?
|
31
20
|
|
32
21
|
# Add error message to the attribute
|
33
|
-
|
22
|
+
message(errors).each do |error|
|
23
|
+
record.errors.add(attribute, error, value: value)
|
24
|
+
end
|
34
25
|
end
|
35
26
|
|
36
27
|
protected
|
@@ -72,4 +63,13 @@ protected
|
|
72
63
|
return value if value.is_a?(String)
|
73
64
|
::ActiveSupport::JSON.encode(value)
|
74
65
|
end
|
66
|
+
|
67
|
+
def message(errors)
|
68
|
+
message = options.fetch(:message)
|
69
|
+
|
70
|
+
case message
|
71
|
+
when Proc then [message.call(errors)].flatten if message.is_a?(Proc)
|
72
|
+
else [message]
|
73
|
+
end
|
74
|
+
end
|
75
75
|
end
|
data/spec/json_validator_spec.rb
CHANGED
@@ -86,6 +86,21 @@ describe JsonValidator do
|
|
86
86
|
|
87
87
|
specify { validate_each! }
|
88
88
|
end
|
89
|
+
|
90
|
+
context 'with multiple error messages' do
|
91
|
+
let(:options) { { attributes: [attribute], message: message, options: { strict: true } } }
|
92
|
+
let(:message) { ->(errors) { errors.to_a } }
|
93
|
+
|
94
|
+
before do
|
95
|
+
expect(validator_errors).to receive(:empty?).and_return(false)
|
96
|
+
expect(validator_errors).to receive(:to_a).and_return(%i(first_error second_error))
|
97
|
+
expect(record).not_to receive(:"#{attribute}_invalid_json")
|
98
|
+
expect(record_errors).to receive(:add).with(attribute, :first_error, value: value)
|
99
|
+
expect(record_errors).to receive(:add).with(attribute, :second_error, value: value)
|
100
|
+
end
|
101
|
+
|
102
|
+
specify { validate_each! }
|
103
|
+
end
|
89
104
|
end
|
90
105
|
|
91
106
|
describe :schema do
|
@@ -152,4 +167,21 @@ describe JsonValidator do
|
|
152
167
|
it { expect(validatable_value).to eql(value) }
|
153
168
|
end
|
154
169
|
end
|
170
|
+
|
171
|
+
describe :message do
|
172
|
+
let(:validator) { JsonValidator.new(options) }
|
173
|
+
let(:options) { { attributes: [:foo], message: message_option } }
|
174
|
+
let(:message) { validator.send(:message, errors) }
|
175
|
+
let(:errors) { %i(first_error second_error) }
|
176
|
+
|
177
|
+
context 'with Symbol message' do
|
178
|
+
let(:message_option) { :invalid_json }
|
179
|
+
it { expect(message).to eql([:invalid_json]) }
|
180
|
+
end
|
181
|
+
|
182
|
+
context 'with String value' do
|
183
|
+
let(:message_option) { ->(errors) { errors } }
|
184
|
+
it { expect(message).to eql(%i(first_error second_error)) }
|
185
|
+
end
|
186
|
+
end
|
155
187
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: activerecord_json_validator
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Rémi Prévost
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-05-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -148,7 +148,7 @@ dependencies:
|
|
148
148
|
requirements:
|
149
149
|
- - ">="
|
150
150
|
- !ruby/object:Gem::Version
|
151
|
-
version: 4.
|
151
|
+
version: 4.2.0
|
152
152
|
- - "<"
|
153
153
|
- !ruby/object:Gem::Version
|
154
154
|
version: '5'
|
@@ -158,7 +158,7 @@ dependencies:
|
|
158
158
|
requirements:
|
159
159
|
- - ">="
|
160
160
|
- !ruby/object:Gem::Version
|
161
|
-
version: 4.
|
161
|
+
version: 4.2.0
|
162
162
|
- - "<"
|
163
163
|
- !ruby/object:Gem::Version
|
164
164
|
version: '5'
|
@@ -179,7 +179,6 @@ files:
|
|
179
179
|
- README.md
|
180
180
|
- Rakefile
|
181
181
|
- activerecord_json_validator.gemspec
|
182
|
-
- gemfiles/Gemfile.activerecord-4.1.x
|
183
182
|
- gemfiles/Gemfile.activerecord-4.2.x
|
184
183
|
- lib/active_record/json_validator/validator.rb
|
185
184
|
- lib/active_record/json_validator/version.rb
|
@@ -211,7 +210,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
211
210
|
version: '0'
|
212
211
|
requirements: []
|
213
212
|
rubyforge_project:
|
214
|
-
rubygems_version: 2.
|
213
|
+
rubygems_version: 2.4.5
|
215
214
|
signing_key:
|
216
215
|
specification_version: 4
|
217
216
|
summary: ActiveRecord::JSONValidator makes it easy to validate JSON attributes with
|