Skip to content

Commit 9dcc3c8

Browse files
Merge pull request #12 from Sage/feature_attribute_alias
Added attribute name alias functionality
2 parents 8c76d6f + 48f5c4c commit 9dcc3c8

5 files changed

Lines changed: 146 additions & 30 deletions

File tree

README.md

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,26 @@ Or install it yourself as:
4949

5050
ClassKit entities can be created by implementing the `extend ClassKit` extend into the entity class and then using the `attr_accessor_type` method to register attributes as above inplace of the standard ruby `attr_accessor` method.
5151

52+
ClassKit entity attributes can use a name alias in order to parse to/from hashes/json with different key names, see the example below:
53+
54+
class Address
55+
extend ClassKit
56+
57+
attr_accessor_type :line1, type: String, alias_name: :l1
58+
attr_accessor_type :line2, alias_name: :l2
59+
attr_accessor_type :postcode, alias_name: :pc
60+
end
61+
62+
{ "l1": "23 the street", "l2": "the town", "pc": "ne1 4rt" }
63+
64+
To use alias names you must specify `use_alias = true` for the following helper methods:
65+
66+
helper.to_hash(entity, true)
67+
helper.from_hash(hash: hash_object, klass: entity_klass, use_alias: true)
68+
69+
helper.to_json(entity, true)
70+
helper.from_json(json: json_string, klass: entity_klass, use_alias: true)
71+
5272
### attr_accessor_type
5373

5474
This method is used to add typed attributes to a class.
@@ -111,12 +131,13 @@ Example:
111131

112132
helper.is_class_kit?(obj)
113133

114-
#### #to_hash(object)
134+
#### #to_hash(object, use_alias)
115135

116136
This method is called to convert a ClassKit entity into a `Hash`.
117137

118138
[Params]
119-
- `object` This is the ClassKit entity to convert.
139+
- `object` [Required] This is the ClassKit entity to convert.
140+
- `use_alias` [Optional] [Default=false] This is used to specify if attribute alias names should be used.
120141

121142
[Return]
122143

@@ -126,14 +147,15 @@ Example:
126147

127148
hash = helper.to_hash(obj)
128149
129-
#### #from_hash(hash:,klass:)
150+
#### #from_hash(hash:,klass:, use_alias:)
130151

131152
This method is called to convert a `Hash` into a ClassKit entity.
132153

133154
[Params]
134-
- `hash:` This is the `Hash` to convert.
135-
- `klass:` This is the class of the ClassKit entity you want to convert the `Hash` into.
136-
(NOTE: It should be the fully qualified class name including modules)
155+
- `hash:` [Required] This is the `Hash` to convert.
156+
- `klass:` [Required] This is the class of the ClassKit entity you want to convert the `Hash` into.
157+
> NOTE: It should be the fully qualified class name including modules
158+
- `use_alias` [Optional] [Default=false] This is used to specify if attribute alias names should be used.
137159

138160
[Return]
139161

@@ -143,12 +165,13 @@ Example:
143165

144166
entity = helper.from_hash(hash: hsh, klass: Contact)
145167

146-
#### #to_json(object)
168+
#### #to_json(object, use_alias)
147169

148170
This method is called to convert a ClassKit entity into JSON.
149171

150172
[Params]
151173
- `object` This is the ClassKit entity to convert.
174+
- `use_alias` [Optional] [Default=false] This is used to specify if attribute alias names should be used.
152175

153176
[Return]
154177

@@ -158,14 +181,15 @@ Example:
158181

159182
json_string = helper.to_json(obj)
160183

161-
#### #from_json(json:, klass:)
184+
#### #from_json(json:, klass:, use_alias:)
162185

163186
This method is called to convert a JSON string into a ClassKit entity.
164187

165188
[Params]
166189
- `json:` This is the JSON string to convert.
167190
- `klass:` This is the class of the ClassKit entity you want to convert the JSON into.
168-
(NOTE: It should be the fully qualified class name including modules)
191+
> NOTE: It should be the fully qualified class name including modules
192+
- `use_alias` [Optional] [Default=false] This is used to specify if attribute alias names should be used.
169193

170194
[Return]
171195

