Commit 472ae3f
committed
Validations: Decode response with format
First, extract the `ActiveResource::ErrorsParser` class along with the
internal `ActiveResource::ActiveModelErrorsParser` class (that inherits
from `ActiveResource::ErrorsParser`). Configure a `errors_parser`
resource class attribute to control how errors are extracted from
decoded payloads.
The `errors_parser` pattern and the `ErrorsParser` class are directly
inspired by the `collection_parser` and `ActiveResource::Collection`
class.
ActiveResource::ErrorsParser
---
`ActiveResource::ErrorsParser` is a wrapper to handle parsing responses in
response to invalid requests that do not directly map to Active Model
error conventions.
You can define a custom class that inherits from
`ActiveResource::ErrorsParser` in order to to set the elements instance.
The initialize method will receive the `ActiveResource::Formats` parsed
result and should set `@messages`.
Consider a `POST /posts.json` request that results in a `422
Unprocessable Content` response with the following `application/json`
body:
```json
{
"error": true,
"messages": ["Something went wrong", "Title can't be blank"]
}
```
A Post class can be setup to handle it with:
```ruby
class Post < ActiveResource::Base
self.errors_parser = PostErrorsParser
end
```
A custom `ActiveResource::ErrorsParser` instance's `messages` method
should return a mapping of attribute names (or `"base"`) to arrays of
error message strings:
```ruby
class PostErrorsParser < ActiveResource::ErrorsParser
def initialize(parsed)
@messages = Hash.new { |hash, attr_name| hash[attr_name] = [] }
parsed["messages"].each do |message|
if message.starts_with?("Title")
@messages["title"] << message
else
@messages["base"] << message
end
end
end
end
```
When the `POST /posts.json` request is submitted by calling `save`, the
errors are parsed from the body and assigned to the Post instance's
`errors` object:
```ruby
post = Post.new(title: "")
post.save # => false
post.valid? # => false
post.errors.messages_for(:base) # => ["Something went wrong"]
post.errors.messages_for(:title) # => ["Title can't be blank"]
```
If the custom `ActiveResource::ErrorsParser` instance's `messages`
method returns an array of error message strings, Active Resource will
try to infer the attribute name based on the contents of the error
message string. If an error starts with a known attribute name, Active
Resource will add the message to that attribute's error messages. If a
known attribute name cannot be inferred, the error messages will be
added to the `:base` errors:
```ruby
class PostErrorsParser < ActiveResource::ErrorsParser
def initialize(parsed)
parsed["messages"]
end
end
```
Changes to ActiveResource::Formats::JsonFormat and ActiveResource::Formats::XmlFormat
---
This commit also adds the `remove_root = true` optional argument to the
`JsonFormat` and `XmlFormat` modules' `#decode` method. The name and
positional argument style draw direct inspiration from the
`ActiveResource::Base#load` method's optional `remove_root = true`
argument.
The change is in support of replacing internal calls to `Hash.from_xml`
and `ActiveSupport::JSON.decode`. Those method invocations are replaced
with the appropriate format's `.decode` method.
This commit changes the `ActiveResource::Errors#from_xml` and
`ActiveResource::Errors#from_json` methods to be implemented in terms of
a new `#from_body` method. The `#from_body` method is flexible enough to
support any application-side custom formats, while internally flexible
enough to rely on the built-in JSON and XML formats.1 parent 62b941e commit 472ae3f
4 files changed
Lines changed: 233 additions & 16 deletions
File tree
- lib/active_resource
- formats
- test/cases
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
19 | 19 | | |
20 | 20 | | |
21 | 21 | | |
22 | | - | |
| 22 | + | |
23 | 23 | | |
24 | | - | |
| 24 | + | |
| 25 | + | |
25 | 26 | | |
26 | 27 | | |
27 | 28 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
19 | 19 | | |
20 | 20 | | |
21 | 21 | | |
22 | | - | |
23 | | - | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
24 | 25 | | |
25 | 26 | | |
26 | 27 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
54 | 54 | | |
55 | 55 | | |
56 | 56 | | |
57 | | - | |
58 | | - | |
59 | | - | |
| 57 | + | |
60 | 58 | | |
61 | 59 | | |
62 | 60 | | |
63 | 61 | | |
64 | | - | |
65 | | - | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
66 | 174 | | |
67 | 175 | | |
68 | 176 | | |
| |||
93 | 201 | | |
94 | 202 | | |
95 | 203 | | |
| 204 | + | |
| 205 | + | |
| 206 | + | |
| 207 | + | |
| 208 | + | |
| 209 | + | |
| 210 | + | |
| 211 | + | |
| 212 | + | |
| 213 | + | |
| 214 | + | |
| 215 | + | |
| 216 | + | |
96 | 217 | | |
97 | 218 | | |
98 | 219 | | |
| |||
123 | 244 | | |
124 | 245 | | |
125 | 246 | | |
126 | | - | |
127 | | - | |
128 | | - | |
129 | | - | |
130 | | - | |
131 | | - | |
| 247 | + | |
132 | 248 | | |
133 | 249 | | |
134 | 250 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
111 | 111 | | |
112 | 112 | | |
113 | 113 | | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
114 | 184 | | |
115 | 185 | | |
116 | 186 | | |
117 | 187 | | |
118 | 188 | | |
119 | | - | |
| 189 | + | |
120 | 190 | | |
121 | 191 | | |
122 | 192 | | |
| |||
126 | 196 | | |
127 | 197 | | |
128 | 198 | | |
| 199 | + | |
| 200 | + | |
| 201 | + | |
| 202 | + | |
| 203 | + | |
| 204 | + | |
| 205 | + | |
| 206 | + | |
| 207 | + | |
| 208 | + | |
| 209 | + | |
| 210 | + | |
| 211 | + | |
| 212 | + | |
| 213 | + | |
| 214 | + | |
| 215 | + | |
| 216 | + | |
| 217 | + | |
| 218 | + | |
| 219 | + | |
| 220 | + | |
| 221 | + | |
| 222 | + | |
| 223 | + | |
| 224 | + | |
| 225 | + | |
| 226 | + | |
| 227 | + | |
129 | 228 | | |
0 commit comments