easy_serializer 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
[ ![Codeship Status for arturictus/easy_serializer](https://codeship.com/projects/5a101d20-6dda-0133-b7b2-666194911eaf/status?branch=master)](https://codeship.com/projects/115737)
|
4
|
+
[![Code Climate](https://codeclimate.com/github/arturictus/easy_serializer/badges/gpa.svg)](https://codeclimate.com/github/arturictus/easy_serializer)
|
5
|
+
[![Test Coverage](https://codeclimate.com/github/arturictus/easy_serializer/badges/coverage.svg)](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
|