adequate_errors 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +16 -1
- data/LICENSE.txt +9 -0
- data/README.md +90 -17
- data/adequate_errors.gemspec +5 -1
- data/lib/adequate_errors/errors.rb +14 -1
- data/lib/adequate_errors/nested_error.rb +30 -0
- data/lib/adequate_errors/version.rb +1 -1
- metadata +22 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1424b1f08a935abadf39c414affcef49d6531a9e
|
4
|
+
data.tar.gz: 40cc4ff506d51660af10a69b995f9b36d0c03dad
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8a3ffd1f57440d0d716e4af3759e892a4cb67a8f9b79160af4a60d854a9f49ad464ef11759ee7ef6cfcf0d9094d452ca972af5f79fdc098d0771682996a434fb
|
7
|
+
data.tar.gz: fd881d54b1ed4afe2d1a0fa0c73162d46658cab1312d12c43cf36175c34c55cbafb5a3b39e349b5b7a0c13d5e6ef289bbcbf195fa9eaaacdf40d878d7c5288f7
|
data/Gemfile.lock
CHANGED
@@ -16,10 +16,24 @@ GEM
|
|
16
16
|
tzinfo (~> 1.1)
|
17
17
|
builder (3.2.3)
|
18
18
|
concurrent-ruby (1.0.5)
|
19
|
+
diff-lcs (1.3)
|
19
20
|
i18n (0.9.1)
|
20
21
|
concurrent-ruby (~> 1.0)
|
21
22
|
minitest (5.10.3)
|
22
23
|
rake (10.5.0)
|
24
|
+
rspec (3.7.0)
|
25
|
+
rspec-core (~> 3.7.0)
|
26
|
+
rspec-expectations (~> 3.7.0)
|
27
|
+
rspec-mocks (~> 3.7.0)
|
28
|
+
rspec-core (3.7.0)
|
29
|
+
rspec-support (~> 3.7.0)
|
30
|
+
rspec-expectations (3.7.0)
|
31
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
32
|
+
rspec-support (~> 3.7.0)
|
33
|
+
rspec-mocks (3.7.0)
|
34
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
35
|
+
rspec-support (~> 3.7.0)
|
36
|
+
rspec-support (3.7.0)
|
23
37
|
thread_safe (0.3.6)
|
24
38
|
tzinfo (1.2.4)
|
25
39
|
thread_safe (~> 0.1)
|
@@ -32,6 +46,7 @@ DEPENDENCIES
|
|
32
46
|
builder (~> 3.2.3)
|
33
47
|
bundler (~> 1.16.a)
|
34
48
|
rake (~> 10.0)
|
49
|
+
rspec (~> 3.7)
|
35
50
|
|
36
51
|
BUNDLED WITH
|
37
|
-
1.16.0
|
52
|
+
1.16.0
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2017 LULALALA
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
6
|
+
|
7
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
8
|
+
|
9
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
CHANGED
@@ -2,7 +2,8 @@
|
|
2
2
|
|
3
3
|
Overcoming limitation of Rails model errors API:
|
4
4
|
|
5
|
-
*
|
5
|
+
* fine-grained `where` query
|
6
|
+
* object-oriented Error object
|
6
7
|
* turn off message's attribute prefix.
|
7
8
|
* lazy evaluation of messages
|
8
9
|
|
@@ -10,50 +11,122 @@ Overcoming limitation of Rails model errors API:
|
|
10
11
|
|
11
12
|
Rails errors API is simple to use, but can be inadequate when coping with more complex requirements.
|
12
13
|
|
14
|
+
Examples of how existing Rails API is limiting are listed here: http://lulalala.logdown.com/posts/2909828-adequate-errors
|
15
|
+
|
13
16
|
The existing API was originally a collection of message strings without much meta data, making it very restrictive. Though `details` hash was added later for storing meta information, many fundamental issues can not be fixed without altering the API and the architecture.
|
14
17
|
|
15
18
|
This gem redesigned the API, placing it in its own object, co-existing with existing Rails API. Thus nothing will break, allowing you to migrate the code one at a time.
|
16
19
|
|
20
|
+
|
17
21
|
## Quick start
|
18
22
|
|
19
|
-
To access the AdequateErrors
|
23
|
+
To access the AdequateErrors, call:
|
20
24
|
|
21
25
|
model.errors.adequate
|
22
26
|
|
23
|
-
From this object, many convenience methods are provided
|
27
|
+
From this `Errors` object, many convenience methods are provided:
|
28
|
+
|
29
|
+
Return an array of AdequateErrors::Error objects, matching a condition:
|
24
30
|
|
25
31
|
model.errors.adequate.where(attribute:'title', :type => :too_short, length: 5)
|
26
32
|
|
27
|
-
|
33
|
+
Prints out each error's full message one by one:
|
28
34
|
|
29
35
|
model.errors.adequate.each {|error| puts error.message }
|
30
36
|
|
31
|
-
|
37
|
+
Return an array of all message strings:
|
32
38
|
|
33
39
|
model.errors.adequate.messages
|
34
40
|
|
35
|
-
|
41
|
+
## `Error` object
|
42
|
+
|
43
|
+
An `Error` object provides the following:
|
44
|
+
|
45
|
+
* `attribute` is the model attribute the error belongs to.
|
46
|
+
* `type` is the error type.
|
47
|
+
* `options` is a hash containing additional information such as `:count` or `:length`.
|
48
|
+
* `message` is the error message. It is full message by design.
|
49
|
+
|
50
|
+
## `where` query
|
51
|
+
|
52
|
+
Use `where` method to find errors matching different conditions. An array of Error objects are returned.
|
53
|
+
|
54
|
+
To find all errors of `title` attribute, pass it with `:attribute` key:
|
55
|
+
|
56
|
+
model.errors.adequate.where(:attribute => :title)
|
57
|
+
|
58
|
+
You can also filter by error type using the `:type` key:
|
59
|
+
|
60
|
+
model.errors.adequate.where(:type => :too_short)
|
61
|
+
|
62
|
+
Custom attributes passed can also be used to filter errors:
|
63
|
+
|
64
|
+
model.errors.adequate.where(:attribute => :title, :type => :too_short, length: 5)
|
65
|
+
|
66
|
+
|
67
|
+
## `include?`
|
68
|
+
|
69
|
+
Same as Rails, provide the attribute name to see if that attribute has errors.
|
36
70
|
|
37
|
-
##
|
71
|
+
## `add`, `delete`
|
38
72
|
|
39
|
-
|
73
|
+
Same as built-in counterparts.
|
74
|
+
|
75
|
+
## `import`
|
76
|
+
|
77
|
+
For copying an error from inner model to outer model, such as form object. This ensures lazy message generation can still reference all information that the inner error has.
|
78
|
+
|
79
|
+
```ruby
|
80
|
+
inner_model.errors.adequate.each do |error|
|
81
|
+
errors.adequate.import(error)
|
82
|
+
end
|
83
|
+
```
|
84
|
+
|
85
|
+
Attribute and type can be overriden in case when attribute does not exist in the outer model:
|
86
|
+
|
87
|
+
```ruby
|
88
|
+
errors.adequate.import(error, attribute: :foo, type: :bar)
|
89
|
+
```
|
90
|
+
|
91
|
+
## Message and I18n
|
92
|
+
|
93
|
+
Error message strings reside under `adequate_errors` namespace. Unlike Rails, there is no global prefixing of attributes. Instead, `%{attribute}` is added into each error message when needed.
|
94
|
+
|
95
|
+
```yaml
|
96
|
+
en:
|
97
|
+
adequate_errors:
|
98
|
+
messages:
|
99
|
+
invalid: "%{attribute} is invalid"
|
100
|
+
inclusion: "%{attribute} is not included in the list"
|
101
|
+
exclusion: "%{attribute} is reserved"
|
102
|
+
```
|
103
|
+
|
104
|
+
This allows omission of attribute prefix. You no longer need to attach errors to `:base` for that purpose.
|
105
|
+
|
106
|
+
Built-in Rails error types already have been prefixed out of the box, but error types from other gems have to be handled manually by copying entries to the `adequate_errors` namespace and prefixing with attributes.
|
40
107
|
|
41
108
|
Error messages are evaluated lazily, which means it can be rendered in a different locale at view rendering time.
|
42
109
|
|
43
|
-
The messages in the locale file are looked up in its own `adequate_errors` namespace, for example:
|
44
110
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
111
|
+
## `messages`
|
112
|
+
|
113
|
+
Returns an array of all messages.
|
114
|
+
|
115
|
+
model.errors.adequate.messages
|
116
|
+
|
117
|
+
## `messages_for`
|
49
118
|
|
50
|
-
|
119
|
+
Returns an array of messages, filtered by conditions. Method argument is the same as `where`.
|
120
|
+
|
121
|
+
model.errors.adequate.messages_for(:attribute => :title, :type => :too_short, length: 5)
|
122
|
+
|
123
|
+
## Full documentation
|
51
124
|
|
52
|
-
|
125
|
+
http://www.rubydoc.info/github/lulalala/adequate_errors
|
53
126
|
|
54
|
-
##
|
127
|
+
## Note
|
55
128
|
|
56
|
-
Deprecated methods such as `[]=`, `get` and `set` are not
|
129
|
+
Calls to Rails' API are synced to AdequateErrors object, but not in reverse. Deprecated methods such as `[]=`, `get` and `set` are not sync'ed however.
|
57
130
|
|
58
131
|
The gem is developed from ActiveModel 5.1, but it should work with earlier versions.
|
59
132
|
|
data/adequate_errors.gemspec
CHANGED
@@ -6,10 +6,11 @@ require "adequate_errors/version"
|
|
6
6
|
Gem::Specification.new do |spec|
|
7
7
|
spec.name = "adequate_errors"
|
8
8
|
spec.version = AdequateErrors::VERSION
|
9
|
+
spec.license = 'MIT'
|
9
10
|
spec.authors = ["lulalala"]
|
10
11
|
spec.email = ["mark@goodlife.tw"]
|
11
12
|
|
12
|
-
spec.summary = %q{
|
13
|
+
spec.summary = %q{Overcoming limitation of Rails model errors API}
|
13
14
|
spec.homepage = "https://github.com/lulalala/adequate_errors/"
|
14
15
|
|
15
16
|
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
@@ -19,9 +20,12 @@ Gem::Specification.new do |spec|
|
|
19
20
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
20
21
|
spec.require_paths = ["lib"]
|
21
22
|
|
23
|
+
spec.required_ruby_version = '>= 2.0.0'
|
24
|
+
|
22
25
|
spec.add_dependency "activemodel"
|
23
26
|
|
24
27
|
spec.add_development_dependency "bundler", "~> 1.16.a"
|
25
28
|
spec.add_development_dependency "rake", "~> 10.0"
|
26
29
|
spec.add_development_dependency "builder", "~> 3.2.3"
|
30
|
+
spec.add_development_dependency "rspec", "~> 3.7"
|
27
31
|
end
|
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'active_model/errors'
|
2
2
|
require 'forwardable'
|
3
3
|
require 'adequate_errors/error'
|
4
|
+
require 'adequate_errors/nested_error'
|
4
5
|
|
5
6
|
module AdequateErrors
|
6
7
|
# Collection of {Error} objects.
|
@@ -45,6 +46,18 @@ module AdequateErrors
|
|
45
46
|
@errors.append(::AdequateErrors::Error.new(@base, attribute, type, options))
|
46
47
|
end
|
47
48
|
|
49
|
+
# Imports error
|
50
|
+
# For copying nested model's errors back to base model.
|
51
|
+
# The provided error will be wrapped, and its attribute/type will be copied across.
|
52
|
+
# If attribute or type needs to be overriden, use `override_options`.
|
53
|
+
#
|
54
|
+
# @param override_options [Hash]
|
55
|
+
# @option override_options [Symbol] :attribute Override the attribute the error belongs to
|
56
|
+
# @option override_options [Symbol] :type Override type of the error.
|
57
|
+
def import(error, override_options = {})
|
58
|
+
@errors.append(::AdequateErrors::NestedError.new(@base, error, override_options))
|
59
|
+
end
|
60
|
+
|
48
61
|
# @return [Array(String)] all error messages
|
49
62
|
def messages
|
50
63
|
@errors.map(&:message)
|
@@ -60,7 +73,7 @@ module AdequateErrors
|
|
60
73
|
# @param params [Hash]
|
61
74
|
# filter condition
|
62
75
|
# The most common keys are +:attribute+ and +:type+,
|
63
|
-
# but other custom keys given during {#add} can also be used.
|
76
|
+
# but other custom keys given during {Errors#add} can also be used.
|
64
77
|
# If params is empty, all errors are returned.
|
65
78
|
# @option params [Symbol] :attribute Filtering on attribute the error belongs to
|
66
79
|
# @option params [Symbol] :type Filter on type of error
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module AdequateErrors
|
2
|
+
# Represents one single error
|
3
|
+
# @!attribute [r] base
|
4
|
+
# @return [ActiveModel::Base] the object which the error belongs to
|
5
|
+
# @!attribute [r] attribute
|
6
|
+
# @return [Symbol] attribute of the object which the error belongs to
|
7
|
+
# @!attribute [r] type
|
8
|
+
# @return [Symbol] error's type
|
9
|
+
# @!attribute [r] options
|
10
|
+
# @return [Hash] additional options
|
11
|
+
# @!attribute [r] inner_error
|
12
|
+
# @return [Error] inner error
|
13
|
+
class NestedError < Error
|
14
|
+
def initialize(base, inner_error, override_options = {})
|
15
|
+
@base = base
|
16
|
+
@inner_error = inner_error
|
17
|
+
@attribute = override_options.fetch(:attribute) { inner_error.attribute }
|
18
|
+
@type = override_options.fetch(:type) { inner_error.type }
|
19
|
+
@options = inner_error.options
|
20
|
+
end
|
21
|
+
|
22
|
+
attr_reader :inner_error
|
23
|
+
|
24
|
+
# Full message of the error.
|
25
|
+
# Sourced from inner error.
|
26
|
+
def message
|
27
|
+
@inner_error.message
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: adequate_errors
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- lulalala
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-12-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activemodel
|
@@ -66,6 +66,20 @@ dependencies:
|
|
66
66
|
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: 3.2.3
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rspec
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '3.7'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '3.7'
|
69
83
|
description:
|
70
84
|
email:
|
71
85
|
- mark@goodlife.tw
|
@@ -77,6 +91,7 @@ files:
|
|
77
91
|
- ".yardopts"
|
78
92
|
- Gemfile
|
79
93
|
- Gemfile.lock
|
94
|
+
- LICENSE.txt
|
80
95
|
- README.md
|
81
96
|
- Rakefile
|
82
97
|
- adequate_errors.gemspec
|
@@ -87,9 +102,11 @@ files:
|
|
87
102
|
- lib/adequate_errors/errors.rb
|
88
103
|
- lib/adequate_errors/interceptor.rb
|
89
104
|
- lib/adequate_errors/locale/en.yml
|
105
|
+
- lib/adequate_errors/nested_error.rb
|
90
106
|
- lib/adequate_errors/version.rb
|
91
107
|
homepage: https://github.com/lulalala/adequate_errors/
|
92
|
-
licenses:
|
108
|
+
licenses:
|
109
|
+
- MIT
|
93
110
|
metadata: {}
|
94
111
|
post_install_message:
|
95
112
|
rdoc_options: []
|
@@ -99,7 +116,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
99
116
|
requirements:
|
100
117
|
- - ">="
|
101
118
|
- !ruby/object:Gem::Version
|
102
|
-
version:
|
119
|
+
version: 2.0.0
|
103
120
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
104
121
|
requirements:
|
105
122
|
- - ">="
|
@@ -110,5 +127,5 @@ rubyforge_project:
|
|
110
127
|
rubygems_version: 2.6.13
|
111
128
|
signing_key:
|
112
129
|
specification_version: 4
|
113
|
-
summary:
|
130
|
+
summary: Overcoming limitation of Rails model errors API
|
114
131
|
test_files: []
|