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.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +19 -1279
  3. data/.rubocop_todo.yml +232 -0
  4. data/README.md +16 -0
  5. data/her.gemspec +3 -2
  6. data/lib/her/api.rb +8 -7
  7. data/lib/her/collection.rb +2 -1
  8. data/lib/her/errors.rb +3 -1
  9. data/lib/her/json_api/model.rb +8 -12
  10. data/lib/her/middleware.rb +1 -1
  11. data/lib/her/middleware/accept_json.rb +1 -0
  12. data/lib/her/middleware/first_level_parse_json.rb +6 -5
  13. data/lib/her/middleware/json_api_parser.rb +6 -5
  14. data/lib/her/middleware/parse_json.rb +2 -1
  15. data/lib/her/middleware/second_level_parse_json.rb +6 -5
  16. data/lib/her/model/associations.rb +6 -6
  17. data/lib/her/model/associations/association.rb +7 -9
  18. data/lib/her/model/associations/association_proxy.rb +2 -3
  19. data/lib/her/model/associations/belongs_to_association.rb +1 -1
  20. data/lib/her/model/attributes.rb +6 -6
  21. data/lib/her/model/base.rb +2 -2
  22. data/lib/her/model/http.rb +1 -1
  23. data/lib/her/model/introspection.rb +5 -3
  24. data/lib/her/model/nested_attributes.rb +1 -1
  25. data/lib/her/model/orm.rb +9 -8
  26. data/lib/her/model/parse.rb +9 -12
  27. data/lib/her/model/paths.rb +3 -4
  28. data/lib/her/model/relation.rb +5 -4
  29. data/lib/her/version.rb +1 -1
  30. data/spec/api_spec.rb +3 -0
  31. data/spec/middleware/accept_json_spec.rb +1 -0
  32. data/spec/middleware/first_level_parse_json_spec.rb +2 -1
  33. data/spec/middleware/json_api_parser_spec.rb +1 -0
  34. data/spec/middleware/second_level_parse_json_spec.rb +1 -0
  35. data/spec/model/associations/association_proxy_spec.rb +1 -0
  36. data/spec/model/associations_spec.rb +4 -3
  37. data/spec/model/attributes_spec.rb +5 -3
  38. data/spec/model/callbacks_spec.rb +14 -15
  39. data/spec/model/dirty_spec.rb +1 -0
  40. data/spec/model/http_spec.rb +1 -0
  41. data/spec/model/introspection_spec.rb +3 -2
  42. data/spec/model/nested_attributes_spec.rb +1 -0
  43. data/spec/model/orm_spec.rb +22 -16
  44. data/spec/model/parse_spec.rb +3 -0
  45. data/spec/model/paths_spec.rb +1 -0
  46. data/spec/model/relation_spec.rb +3 -2
  47. data/spec/model/validations_spec.rb +1 -0
  48. data/spec/model_spec.rb +1 -0
  49. data/spec/support/extensions/array.rb +1 -0
  50. data/spec/support/extensions/hash.rb +1 -0
  51. metadata +12 -11
@@ -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.
@@ -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"
@@ -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.reject { |key, value| !FARADAY_OPTIONS.include?(key.to_sym) }
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, value| key.to_s =~ /^_/ } # Remove all internal parameters
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
@@ -1,9 +1,10 @@
1
1
  module Her
2
2
  class Collection < ::Array
3
+
3
4
  attr_reader :metadata, :errors
4
5
 
5
6
  # @private
6
- def initialize(items=[], metadata={}, errors={})
7
+ def initialize(items = [], metadata = {}, errors = {})
7
8
  super(items)
8
9
  @metadata = metadata
9
10
  @errors = errors
@@ -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
@@ -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 |*args|
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 { |request_body|
25
- attrs = attributes.dup.symbolize_keys.tap { |filtered_attributes|
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 = changes.symbolize_keys.keys.inject({}) do |hash, attribute|
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
 
@@ -7,6 +7,6 @@ module Her
7
7
  module Middleware
8
8
  DefaultParseJSON = FirstLevelParseJSON
9
9
 
10
- autoload :JsonApiParser, 'her/middleware/json_api_parser'
10
+ autoload :JsonApiParser, 'her/middleware/json_api_parser'
11
11
  end
12
12
  end
@@ -2,6 +2,7 @@ module Her
2
2
  module Middleware
3
3
  # This middleware adds a "Accept: application/json" HTTP header
4
4
  class AcceptJSON < Faraday::Middleware
5
+
5
6
  # @private
6
7
  def add_header(headers)
7
8
  headers.merge! "Accept" => "application/json"
@@ -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
- when 204
29
- parse('{}')
30
- else
31
- parse(env[:body])
32
- end
29
+ when 204
30
+ parse('{}')
31
+ else
32
+ parse(env[:body])
33
+ end
33
34
  end
34
35
  end
35
36
  end