lib/class_kit/class_methods.rb

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,29 @@
11
module ClassKit
2-
def attr_accessor_type(name, type: nil, collection_type: nil, allow_nil: true, default: nil, auto_init: false,
3-
meta: {})
4-
2+
def attr_accessor_type(
3+
name,
4+
type: nil,
5+
collection_type: nil,
6+
allow_nil: true,
7+
default: nil,
8+
auto_init: false,
9+
alias_name: nil,
10+
meta: {})
511
unless instance_variable_defined?(:@class_kit_attributes)
612
instance_variable_set(:@class_kit_attributes, {})
713
end
814

915
attributes = instance_variable_get(:@class_kit_attributes)
1016

11-
attributes[name] = { name: name, type: type, collection_type: collection_type, allow_nil: allow_nil,
12-
default: default, auto_init: auto_init, meta: meta }
17+
attributes[name] = {
18+
name: name,
19+
type: type,
20+
collection_type: collection_type,
21+
allow_nil: allow_nil,
22+
default: default,
23+
auto_init: auto_init,
24+
alias: alias_name,
25+
meta: meta
26+
}
1327

1428
class_eval do
1529
define_method name do

lib/class_kit/helper.rb

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -16,17 +16,17 @@ def validate_class_kit(klass)
1616
"Class: #{klass} does not implement ClassKit.")
1717
end
1818

19-
#This method is called to convert a ClassKit object into a Hash.
20-
def to_hash(object)
19+
# This method is called to convert a ClassKit object into a Hash.
20+
def to_hash(object, use_alias = false)
2121
validate_class_kit(object.class)
2222

2323
hash = {}
2424

2525
attributes = @attribute_helper.get_attributes(object.class)
2626
attributes.each do |attribute|
27-
key = attribute[:name]
27+
key = use_alias ? (attribute[:alias] || attribute[:name]) : attribute[:name]
2828
type = attribute[:type]
29-
value = object.public_send(key)
29+
value = object.public_send(attribute[:name])
3030
if value != nil
3131
hash[key] = if is_class_kit?(type)
3232
to_hash(value)
@@ -47,18 +47,18 @@ def to_hash(object)
4747
hash
4848
end
4949

50-
#This method is called to convert a Hash into a ClassKit object.
51-
def from_hash(hash:, klass:)
50+
# This method is called to convert a Hash into a ClassKit object.
51+
def from_hash(hash:, klass:, use_alias: false)
5252
validate_class_kit(klass)
5353

5454
@hash_helper.indifferent!(hash)
5555
entity = klass.new
5656
attributes = @attribute_helper.get_attributes(klass)
5757
attributes.each do |attribute|
58-
key = attribute[:name]
58+
key = use_alias ? (attribute[:alias] || attribute[:name]) : attribute[:name]
5959
type = attribute[:type]
6060

61-
#if the hash value is nil skip it
61+
# if the hash value is nil skip it
6262
next if hash[key].nil?
6363

6464
value = if is_class_kit?(type)
@@ -79,22 +79,22 @@ def from_hash(hash:, klass:)
7979
hash[key]
8080
end
8181

82-
entity.public_send(:"#{key}=", value)
82+
entity.public_send(:"#{attribute[:name]}=", value)
8383
end
8484

8585
entity
8686
end
8787

88-
#This method is called to convert a ClassKit object into JSON.
89-
def to_json(object)
90-
hash = to_hash(object)
88+
# This method is called to convert a ClassKit object into JSON.
89+
def to_json(object, use_alias = false)
90+
hash = to_hash(object, use_alias)
9191
JSON.dump(hash)
9292
end
9393

94-
#This method is called to convert JSON into a ClassKit object.
95-
def from_json(json:, klass:)
94+
# This method is called to convert JSON into a ClassKit object.
95+
def from_json(json:, klass:, use_alias: false)
9696
hash = JSON.load(json)
97-
from_hash(hash: hash, klass: klass)
97+
from_hash(hash: hash, klass: klass, use_alias: use_alias)
9898
end
9999
end
100100
end

spec/class_kit/helper_spec.rb

