activerecord_json_validator 0.5.1 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e122734c159cf841ab43d38bdc6efd2e4d554605
4
- data.tar.gz: 96c99ba0cde8902483245991ccab6b2bc03870d6
3
+ metadata.gz: 53b4aea1bc7007643f31d936e12b78804f96ab9f
4
+ data.tar.gz: 70f49f4c9bc9930dec7cdaede3d612cd387fd00b
5
5
  SHA512:
6
- metadata.gz: 3d060208f9aebadac25bd9b6c3a72db71eb689e775c9a3be343c45f05d0e5d7a5e36c4b91a6341b2823c3b6b7bce7a2c2efe7a3b1972a0b4d97a618b3da2a759
7
- data.tar.gz: 5aff819411acfe4a894c3e5f4d6422f7ffdef61c78cf07b8551025c8b7d0ab6794ed51283e9d90a1f4c479c32fe65622e2c548fd526ef7e2f0059ed560d04a72
6
+ metadata.gz: c360ce94176ec1471287f51ad23224a4cd6fe8caeee92d62df27d04df6fa518af18cd92969167282a6e6886aca46ec0221196e825db5ad8758f657165c85f4c9
7
+ data.tar.gz: f1586c5cca10f3eef4dbb31d602b29f633daf2a778557642816026092db2bfc9c3ed54b672c39e9835bea877280129580d30bb55d9754a3ed47c70f6b2cac589
@@ -6,7 +6,6 @@ rvm:
6
6
 
7
7
  gemfile:
8
8
  - gemfiles/Gemfile.activerecord-4.2.x
9
- - gemfiles/Gemfile.activerecord-4.1.x
10
9
 
11
10
  sudo: false
12
11
 
data/README.md CHANGED
@@ -1,9 +1,15 @@
1
- # ActiveRecord::JSONValidator
2
-
3
- `ActiveRecord::JSONValidator` makes it easy to validate JSON attributes against a JSON schema.
4
-
5
- [![Gem Version](http://img.shields.io/gem/v/activerecord_json_validator.svg)](https://rubygems.org/gems/activerecord_json_validator)
6
- [![Build Status](http://img.shields.io/travis/mirego/activerecord_json_validator.svg)](https://travis-ci.org/mirego/activerecord_json_validator)
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-03/schema",
29
+ "$schema": "http://json-schema.org/draft-04/schema",
24
30
  "properties": {
25
- "city": { "type": "string", "required": false },
26
- "country": { "type": "string", "required": true }
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 **JSON schema option** section)
64
- | `:message` | The ActiveRecord message added to the record errors (default: `:invalid_json`)
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
- ##### JSON schema option
73
+ ##### Schema
67
74
 
68
- You can specify four kinds of value for the `:schema` option.
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
- ###### A path to a file containing a JSON schema
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
- PROFILE_JSON_SCHEMA = Rails.root.join('config', 'schemas', 'profile.json_schema').to_s
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: PROFILE_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
- ###### A Ruby `Hash` representing a JSON schema
83
-
84
- ```ruby
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
- ###### A plain JSON schema as a Ruby `String`
98
+ ##### Message
102
99
 
103
- ```ruby
104
- class User < ActiveRecord::Base
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
- # Validations
116
- validates :profile, presence: true, json: { schema: PROFILE_JSON_SCHEMA }
117
- end
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: { schema: lambda { dynamic_profile_schema } }
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).
@@ -28,5 +28,5 @@ Gem::Specification.new do |spec|
28
28
  spec.add_development_dependency 'rubocop', '~> 0.28'
29
29
 
30
30
  spec.add_dependency 'json-schema', '~> 2.5'
31
- spec.add_dependency 'activerecord', '>= 4.1.0', '< 5'
31
+ spec.add_dependency 'activerecord', '>= 4.2.0', '< 5'
32
32
  end
@@ -7,18 +7,7 @@ class JsonValidator < ActiveModel::EachValidator
7
7
 
8
8
  super
9
9
 
10
- # Rails 4.1 and above expose a `class` option
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
- record.errors.add(attribute, options.fetch(:message), value: value)
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
@@ -1,5 +1,5 @@
1
1
  module ActiveRecord
2
2
  module JSONValidator
3
- VERSION = '0.5.1'
3
+ VERSION = '1.0.0'
4
4
  end
5
5
  end
@@ -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.5.1
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-02-08 00:00:00.000000000 Z
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.1.0
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.1.0
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.2.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
@@ -1,5 +0,0 @@
1
- source 'https://rubygems.org'
2
-
3
- gemspec path: '../'
4
-
5
- gem 'activerecord', '~> 4.1'