json_api_client 1.4.0 → 1.5.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e0d020be7e9bf6e1b22999ffc3a0acde1ecc5625
4
- data.tar.gz: 5125ad8d9ea03cf4cf58c77e4031d678de6778f8
3
+ metadata.gz: c6080263ed5bd33871ec24abc5e89a8f70b6e63c
4
+ data.tar.gz: c084e334f7435d9301f5c5577df6b8b7b8baf6c5
5
5
  SHA512:
6
- metadata.gz: 625e1b33f72351b242e9d3ed4920b43be7ab14c150c71eeb3d7f5f077a644d5bc8dfee01c58855735e3095d5f084e32ecd86ce0f3075f70bd869b1765e72b3c9
7
- data.tar.gz: 7f8675ae9030f8b1d4d1342d77075c73f117715a0b3b8540144ca7074701e38fbed1f0e3b4c793fbddcdb588d627ae166beda7c2908d79fe7cd3f0ab66677205
6
+ metadata.gz: 141e23e17b57f4aa31a7299cb9d43acf177bc9703869dd4e97577cc32da7ee3bfe8924fdb69ff2ae8c62b3972d6b209c4b1848e940bdcbb2e33adf2fbf955ad9
7
+ data.tar.gz: 74b02104a09ef030924b5b885e397c35facd293e749a03a9fa8e8a83f2c11799a5006563d5dd095ec709623e4e393296a0a0b852433562cfec960aeeb2c1b70d
data/README.md CHANGED
@@ -447,6 +447,17 @@ end
447
447
 
448
448
  You can customize how your resources find pagination information from the response.
449
449
 
