easy_serializer 0.1.0 → 0.1.1
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 +4 -4
- data/.gitignore +2 -1
- data/.rspec +1 -0
- data/Gemfile +2 -0
- data/README.md +218 -6
- data/bin/console +4 -4
- data/lib/easy_serializer/base.rb +20 -4
- data/lib/easy_serializer/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0cc2097011b0fa8a92990c2207848e77eae0891a
|
4
|
+
data.tar.gz: ea4d21a3fe3bf12dfdedd7b795b884962564a990
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 80b141c0fb80d95525bcf0ae6b9b3335795fcf61ae6bcaff8c51b253ffd4650f277eb5f57f0be5ad0d50cf229bf0faf2f13a06e5ff65fb25e9fda1b921796f30
|
7
|
+
data.tar.gz: fea25e7aebe7a75967856269096a2f6ad84a049e236c1b6a88fefec005c15b5e7a024a03054d2593adbe3f451a34beb96a41a6c487e468fe1648d2eca47753af
|
data/.gitignore
CHANGED
data/.rspec
CHANGED
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,7 +1,20 @@
|
|
1
1
|
# EasySerializer
|
2
2
|
|
3
|
+
[ ](https://codeship.com/projects/115737)
|
4
|
+
[](https://codeclimate.com/github/arturictus/easy_serializer)
|
5
|
+
[](https://codeclimate.com/github/arturictus/easy_serializer/coverage)
|
6
|
+
|
3
7
|
Semantic serializer for making easy serializing objects.
|
4
8
|
|
9
|
+
features:
|
10
|
+
- Nice and simple serialization DSL.
|
11
|
+
- Cache helpers to use with your favorite adapter like rails cache.
|
12
|
+
|
13
|
+
Advantages:
|
14
|
+
- Separated responsibility from Model class and serialization allowing multiple serializers for the same Model class, very useful for API versioning.
|
15
|
+
- In contraposition with active model serializers with EasySerializer you can serialize any object responding to the methods you want to serialize.
|
16
|
+
- EasySerializer is an small library with few dependencies.
|
17
|
+
|
5
18
|
## Installation
|
6
19
|
|
7
20
|
Add this line to your application's Gemfile:
|
@@ -18,10 +31,209 @@ Or install it yourself as:
|
|
18
31
|
|
19
32
|
$ gem install easy_serializer
|
20
33
|
|
34
|
+
Add the configuration file:
|
35
|
+
|
36
|
+
**Only if you need caching.**
|
37
|
+
|
38
|
+
_If your are in a Rails environment place this file at config/initializers_
|
39
|
+
|
40
|
+
```ruby
|
41
|
+
EasySerializer.setup do |config|
|
42
|
+
# = perform_caching
|
43
|
+
#
|
44
|
+
# Enable o disable caching.
|
45
|
+
# default: false
|
46
|
+
#
|
47
|
+
# config.perform_caching = true
|
48
|
+
|
49
|
+
# = cache
|
50
|
+
#
|
51
|
+
# Set your caching tool for the serializer
|
52
|
+
# must respond to fetch(obj, opts, &block) like Rails Cache.
|
53
|
+
# default: nil
|
54
|
+
#
|
55
|
+
# config.cache = Rails.cache
|
56
|
+
end
|
57
|
+
```
|
58
|
+
|
21
59
|
## Usage
|
22
60
|
|
23
|
-
example:
|
24
|
-
|
61
|
+
### Simple example:
|
62
|
+
|
63
|
+
```ruby
|
64
|
+
user = OpenStruct.new(name: 'John', surname: 'Doe')
|
65
|
+
|
66
|
+
class UserSerializer < EasySerializer::Base
|
67
|
+
attributes :name, :surname
|
68
|
+
end
|
69
|
+
|
70
|
+
UserSerializer.call(user)
|
71
|
+
# =>
|
72
|
+
{
|
73
|
+
name: 'John',
|
74
|
+
surname: 'Doe'
|
75
|
+
}
|
76
|
+
```
|
77
|
+
**Using blocks:**
|
78
|
+
|
79
|
+
```ruby
|
80
|
+
class UserSerializer < EasySerializer::Base
|
81
|
+
attribute(:name) { |user| user.name.capitalize }
|
82
|
+
attribute(:surname) { |user| user.surname.capitalize }
|
83
|
+
end
|
84
|
+
```
|
85
|
+
|
86
|
+
**Changing keys:**
|
87
|
+
|
88
|
+
```ruby
|
89
|
+
class UserSerializer < EasySerializer::Base
|
90
|
+
attribute :name, key: :named
|
91
|
+
attribute(:surname, key: :lastname) { |user| user.surname.capitalize }
|
92
|
+
end
|
93
|
+
```
|
94
|
+
|
95
|
+
### Serializing attributes with serializer
|
96
|
+
|
97
|
+
```ruby
|
98
|
+
user = OpenStruct.new(
|
99
|
+
name: 'John',
|
100
|
+
surname: 'Doe',
|
101
|
+
address: OpenStruct.new(
|
102
|
+
street: 'Happy street',
|
103
|
+
country: 'Wonderland'
|
104
|
+
)
|
105
|
+
)
|
106
|
+
|
107
|
+
class AddressSerializer < EasySerializer::Base
|
108
|
+
attributes :street, :country
|
109
|
+
end
|
110
|
+
|
111
|
+
class UserSerializer < EasySerializer::Base
|
112
|
+
attributes :name, :surname
|
113
|
+
collection :address, serializer: AddressSerializer
|
114
|
+
end
|
115
|
+
|
116
|
+
UserSerializer.call(user)
|
117
|
+
# =>
|
118
|
+
{
|
119
|
+
name: 'John',
|
120
|
+
surname: 'Doe',
|
121
|
+
address: {
|
122
|
+
street: 'Happy street',
|
123
|
+
country: 'Wonderland'
|
124
|
+
}
|
125
|
+
}
|
126
|
+
```
|
127
|
+
|
128
|
+
**Removing keys from nested hashes:**
|
129
|
+
|
130
|
+
```ruby
|
131
|
+
class UserSerializer < EasySerializer::Base
|
132
|
+
attribute :name, :lastname
|
133
|
+
attribute :address,
|
134
|
+
key: false,
|
135
|
+
serializer: AddressSerializer
|
136
|
+
end
|
137
|
+
UserSerializer.call(user)
|
138
|
+
# =>
|
139
|
+
{
|
140
|
+
name: 'John',
|
141
|
+
surname: 'Doe',
|
142
|
+
street: 'Happy street',
|
143
|
+
country: 'Wonderland'
|
144
|
+
}
|
145
|
+
```
|
146
|
+
|
147
|
+
**Serializer option accepts a Proc:**
|
148
|
+
|
149
|
+
```ruby
|
150
|
+
class UserSerializer < EasySerializer::Base
|
151
|
+
attributes :name, :surname
|
152
|
+
attribute :address,
|
153
|
+
serializer: proc { |serializer| "#{serializer.klass_ins.name}Serializer" },
|
154
|
+
cache: true
|
155
|
+
end
|
156
|
+
```
|
157
|
+
|
158
|
+
### Collection Example:
|
159
|
+
|
160
|
+
```ruby
|
161
|
+
user = OpenStruct.new(
|
162
|
+
name: 'John',
|
163
|
+
surname: 'Doe',
|
164
|
+
emails: [
|
165
|
+
OpenStruct.new(address: 'hello@email.com', type: 'work')
|
166
|
+
]
|
167
|
+
)
|
168
|
+
|
169
|
+
class EmailSerializer < EasySerializer::Base
|
170
|
+
attributes :address, :type
|
171
|
+
end
|
172
|
+
|
173
|
+
class UserSerializer < EasySerializer::Base
|
174
|
+
attributes :name, :surname
|
175
|
+
collection :emails, serializer: EmailSerializer
|
176
|
+
end
|
177
|
+
|
178
|
+
UserSerializer.call(user)
|
179
|
+
# =>
|
180
|
+
{
|
181
|
+
name: 'John',
|
182
|
+
surname: 'Doe',
|
183
|
+
emails: [ { address: 'hello@email.com', type: 'work' } ]
|
184
|
+
}
|
185
|
+
```
|
186
|
+
|
187
|
+
### Cache
|
188
|
+
|
189
|
+
**Important** cache will only work if is set in the configuration file.
|
190
|
+
|
191
|
+
**Caching the serialized object:**
|
192
|
+
|
193
|
+
Serialization will happen only once and the result hash will be stored in the cache.
|
194
|
+
|
195
|
+
```ruby
|
196
|
+
class UserSerializer < EasySerializer::Base
|
197
|
+
cache true
|
198
|
+
attributes :name, :surname
|
199
|
+
end
|
200
|
+
```
|
201
|
+
|
202
|
+
**Caching attributes:**
|
203
|
+
|
204
|
+
Attributes can be cached independently.
|
205
|
+
|
206
|
+
```ruby
|
207
|
+
class UserSerializer < EasySerializer::Base
|
208
|
+
attributes :name, :surname
|
209
|
+
attribute :costly_query, cache: true
|
210
|
+
end
|
211
|
+
```
|
212
|
+
|
213
|
+
of course it works with blocks:
|
214
|
+
|
215
|
+
```ruby
|
216
|
+
class UserSerializer < EasySerializer::Base
|
217
|
+
attributes :name, :surname
|
218
|
+
attribute(:costly_query, cache: true) do |user|
|
219
|
+
user.best_friends
|
220
|
+
end
|
221
|
+
end
|
222
|
+
```
|
223
|
+
|
224
|
+
**Caching Collections:**
|
225
|
+
|
226
|
+
Cache will try to fetch the cached object in the collection **one by one, the whole collection is not cached**.
|
227
|
+
|
228
|
+
```ruby
|
229
|
+
class UserSerializer < EasySerializer::Base
|
230
|
+
attributes :name, :surname
|
231
|
+
collection :address, serializer: AddressSerializer, cache: true
|
232
|
+
end
|
233
|
+
```
|
234
|
+
|
235
|
+
### Complex example using all features:
|
236
|
+
|
25
237
|
```ruby
|
26
238
|
class PolymorphicSerializer < EasySerializer::Base
|
27
239
|
cache true
|
@@ -36,7 +248,7 @@ class PolymorphicSerializer < EasySerializer::Base
|
|
36
248
|
|
37
249
|
attribute :subject,
|
38
250
|
key: false,
|
39
|
-
serializer: proc {|serializer| serializer.serializer_for_subject },
|
251
|
+
serializer: proc { |serializer| serializer.serializer_for_subject },
|
40
252
|
cache: true
|
41
253
|
collection :elements, serializer: ElementsSerializer, cache: true
|
42
254
|
|
@@ -49,8 +261,8 @@ end
|
|
49
261
|
```
|
50
262
|
|
51
263
|
```ruby
|
52
|
-
PolymorphicSerializer.
|
53
|
-
# => Hash with the object serialized
|
264
|
+
PolymorphicSerializer.call(Polymorphic.last)
|
265
|
+
# => Hash with the object serialized
|
54
266
|
```
|
55
267
|
|
56
268
|
## Development
|
@@ -61,7 +273,7 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
|
|
61
273
|
|
62
274
|
## Contributing
|
63
275
|
|
64
|
-
Bug reports and pull requests are welcome on GitHub at https://github.com/
|
276
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/arturictus/easy_serializer. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](contributor-covenant.org) code of conduct.
|
65
277
|
|
66
278
|
|
67
279
|
## License
|
data/bin/console
CHANGED
@@ -7,8 +7,8 @@ require "easy_serializer"
|
|
7
7
|
# with your gem easier. You can also use a different console, if you like.
|
8
8
|
|
9
9
|
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
-
|
11
|
-
|
10
|
+
require "pry"
|
11
|
+
Pry.start
|
12
12
|
|
13
|
-
require "irb"
|
14
|
-
IRB.start
|
13
|
+
# require "irb"
|
14
|
+
# IRB.start
|
data/lib/easy_serializer/base.rb
CHANGED
@@ -7,6 +7,14 @@ module EasySerializer
|
|
7
7
|
end
|
8
8
|
|
9
9
|
class << self
|
10
|
+
|
11
|
+
def call(obj)
|
12
|
+
new(obj).serialize
|
13
|
+
end
|
14
|
+
alias_method :serialize, :call
|
15
|
+
alias_method :to_hash, :call
|
16
|
+
alias_method :to_h, :call
|
17
|
+
|
10
18
|
def attribute(name, opts = {}, &block)
|
11
19
|
@__serializable_attributes ||= []
|
12
20
|
@__serializable_attributes << { name: name, block: block }.merge(opts)
|
@@ -76,16 +84,24 @@ module EasySerializer
|
|
76
84
|
end
|
77
85
|
|
78
86
|
def attr_serializer(setup)
|
79
|
-
|
80
|
-
content = klass_ins.send(setup[:name])
|
87
|
+
content = cache_or_attribute(klass_ins, setup)
|
81
88
|
return content unless serializer = setup[:serializer]
|
82
89
|
if setup[:collection]
|
83
|
-
content.map { |o| cache_or_serialize(serializer, o, setup) }
|
90
|
+
Array.wrap(content).map { |o| cache_or_serialize(serializer, o, setup) }
|
84
91
|
else
|
85
92
|
cache_or_serialize(serializer, content, setup)
|
86
93
|
end
|
87
94
|
end
|
88
95
|
|
96
|
+
def cache_or_attribute(obj, setup)
|
97
|
+
execute = setup[:block] || proc { |o| o.send(setup[:name]) }
|
98
|
+
if EasySerializer.perform_caching && setup[:cache] && !setup[:serializer]
|
99
|
+
EasySerializer.cache.fetch(obj, setup[:name]) { execute.call(obj) }
|
100
|
+
else
|
101
|
+
execute.call(obj)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
89
105
|
def cache_or_serialize(serializer, content, opts)
|
90
106
|
return unless content
|
91
107
|
if EasySerializer.perform_caching && opts[:cache]
|
@@ -95,7 +111,7 @@ module EasySerializer
|
|
95
111
|
[content, 'EasySerialized']
|
96
112
|
end
|
97
113
|
# Be Aware
|
98
|
-
# We are
|
114
|
+
# We are caching the serialized object
|
99
115
|
EasySerializer.cache.fetch(key) { send_to_serializer(serializer, content) }
|
100
116
|
else
|
101
117
|
send_to_serializer(serializer, content)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: easy_serializer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Artur Pañach
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2016-01-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|