json_api_ruby 0.1.1 → 0.2.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: 6cf3164f2abf635e618957c75eea9210e2964c3e
4
- data.tar.gz: f1927eafda56413ca744cc43ac5608344db1af55
3
+ metadata.gz: 2ba5f435a463e08420afbfe01b6e6c00d872c1d6
4
+ data.tar.gz: 82bd54e3e35ce66ac027407ddd5edcc71d06a9bf
5
5
  SHA512:
6
- metadata.gz: 6af9abffd2f8321a35ef837a92bcfc8da35bec3685cfda916b0559db0c152bc3e00d80a39f34a5a381736a48af28f9fa15a409e0f85052c6dd30e1dd65c44aaf
7
- data.tar.gz: 9e1a89a1741949c212c6833df0e65aa266bfc17630eca272b56f2690a4477e655d68f36442f8d370fc2a1bd7be12cc614f1bdfe3035f1547e0b9e0ad2fd6bd7b
6
+ metadata.gz: 07593a0a1372734b4adcd11bd263e129cece029dc3f3bf3de9dd8998a7a28f32ebf0d02de4e9ff1c77cbdda4a7f6e976a15d666a803a0d983d57a4da935bea80
7
+ data.tar.gz: 3625634704e631f29bcce7f64bbd53c847febf50806b063dffced0b3babe90f88360b2349622dce08a47a2bd4ec77529db629e3540fcd0aa9d95534216b451ad
data/CHANGELOG.md CHANGED
@@ -1,3 +1,6 @@
1
+ 0.2.0
2
+ Added the ability to subclass from a class whose superclass is Resource
3
+
1
4
  0.1.1
2
5
  Fix issues related to empty or nil objects
3
6
 
@@ -37,7 +37,7 @@ module JsonApi
37
37
  end
38
38
 
39
39
  def attributes_hash
40
- Array(self.class.fields).inject({}) do |attrs, attr|
40
+ fields_array.inject({}) do |attrs, attr|
41
41
  meth = method(attr)
42
42
  attrs[attr.to_s] = meth.call
43
43
  attrs
@@ -47,12 +47,47 @@ module JsonApi
47
47
  # Builds relationship resource classes
48
48
  def build_object_graph
49
49
  @relationships ||= []
50
- Array(self.class.relationships).each do |relationship|
50
+ relationships_array.each do |relationship|
51
51
  included = includes.include?(relationship.name)
52
52
  rel = relationship.build_resources({parent_resource: self, included: included})
53
53
  @relationships << rel
54
54
  end
55
55
  end
56
+
57
+ # Traverses fields set on super-class(es) and concatinates them into a
58
+ # single set. Stores the set in `self.class.fields`, leaving super-class
59
+ # `fields` sets untouched.
60
+ def fields_array(klass = self.class)
61
+ fields_list = concat_list(self.class.fields, klass.fields)
62
+ unless klass.superclass == Resource
63
+ return fields_array(klass.superclass)
64
+ end
65
+ fields_list
66
+ end
67
+
68
+ # Traverses relationships set on super-class(es) and concatinates them
69
+ # into a single set. Stores the set in `self.class.relationships`,
70
+ # leaving super-class `relationships` sets untouched.
71
+ def relationships_array(klass = self.class)
72
+ rel_list = concat_list(self.class.relationships, klass.relationships)
73
+ unless klass.superclass == Resource
74
+ return relationships_array(klass.superclass)
75
+ end
76
+ rel_list
77
+ end
78
+
79
+ private
80
+
81
+ # Adds elements of the `concat_list` to the `target_list` if they are
82
+ # not already present.
83
+ def concat_list(target_list, concat_list)
84
+ list = Array(target_list)
85
+ not_in_list = Array(concat_list).reject do |item|
86
+ list.include?(item)
87
+ end
88
+ not_in_list.each { |item| list << item }
89
+ list
90
+ end
56
91
  end
57
92
 
58
93
  end
@@ -1,3 +1,3 @@
1
1
  module JsonApi
2
- VERSION = '0.1.1'
2
+ VERSION = '0.2.0'
3
3
  end
@@ -87,4 +87,65 @@ RSpec.describe JsonApi::Resource do
87
87
  expect(serialized_person['links']['self']).to eq("http://localhost:3000/people/#{person.id}")
88
88
  end
89
89
  end