Lines changed: 71 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,23 @@
3131
expect(hash[:country]).to eq(entity.country)
3232
end
3333
end
34+
context 'when a valid class is specified with json aliases' do
35+
let(:entity) do
36+
TestAddressWithAlias.new.tap do |e|
37+
e.line1 = 'line1'
38+
e.line2 = 'line2'
39+
e.postcode = 'ne1 8rt'
40+
end
41+
end
42+
it 'should return a hash' do
43+
hash = subject.to_hash(entity, true)
44+
expect(hash).to be_a(Hash)
45+
expect(hash[:l1]).to eq(entity.line1)
46+
expect(hash[:l2]).to eq(entity.line2)
47+
expect(hash[:pc]).to eq(entity.postcode)
48+
expect(hash[:c]).to eq(entity.country)
49+
end
50+
end
3451
context 'when a valid class is specified with array attributes' do
3552
let(:address1) do
3653
TestAddress.new.tap do |e|
@@ -134,6 +151,24 @@
134151
expect(entity.address_collection.length).to eq(0)
135152
end
136153
end
154+
context 'when a valid hash is specified with aliases' do
155+
let(:hash) do
156+
{
157+
l1: 'line1',
158+
l2: 'line2',
159+
pc: 'ne1 4rt',
160+
c: 'United Kingdom'
161+
}
162+
end
163+
it 'should convert the hash' do
164+
entity = subject.from_hash(hash: hash, klass: TestAddressWithAlias, use_alias: true)
165+
expect(entity).not_to be_nil
166+
expect(entity.line1).to eq hash[:l1]
167+
expect(entity.line2).to eq hash[:l2]
168+
expect(entity.postcode).to eq hash[:pc]
169+
expect(entity.country).to eq hash[:c]
170+
end
171+
end
137172
end
138173

139174
describe '#to_json' do
@@ -195,6 +230,24 @@
195230
expect(result_hash['address_collection'].length).to eq(2)
196231
expect(result_hash['address_collection'][0]['post_code']).to eq hash[:address_collection][0][:post_code]
197232
end
233+
context 'when entity specifies aliases' do
234+
let(:address) do
235+
TestAddressWithAlias.new.tap do |a|
236+
a.line1 = 'street 1'
237+
a.line2 = 'street 2'
238+
a.postcode = 'ne3 5rt'
239+
end
240+
end
241+
it 'converts class to json using aliases' do
242+
result = subject.to_json(address, true)
243+
expect(result).to be_a(String)
244+
result_hash = JSON.load(result)
245+
expect(result_hash['l1']).to eq address.line1
246+
expect(result_hash['l2']).to eq address.line2
247+
expect(result_hash['pc']).to eq address.postcode
248+
expect(result_hash['c']).to eq address.country
249+
end
250+
end
198251
end
199252

200253
describe '#from_json' do
@@ -253,5 +306,22 @@
253306
expect(entity.address_collection[1].line2).to eq(hash[:address_collection][1][:line2])
254307
expect(entity.address_collection[1].postcode).to eq(hash[:address_collection][1][:postcode])
255308
end
309+
context 'when entity has json aliases' do
310+
let(:hash) do
311+
{
312+
l1: 'line1',
313+
l2: 'line2',
314+
pc: 'ne1 4rt',
315+
c: 'United Kingdom'
316+
}
317+
end
318+
it 'converts json into the relevant entity' do
319+
entity = subject.from_json(json: json, klass: TestAddressWithAlias, use_alias: true)
320+
expect(entity.line1).to eq(hash[:l1])
321+
expect(entity.line2).to eq(hash[:l2])
322+
expect(entity.postcode).to eq(hash[:pc])
323+
expect(entity.country).to eq(hash[:c])
324+
end
325+
end
256326
end
257-
end
327+
end

spec/class_kit/test_objects.rb

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,14 @@ class TestAddress
66
attr_accessor_type :country, type: String, default: 'United Kingdom'
77
end
88

9+
class TestAddressWithAlias
10+
extend ClassKit
11+
attr_accessor_type :line1, type: String, alias_name: :l1
12+
attr_accessor_type :line2, alias_name: :l2
13+
attr_accessor_type :postcode, alias_name: :pc
14+
attr_accessor_type :country, type: String, default: 'United Kingdom', alias_name: :c
15+
end
16+
917
class TestEntity
1018
extend ClassKit
1119

0 commit comments

Comments
 (0)