her 1.0.1 → 1.0.2
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/.rubocop.yml +19 -1279
- data/.rubocop_todo.yml +232 -0
- data/README.md +16 -0
- data/her.gemspec +3 -2
- data/lib/her/api.rb +8 -7
- data/lib/her/collection.rb +2 -1
- data/lib/her/errors.rb +3 -1
- data/lib/her/json_api/model.rb +8 -12
- data/lib/her/middleware.rb +1 -1
- data/lib/her/middleware/accept_json.rb +1 -0
- data/lib/her/middleware/first_level_parse_json.rb +6 -5
- data/lib/her/middleware/json_api_parser.rb +6 -5
- data/lib/her/middleware/parse_json.rb +2 -1
- data/lib/her/middleware/second_level_parse_json.rb +6 -5
- data/lib/her/model/associations.rb +6 -6
- data/lib/her/model/associations/association.rb +7 -9
- data/lib/her/model/associations/association_proxy.rb +2 -3
- data/lib/her/model/associations/belongs_to_association.rb +1 -1
- data/lib/her/model/attributes.rb +6 -6
- data/lib/her/model/base.rb +2 -2
- data/lib/her/model/http.rb +1 -1
- data/lib/her/model/introspection.rb +5 -3
- data/lib/her/model/nested_attributes.rb +1 -1
- data/lib/her/model/orm.rb +9 -8
- data/lib/her/model/parse.rb +9 -12
- data/lib/her/model/paths.rb +3 -4
- data/lib/her/model/relation.rb +5 -4
- data/lib/her/version.rb +1 -1
- data/spec/api_spec.rb +3 -0
- data/spec/middleware/accept_json_spec.rb +1 -0
- data/spec/middleware/first_level_parse_json_spec.rb +2 -1
- data/spec/middleware/json_api_parser_spec.rb +1 -0
- data/spec/middleware/second_level_parse_json_spec.rb +1 -0
- data/spec/model/associations/association_proxy_spec.rb +1 -0
- data/spec/model/associations_spec.rb +4 -3
- data/spec/model/attributes_spec.rb +5 -3
- data/spec/model/callbacks_spec.rb +14 -15
- data/spec/model/dirty_spec.rb +1 -0
- data/spec/model/http_spec.rb +1 -0
- data/spec/model/introspection_spec.rb +3 -2
- data/spec/model/nested_attributes_spec.rb +1 -0
- data/spec/model/orm_spec.rb +22 -16
- data/spec/model/parse_spec.rb +3 -0
- data/spec/model/paths_spec.rb +1 -0
- data/spec/model/relation_spec.rb +3 -2
- data/spec/model/validations_spec.rb +1 -0
- data/spec/model_spec.rb +1 -0
- data/spec/support/extensions/array.rb +1 -0
- data/spec/support/extensions/hash.rb +1 -0
- metadata +12 -11
data/.rubocop_todo.yml
ADDED
@@ -0,0 +1,232 @@
|
|
1
|
+
# This configuration was generated by
|
2
|
+
# `rubocop --auto-gen-config`
|
3
|
+
# on 2018-05-16 14:33:11 -0300 using RuboCop version 0.54.0.
|
4
|
+
# The point is for the user to remove these configuration records
|
5
|
+
# one by one as the offenses are removed from the code base.
|
6
|
+
# Note that changes in the inspected code, or installation of new
|
7
|
+
# versions of RuboCop, may require this file to be generated again.
|
8
|
+
|
9
|
+
# Offense count: 2
|
10
|
+
# Configuration parameters: Include.
|
11
|
+
# Include: **/*.gemfile, **/Gemfile, **/gems.rb
|
12
|
+
Bundler/DuplicatedGem:
|
13
|
+
Exclude:
|
14
|
+
- 'Gemfile'
|
15
|
+
|
16
|
+
# Offense count: 1
|
17
|
+
Lint/EmptyWhen:
|
18
|
+
Exclude:
|
19
|
+
- 'lib/her/model/parse.rb'
|
20
|
+
|
21
|
+
# Offense count: 1
|
22
|
+
Lint/IneffectiveAccessModifier:
|
23
|
+
Exclude:
|
24
|
+
- 'lib/her/api.rb'
|
25
|
+
|
26
|
+
# Offense count: 6
|
27
|
+
# Cop supports --auto-correct.
|
28
|
+
# Configuration parameters: AllowUnusedKeywordArguments, IgnoreEmptyMethods.
|
29
|
+
Lint/UnusedMethodArgument:
|
30
|
+
Exclude:
|
31
|
+
- 'lib/her/api.rb'
|
32
|
+
- 'lib/her/model/associations/association.rb'
|
33
|
+
- 'lib/her/model/attributes.rb'
|
34
|
+
- 'lib/her/model/orm.rb'
|
35
|
+
- 'spec/model/attributes_spec.rb'
|
36
|
+
|
37
|
+
# Offense count: 1
|
38
|
+
# Configuration parameters: ContextCreatingMethods, MethodCreatingMethods.
|
39
|
+
Lint/UselessAccessModifier:
|
40
|
+
Exclude:
|
41
|
+
- 'lib/her/api.rb'
|
42
|
+
|
43
|
+
# Offense count: 10
|
44
|
+
Metrics/AbcSize:
|
45
|
+
Max: 38
|
46
|
+
|
47
|
+
# Offense count: 91
|
48
|
+
# Configuration parameters: CountComments, ExcludedMethods.
|
49
|
+
Metrics/BlockLength:
|
50
|
+
Max: 694
|
51
|
+
|
52
|
+
# Offense count: 4
|
53
|
+
Metrics/CyclomaticComplexity:
|
54
|
+
Max: 12
|
55
|
+
|
56
|
+
# Offense count: 10
|
57
|
+
# Configuration parameters: CountComments.
|
58
|
+
Metrics/MethodLength:
|
59
|
+
Max: 28
|
60
|
+
|
61
|
+
# Offense count: 1
|
62
|
+
# Configuration parameters: CountComments.
|
63
|
+
Metrics/ModuleLength:
|
64
|
+
Max: 106
|
65
|
+
|
66
|
+
# Offense count: 4
|
67
|
+
Metrics/PerceivedComplexity:
|
68
|
+
Max: 12
|
69
|
+
|
70
|
+
# Offense count: 4
|
71
|
+
Naming/MemoizedInstanceVariableName:
|
72
|
+
Exclude:
|
73
|
+
- 'lib/her/model/associations.rb'
|
74
|
+
- 'lib/her/model/attributes.rb'
|
75
|
+
- 'lib/her/model/relation.rb'
|
76
|
+
|
77
|
+
# Offense count: 7
|
78
|
+
# Configuration parameters: NamePrefix, NamePrefixBlacklist, NameWhitelist, MethodDefinitionMacros.
|
79
|
+
# NamePrefix: is_, has_, have_
|
80
|
+
# NamePrefixBlacklist: is_, has_, have_
|
81
|
+
# NameWhitelist: is_a?
|
82
|
+
# MethodDefinitionMacros: define_method, define_singleton_method
|
83
|
+
Naming/PredicateName:
|
84
|
+
Exclude:
|
85
|
+
- 'spec/**/*'
|
86
|
+
- 'lib/her/model/associations.rb'
|
87
|
+
- 'lib/her/model/attributes.rb'
|
88
|
+
- 'lib/her/model/base.rb'
|
89
|
+
- 'lib/her/model/deprecated_methods.rb'
|
90
|
+
|
91
|
+
# Offense count: 1
|
92
|
+
# Cop supports --auto-correct.
|
93
|
+
Performance/RegexpMatch:
|
94
|
+
Exclude:
|
95
|
+
- 'spec/support/macros/model_macros.rb'
|
96
|
+
|
97
|
+
# Offense count: 23
|
98
|
+
Style/Documentation:
|
99
|
+
Enabled: false
|
100
|
+
|
101
|
+
# Offense count: 21
|
102
|
+
# Cop supports --auto-correct.
|
103
|
+
Style/Encoding:
|
104
|
+
Enabled: false
|
105
|
+
|
106
|
+
# Offense count: 2
|
107
|
+
# Cop supports --auto-correct.
|
108
|
+
Style/ExpandPathArguments:
|
109
|
+
Exclude:
|
110
|
+
- 'her.gemspec'
|
111
|
+
- 'spec/spec_helper.rb'
|
112
|
+
|
113
|
+
# Offense count: 59
|
114
|
+
# Cop supports --auto-correct.
|
115
|
+
# Configuration parameters: EnforcedStyle.
|
116
|
+
# SupportedStyles: when_needed, always, never
|
117
|
+
Style/FrozenStringLiteralComment:
|
118
|
+
Enabled: false
|
119
|
+
|
120
|
+
# Offense count: 89
|
121
|
+
# Cop supports --auto-correct.
|
122
|
+
# Configuration parameters: EnforcedStyle, UseHashRocketsWithSymbolValues, PreferHashRocketsForNonAlnumEndingSymbols.
|
123
|
+
# SupportedStyles: ruby19, hash_rockets, no_mixed_keys, ruby19_no_mixed_keys
|
124
|
+
Style/HashSyntax:
|
125
|
+
Enabled: false
|
126
|
+
|
127
|
+
# Offense count: 6
|
128
|
+
# Cop supports --auto-correct.
|
129
|
+
Style/IfUnlessModifier:
|
130
|
+
Exclude:
|
131
|
+
- 'lib/her/json_api/model.rb'
|
132
|
+
- 'lib/her/model/associations/association_proxy.rb'
|
133
|
+
- 'lib/her/model/nested_attributes.rb'
|
134
|
+
- 'lib/her/model/orm.rb'
|
135
|
+
- 'lib/her/model/parse.rb'
|
136
|
+
|
137
|
+
# Offense count: 2
|
138
|
+
Style/MethodMissing:
|
139
|
+
Exclude:
|
140
|
+
- 'lib/her/model/associations/association_proxy.rb'
|
141
|
+
- 'lib/her/model/relation.rb'
|
142
|
+
|
143
|
+
# Offense count: 2
|
144
|
+
# Cop supports --auto-correct.
|
145
|
+
Style/MutableConstant:
|
146
|
+
Exclude:
|
147
|
+
- 'lib/her/model/http.rb'
|
148
|
+
- 'lib/her/version.rb'
|
149
|
+
|
150
|
+
# Offense count: 3
|
151
|
+
# Cop supports --auto-correct.
|
152
|
+
Style/PerlBackrefs:
|
153
|
+
Exclude:
|
154
|
+
- 'lib/her/model/paths.rb'
|
155
|
+
|
156
|
+
# Offense count: 1
|
157
|
+
# Cop supports --auto-correct.
|
158
|
+
# Configuration parameters: EnforcedStyle, AllowInnerSlashes.
|
159
|
+
# SupportedStyles: slashes, percent_r, mixed
|
160
|
+
Style/RegexpLiteral:
|
161
|
+
Exclude:
|
162
|
+
- 'lib/her/model/paths.rb'
|
163
|
+
|
164
|
+
# Offense count: 1
|
165
|
+
# Cop supports --auto-correct.
|
166
|
+
# Configuration parameters: ConvertCodeThatCanStartToReturnNil, Whitelist.
|
167
|
+
# Whitelist: present?, blank?, presence, try
|
168
|
+
Style/SafeNavigation:
|
169
|
+
Exclude:
|
170
|
+
- 'spec/model/orm_spec.rb'
|
171
|
+
|
172
|
+
# Offense count: 1
|
173
|
+
# Cop supports --auto-correct.
|
174
|
+
# Configuration parameters: EnforcedStyle.
|
175
|
+
# SupportedStyles: use_perl_names, use_english_names
|
176
|
+
Style/SpecialGlobalVars:
|
177
|
+
Exclude:
|
178
|
+
- 'her.gemspec'
|
179
|
+
|
180
|
+
# Offense count: 1613
|
181
|
+
# Cop supports --auto-correct.
|
182
|
+
# Configuration parameters: EnforcedStyle, ConsistentQuotesInMultiline.
|
183
|
+
# SupportedStyles: single_quotes, double_quotes
|
184
|
+
Style/StringLiterals:
|
185
|
+
Enabled: false
|
186
|
+
|
187
|
+
# Offense count: 1
|
188
|
+
# Cop supports --auto-correct.
|
189
|
+
# Configuration parameters: EnforcedStyle.
|
190
|
+
# SupportedStyles: single_quotes, double_quotes
|
191
|
+
Style/StringLiteralsInInterpolation:
|
192
|
+
Exclude:
|
193
|
+
- 'lib/her/model/introspection.rb'
|
194
|
+
|
195
|
+
# Offense count: 1
|
196
|
+
# Cop supports --auto-correct.
|
197
|
+
# Configuration parameters: IgnoredMethods.
|
198
|
+
# IgnoredMethods: respond_to, define_method
|
199
|
+
Style/SymbolProc:
|
200
|
+
Exclude:
|
201
|
+
- 'lib/her/model/parse.rb'
|
202
|
+
|
203
|
+
# Offense count: 2
|
204
|
+
# Cop supports --auto-correct.
|
205
|
+
# Configuration parameters: EnforcedStyle, AllowSafeAssignment.
|
206
|
+
# SupportedStyles: require_parentheses, require_no_parentheses, require_parentheses_when_complex
|
207
|
+
Style/TernaryParentheses:
|
208
|
+
Exclude:
|
209
|
+
- 'lib/her/model/http.rb'
|
210
|
+
- 'lib/her/model/orm.rb'
|
211
|
+
|
212
|
+
# Offense count: 1
|
213
|
+
# Cop supports --auto-correct.
|
214
|
+
# Configuration parameters: EnforcedStyleForMultiline.
|
215
|
+
# SupportedStylesForMultiline: comma, consistent_comma, no_comma
|
216
|
+
Style/TrailingCommaInHashLiteral:
|
217
|
+
Exclude:
|
218
|
+
- 'lib/her/middleware/json_api_parser.rb'
|
219
|
+
|
220
|
+
# Offense count: 6
|
221
|
+
# Cop supports --auto-correct.
|
222
|
+
# Configuration parameters: EnforcedStyle, MinSize, WordRegex.
|
223
|
+
# SupportedStyles: percent, brackets
|
224
|
+
Style/WordArray:
|
225
|
+
Exclude:
|
226
|
+
- 'spec/model/orm_spec.rb'
|
227
|
+
|
228
|
+
# Offense count: 409
|
229
|
+
# Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns.
|
230
|
+
# URISchemes: http, https
|
231
|
+
Metrics/LineLength:
|
232
|
+
Max: 377
|
data/README.md
CHANGED
@@ -452,6 +452,22 @@ Her expects all `User` resources to have an `:organization_id` (or `:_organizati
|
|
452
452
|
Her::Errors::PathError: Missing :_organization_id parameter to build the request path. Path is `organizations/:organization_id/users`. Parameters are `{ … }`.
|
453
453
|
```
|
454
454
|
|
455
|
+
#### Associations with custom attributes
|
456
|
+
|
457
|
+
Associations can also be made using custom attributes:
|
458
|
+
|
459
|
+
```ruby
|
460
|
+
class User
|
461
|
+
include Her::Model
|
462
|
+
belongs_to :owns, class_name: "Organization"
|
463
|
+
end
|
464
|
+
|
465
|
+
class Organization
|
466
|
+
include Her::Model
|
467
|
+
has_many :owners, class_name: "User"
|
468
|
+
end
|
469
|
+
```
|
470
|
+
|
455
471
|
### Validations
|
456
472
|
|
457
473
|
Her includes `ActiveModel::Validations` so you can declare validations the same way you do in Rails.
|
data/her.gemspec
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
|
+
|
2
3
|
$:.push File.expand_path("../lib", __FILE__)
|
3
4
|
require "her/version"
|
4
5
|
|
@@ -14,12 +15,12 @@ Gem::Specification.new do |s|
|
|
14
15
|
|
15
16
|
s.files = `git ls-files`.split("\n")
|
16
17
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
17
|
-
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
18
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
|
18
19
|
s.require_paths = ["lib"]
|
19
20
|
|
21
|
+
s.add_development_dependency "json", "~> 1.8"
|
20
22
|
s.add_development_dependency "rake", "~> 10.0"
|
21
23
|
s.add_development_dependency "rspec", "~> 3.5"
|
22
|
-
s.add_development_dependency "json", "~> 1.8"
|
23
24
|
|
24
25
|
s.add_runtime_dependency "activemodel", ">= 4.2.1"
|
25
26
|
s.add_runtime_dependency "faraday", ">= 0.8", "< 1.0"
|
data/lib/her/api.rb
CHANGED
@@ -2,6 +2,7 @@ module Her
|
|
2
2
|
# This class is where all HTTP requests are made. Before using Her, you must configure it
|
3
3
|
# so it knows where to make those requests. In Rails, this is usually done in `config/initializers/her.rb`:
|
4
4
|
class API
|
5
|
+
|
5
6
|
# @private
|
6
7
|
attr_reader :connection, :options
|
7
8
|
|
@@ -9,7 +10,7 @@ module Her
|
|
9
10
|
FARADAY_OPTIONS = [:request, :proxy, :ssl, :builder, :url, :parallel_manager, :params, :headers, :builder_class].freeze
|
10
11
|
|
11
12
|
# Setup a default API connection. Accepted arguments and options are the same as {API#setup}.
|
12
|
-
def self.setup(opts={}, &block)
|
13
|
+
def self.setup(opts = {}, &block)
|
13
14
|
@default_api = new(opts, &block)
|
14
15
|
end
|
15
16
|
|
@@ -68,11 +69,11 @@ module Her
|
|
68
69
|
# connection.use MyCustomParser
|
69
70
|
# connection.use Faraday::Adapter::NetHttp
|
70
71
|
# end
|
71
|
-
def setup(opts={}, &blk)
|
72
|
+
def setup(opts = {}, &blk)
|
72
73
|
opts[:url] = opts.delete(:base_uri) if opts.include?(:base_uri) # Support legacy :base_uri option
|
73
74
|
@options = opts
|
74
75
|
|
75
|
-
faraday_options = @options.
|
76
|
+
faraday_options = @options.select { |key, _| FARADAY_OPTIONS.include?(key.to_sym) }
|
76
77
|
@connection = Faraday.new(faraday_options) do |connection|
|
77
78
|
yield connection if block_given?
|
78
79
|
end
|
@@ -84,11 +85,11 @@ module Her
|
|
84
85
|
# and a metadata Hash.
|
85
86
|
#
|
86
87
|
# @private
|
87
|
-
def request(opts={})
|
88
|
+
def request(opts = {})
|
88
89
|
method = opts.delete(:_method)
|
89
90
|
path = opts.delete(:_path)
|
90
91
|
headers = opts.delete(:_headers)
|
91
|
-
opts.delete_if { |key,
|
92
|
+
opts.delete_if { |key, _| key.to_s =~ /^_/ } # Remove all internal parameters
|
92
93
|
if method == :options
|
93
94
|
# Faraday doesn't support the OPTIONS verb because of a name collision with an internal options method
|
94
95
|
# so we need to call run_request directly.
|
@@ -108,12 +109,12 @@ module Her
|
|
108
109
|
end
|
109
110
|
end
|
110
111
|
{ :parsed_data => response.env[:body], :response => response }
|
111
|
-
|
112
112
|
end
|
113
113
|
|
114
114
|
private
|
115
|
+
|
115
116
|
# @private
|
116
|
-
def self.default_api(opts={})
|
117
|
+
def self.default_api(opts = {})
|
117
118
|
defined?(@default_api) ? @default_api : nil
|
118
119
|
end
|
119
120
|
end
|
data/lib/her/collection.rb
CHANGED
data/lib/her/errors.rb
CHANGED
@@ -1,9 +1,10 @@
|
|
1
1
|
module Her
|
2
2
|
module Errors
|
3
3
|
class PathError < StandardError
|
4
|
+
|
4
5
|
attr_reader :missing_parameter
|
5
6
|
|
6
|
-
def initialize(message, missing_parameter=nil)
|
7
|
+
def initialize(message, missing_parameter = nil)
|
7
8
|
super(message)
|
8
9
|
@missing_parameter = missing_parameter
|
9
10
|
end
|
@@ -16,6 +17,7 @@ module Her
|
|
16
17
|
end
|
17
18
|
|
18
19
|
class ResourceInvalid < StandardError
|
20
|
+
|
19
21
|
attr_reader :resource
|
20
22
|
def initialize(resource)
|
21
23
|
@resource = resource
|
data/lib/her/json_api/model.rb
CHANGED
@@ -1,13 +1,12 @@
|
|
1
1
|
module Her
|
2
2
|
module JsonApi
|
3
3
|
module Model
|
4
|
-
|
5
4
|
def self.included(klass)
|
6
5
|
klass.class_eval do
|
7
6
|
include Her::Model
|
8
7
|
|
9
8
|
[:parse_root_in_json, :include_root_in_json, :root_element, :primary_key].each do |method|
|
10
|
-
define_method method do |*
|
9
|
+
define_method method do |*_|
|
11
10
|
raise NoMethodError, "Her::JsonApi::Model does not support the #{method} configuration option"
|
12
11
|
end
|
13
12
|
end
|
@@ -15,24 +14,21 @@ module Her
|
|
15
14
|
method_for :update, :patch
|
16
15
|
|
17
16
|
@type = name.demodulize.tableize
|
18
|
-
|
17
|
+
|
19
18
|
def self.parse(data)
|
20
19
|
data.fetch(:attributes).merge(data.slice(:id))
|
21
20
|
end
|
22
21
|
|
23
|
-
def self.to_params(attributes, changes={})
|
24
|
-
request_data = { type: @type }.tap
|
25
|
-
attrs = attributes.dup.symbolize_keys.tap
|
22
|
+
def self.to_params(attributes, changes = {})
|
23
|
+
request_data = { type: @type }.tap do |request_body|
|
24
|
+
attrs = attributes.dup.symbolize_keys.tap do |filtered_attributes|
|
26
25
|
if her_api.options[:send_only_modified_attributes]
|
27
|
-
filtered_attributes
|
28
|
-
hash[attribute] = filtered_attributes[attribute]
|
29
|
-
hash
|
30
|
-
end
|
26
|
+
filtered_attributes.slice! *changes.keys.map(&:to_sym)
|
31
27
|
end
|
32
|
-
|
28
|
+
end
|
33
29
|
request_body[:id] = attrs.delete(:id) if attrs[:id]
|
34
30
|
request_body[:attributes] = attrs
|
35
|
-
|
31
|
+
end
|
36
32
|
{ data: request_data }
|
37
33
|
end
|
38
34
|
|
data/lib/her/middleware.rb
CHANGED
@@ -2,6 +2,7 @@ module Her
|
|
2
2
|
module Middleware
|
3
3
|
# This middleware treat the received first-level JSON structure as the resource data.
|
4
4
|
class FirstLevelParseJSON < ParseJSON
|
5
|
+
|
5
6
|
# Parse the response body
|
6
7
|
#
|
7
8
|
# @param [String] body The response body
|
@@ -25,11 +26,11 @@ module Her
|
|
25
26
|
# @private
|
26
27
|
def on_complete(env)
|
27
28
|
env[:body] = case env[:status]
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
29
|
+
when 204
|
30
|
+
parse('{}')
|
31
|
+
else
|
32
|
+
parse(env[:body])
|
33
|
+
end
|
33
34
|
end
|
34
35
|
end
|
35
36
|
end
|