90
+
91
+ describe 'deep subclassing of Resources' do
92
+ let(:person) { Person.new('Philip J. Fry', 'fry@thefuture.com', 'www.thefuture.com', '@philipjfry') }
93
+ subject(:super_class_serialization) do
94
+ PersonResource.new(person).to_hash
95
+ end
96
+
97
+ context 'subclasses of class whose superclass is Resource' do
98
+ subject(:subclass_serialization) do
99
+ SubclassedPersonResource.new(person).to_hash
100
+ end
101
+
102
+ it "does not affect its super-class's list of attributes" do
103
+ expect(PersonResource.fields).to_not eq(SubclassedPersonResource.fields)
104
+ end
105
+
106
+ it 'concatinates its attributes with the list of attributes from its super-class' do
107
+ expected_attributes = super_class_serialization['attributes'].merge('website' => 'www.thefuture.com')
108
+ expect(subclass_serialization['attributes']).to eq(expected_attributes)
109
+ end
110
+
111
+ it 'returns the same relationships as its super-class' do
112
+ expect(subclass_serialization['relationships']).to eq(super_class_serialization['relationships'])
113
+ end
114
+
115
+ context 'with overridden attributes' do
116
+ subject(:overridden_serialization) do
117
+ OverriddenSubclassedPersonResource.new(person).to_hash
118
+ end
119
+
120
+ it 'returns overridden attributes from the subclass' do
121
+ expect(overridden_serialization['attributes']['name']).to eq('Philip J. Fry!!')
122
+ end
123
+ end
124
+ end
125
+
126
+ context 'subclasses of subclasses of class whose superclass is Resource' do
127
+ subject(:deep_subclass_serialization) do
128
+ DeeplySubclassedPersonResource.new(person).to_hash
129
+ end
130
+
131
+ it 'concatinates its attributes with the list of attributes from its super-classes' do
132
+ expected_attributes = super_class_serialization['attributes'].merge('website' => 'www.thefuture.com', 'twitter' => '@philipjfry')
133
+ expect(deep_subclass_serialization['attributes']).to eq(expected_attributes)
134
+ end
135
+
136
+ it 'returns the same relationships as its super-classes' do
137
+ expect(deep_subclass_serialization['relationships']).to eq(super_class_serialization['relationships'])
138
+ end
139
+
140
+ context 'with overridden attributes' do
141
+ subject(:deep_overridden_serialization) do
142
+ OverriddenDeeplySubclassedPersonResource.new(person).to_hash
143
+ end
144
+
145
+ it 'returns overridden attributes from the subclass' do
146
+ expect(deep_overridden_serialization['attributes']['name']).to eq('Philip J. Fry?')
147
+ end
148
+ end
149
+ end
150
+ end
90
151
  end
@@ -53,11 +53,13 @@ end
53
53
 
54
54
  class Person
55
55
  include Identifiers
56
- attr_accessor :name, :email_address, :created_at, :updated_at
56
+ attr_accessor :name, :email_address, :website, :twitter, :created_at, :updated_at
57
57
 
58
- def initialize(name, email)
58
+ def initialize(name, email, website = nil, twitter = nil)
59
59
  @name = name
60
60
  @email_address = email
61
+ @website = website
62
+ @twitter = twitter
61
63
  @created_at = 1.month.ago
62
64
  @updated_at = 1.month.ago
63
65
  end
@@ -76,6 +78,26 @@ class PersonResource < JsonApi::Resource
76
78
  has_many :articles
77
79
  end
78
80
 
81
+ class SubclassedPersonResource < PersonResource
82
+ attribute :website
83
+ end
84
+
85
+ class DeeplySubclassedPersonResource < SubclassedPersonResource
86
+ attribute :twitter
87
+ end
88
+
89
+ class OverriddenSubclassedPersonResource < PersonResource
90
+ def name
91
+ object.name + '!!'
92
+ end
93
+ end
94
+
95
+ class OverriddenDeeplySubclassedPersonResource < OverriddenSubclassedPersonResource
96
+ def name
97
+ object.name + '?'
98
+ end
99
+ end
100
+
79
101
  class ArticleResource < JsonApi::Resource
80
102
  id_field :uuid
81
103
  attributes :publish_date, :title, :short_description, :created_at, :updated_at
@@ -127,4 +149,3 @@ module DifferentNamespace
127
149
  class ThreeResource < JsonApi::Resource
128
150
  end
129
151
  end
130
-
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: json_api_ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tracey Eubanks
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-02-04 00:00:00.000000000 Z
11
+ date: 2016-02-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport