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 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'