her 1.0.1 → 1.0.2

Sign up to get free protection for your applications and to get access to all the features.
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