450
+ If the [existing paginator](https://github.com/chingor13/json_api_client/blob/master/lib/json_api_client/paginating/paginator.rb) fits your requirements but you don't use the default `page` and `per_page` params for pagination, you can customise the param keys as follows:
451
+
452
+ ```ruby
453
+ JsonApiClient::Paginating::Paginator.page_param = "page[number]"
454
+ JsonApiClient::Paginating::Paginator.per_page_param = "page[size]"
455
+ ```
456
+
457
+ Please note that this is a global configuration, so library authors should create a custom paginator that inherits `JsonApiClient::Paginating::Paginator` and configure the custom paginator to avoid modifying global config.
458
+
459
+ If the [existing paginator](https://github.com/chingor13/json_api_client/blob/master/lib/json_api_client/paginating/paginator.rb) does not fit your needs, you can create a custom paginator:
460
+
450
461
  ```ruby
451
462
  class MyPaginator
452
463
  def initialize(result_set, data); end
@@ -458,6 +469,36 @@ class MyApi::Base < JsonApiClient::Resource
458
469
  end
459
470
  ```
460
471
 
472
+
473
+ ### Type Casting
474
+
475
+ You can define your own types and its casting mechanism for schema.
476
+
477
+ ```ruby
478
+ require 'money'
479
+ class MyMoneyCaster
480
+ def self.cast(value, default)
481
+ begin
482
+ Money.new(value, "USD")
483
+ rescue ArgumentError
484
+ default
485
+ end
486
+ end
487
+ end
488
+
489
+ JsonApiClient::Schema.register money: MyMoneyCaster
490
+
491
+ ```
492
+ and finally
493
+
494
+ ```ruby
495
+ class Order < JsonApiClient::Resource
496
+ property :total_amount, type: :money
497
+ end
498
+
499
+ ```
500
+
501
+
461
502
  ## Changelog
462
503
 
463
504
  See [changelog](https://github.com/chingor13/json_api_client/blob/master/CHANGELOG.md)
@@ -1,11 +1,18 @@
1
1
  module JsonApiClient
2
2
  module Paginating
3
3
  class Paginator
4
+ class_attribute :page_param,
5
+ :per_page_param
6
+
7
+ self.page_param = "page"
8
+ self.per_page_param = "per_page"
9
+
4
10
  attr_reader :params, :result_set, :links
11
+
5
12
  def initialize(result_set, data)
6
13
  @params = params_for_uri(result_set.uri)
7
14
  @result_set = result_set
8
- @links = data['links']
15
+ @links = data["links"]
9
16
  end
10
17
 
11
18
  def next
@@ -28,7 +35,7 @@ module JsonApiClient
28
35
  if links["last"]
29
36
  uri = result_set.links.link_url_for("last")
30
37
  last_params = params_for_uri(uri)
31
- last_params.fetch("page") do
38
+ last_params.fetch(page_param) do
32
39
  current_page
33
40
  end.to_i
34
41
  else
@@ -47,13 +54,13 @@ module JsonApiClient
47
54
  end
48
55
 
49
56
  def per_page
50
- params.fetch("per_page") do
57
+ params.fetch(per_page_param) do
51
58
  result_set.length
52
59
  end.to_i
53
60
  end
54
61
 
55
62
  def current_page
56
- params.fetch("page", 1).to_i
63
+ params.fetch(page_param, 1).to_i
57
64
  end
58
65
 
59
66
  def out_of_bounds?
@@ -398,7 +398,7 @@ module JsonApiClient
398
398
  if last_result_set.has_errors?
399
399
  last_result_set.errors.each do |error|
400
400
  if error.source_parameter
401
- errors.add(error.source_parameter, error.title || error.detail)
401
+ errors.add(self.class.key_formatter.unformat(error.source_parameter), error.title || error.detail)
402
402
  else
403
403
  errors.add(:base, error.title || error.detail)
404
404
  end
@@ -409,6 +409,7 @@ module JsonApiClient
409
409
  mark_as_persisted!
410
410
  if updated = last_result_set.first
411
411
  self.attributes = updated.attributes
412
+ self.links.attributes = updated.links.attributes
412
413
  self.relationships.attributes = updated.relationships.attributes
413
414
  clear_changes_information
414
415
  end
@@ -1,36 +1,108 @@
1
1
  require 'bigdecimal'
2
2
  module JsonApiClient
3
3
  class Schema
4
- Property = Struct.new(:name, :type, :default) do
5
- def cast(value)
6
- return nil if value.nil?
7
- return value if type.nil?
4
+ module Types
8
5
 
9
- case type.to_sym
10
- when :int, :integer
6
+ class Integer
7
+ def self.cast(value, _)
11
8
  value.to_i
12
- when :string
9
+ end
10
+ end
11
+
12
+ class String
13
+ def self.cast(value, _)
13
14
  value.to_s
14
- when :float
15
+ end
16
+ end
17
+
18
+ class Float
19
+ def self.cast(value, _)
15
20
  value.to_f
16
- when :time
17
- value.is_a?(Time) || nil ? value : Time.parse(value)
18
- when :decimal
19
- value.nil? ? nil : BigDecimal.new(value)
20
- when :boolean
21
+ end
22
+ end
23
+
24
+ class Time
25
+ def self.cast(value, _)
26
+ value.is_a?(::Time) ? value : ::Time.parse(value)
27
+ end
28
+ end
29
+
30
+ class Decimal
31
+ def self.cast(value, _)
32
+ BigDecimal.new(value)
33
+ end
34
+ end
35
+
36
+ class Boolean
37
+ def self.cast(value, default)
21
38
  case value
22
- when "false", "0", 0, false
23
- false
24
- when "true", "1", 1, true
25
- true
26
- else
27
- # if it's unknown, use the default value
28
- default
39
+ when "false", "0", 0, false
40
+ false
41
+ when "true", "1", 1, true
42
+ true
43
+ else
44
+ # if it's unknown, use the default value
45
+ default
29
46
  end
30
- else
31
- value
32
47
  end
33
48
  end
49
+
50
+ end
51
+
52
+ class TypeFactory
53
+ @@types = {}
54
+ # Register a new type key or keys with appropriate classes
55
+ #
56
+ # eg:
57
+ #
58
+ # require 'money'
59
+ #
60
+ # class MyMoneyCaster
61
+ # def self.cast(value, default)
62
+ # begin
63
+ # Money.new(value, "USD")
64
+ # rescue ArgumentError
65
+ # default
66
+ # end
67
+ # end
68
+ # end
69
+ #
70
+ # JsonApiClient::Schema::Types.register money: MyMoneyCaster
71
+ #
72
+ # You can setup several at once:
73
+ #
74
+ # JsonApiClient::Schema::Types.register money: MyMoneyCaster,
75
+ # date: MyJsonDateTypeCaster
76
+ #
77
+ #
78
+ #
79
+ #
80
+ def self.register(type_hash)
81
+ @@types.merge!(type_hash)
82
+ end
83
+
84
+ def self.type_for(type)
85
+ @@types[type]
86
+ end
87
+
88
+ self.register int: Types::Integer,
89
+ integer: Types::Integer,
90
+ string: Types::String,
91
+ float: Types::Float,
92
+ time: Types::Time,
93
+ decimal: Types::Decimal,
94
+ boolean: Types::Boolean
95
+
96
+ end
97
+
98
+ Property = Struct.new(:name, :type, :default) do
99
+ def cast(value)
100
+ return nil if value.nil?
101
+ return value if type.nil?
102
+ type_caster = TypeFactory.type_for(type)
103
+ return value if type_caster.nil?
104
+ type_caster.cast(value, default)
105
+ end
34
106
  end
35
107
 
36
108
  def initialize
@@ -54,11 +126,13 @@ module JsonApiClient
54
126
  def size
55
127
  @properties.size
56
128
  end
129
+
57
130
  alias_method :length, :size
58
131
 
59
132
  def each_property(&block)
60
133
  @properties.values.each(&block)
61
134
  end
135
+
62
136
  alias_method :each, :each_property
63
137
 
64
138
  # Look up a property by name
@@ -68,6 +142,13 @@ module JsonApiClient
68
142
  def find(property_name)
69
143
  @properties[property_name.to_sym]
70
144
  end
145
+
71
146
  alias_method :[], :find
147
+
148
+ class << self
149
+ def register(type_hash)
150
+ TypeFactory.register(type_hash)
151
+ end
152
+ end
72
153
  end
73
154
  end
@@ -1,3 +1,3 @@
1
1
  module JsonApiClient
2
- VERSION = "1.4.0"
2
+ VERSION = "1.5.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: json_api_client
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.0
4
+ version: 1.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jeff Ching
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-01-14 00:00:00.000000000 Z
11
+ date: 2017-03-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -176,7 +176,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
176
176
  version: '0'
177
177
  requirements: []
178
178
  rubyforge_project:
179
- rubygems_version: 2.5.2
179
+ rubygems_version: 2.6.8
180
180
  signing_key:
181
181
  specification_version: 4
182
182
  summary: Build client libraries compliant with specification defined by jsonapi.org