shreddies 0.2.0 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1f3a9878d5d25ca7eb02bc3d9f3e4e4dc6f71ab6f970312331ed01fe864923b4
4
- data.tar.gz: bfba9356df3012c94527f1214d1862c5a507f91aab243f43fc85c8a30b0d50e3
3
+ metadata.gz: 5d29eb71728861282bd3c4a7e04ee829c4d647962951dfc494b311146142a84b
4
+ data.tar.gz: 9281b757f6ac85f5d17879b54b4554a7cf4ea5853c04420f52a4755080157092
5
5
  SHA512:
6
- metadata.gz: '069be646751138acce14f15960e417c18dcb2f57981a49b77d7d1a3a71ef4c2c079c49be4535c8ae193e752cb90298ddca0a72d5f51d12a9f2f2860c940a1e84'
7
- data.tar.gz: 8cf4dd148fe6ab7a6989e52462bc3fd3b14cddf592d17b45bd6470ec60f7482fe21e64a12af1909181bf789981b64a964b30f241e746ff3150de7bb4edfa3245
6
+ metadata.gz: 70f1959dbd3cd6a7e134c3fb4404a8d75ea55e219ba8e01eaba675bcfbbdc597fc0e85a12df4574e73617cb5aec946f67fcb3a077d73ccbf068d5ec158e82996
7
+ data.tar.gz: b8618164e87ad5d94279a5e9294ec7d975d2b96ec3966fe8b074f4733296b9c047348b718002942911442f9f4511a61909045baeccfb9d9705975c749ffa7fb7
data/Gemfile CHANGED
@@ -5,7 +5,7 @@ source 'https://rubygems.org'
5
5
  # Specify your gem's dependencies in shreddies.gemspec
6
6
  gemspec
7
7
 
8
- gem 'rake', '~> 12.0'
8
+ gem 'rake', '~> 13.0'
9
9
  gem 'minitest', '~> 5.0'
10
10
  gem 'autotest-suffix'
11
11
  gem 'minitest-autotest'
@@ -1,32 +1,32 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- shreddies (0.1.0)
4
+ shreddies (0.6.0)
5
5
  activerecord (>= 5)
6
6
  railties (>= 5)
7
7
 
8
8
  GEM
9
9
  remote: https://rubygems.org/
10
10
  specs:
11
- actionpack (6.0.3.2)
12
- actionview (= 6.0.3.2)
13
- activesupport (= 6.0.3.2)
11
+ actionpack (6.0.3.4)
12
+ actionview (= 6.0.3.4)
13
+ activesupport (= 6.0.3.4)
14
14
  rack (~> 2.0, >= 2.0.8)
15
15
  rack-test (>= 0.6.3)
16
16
  rails-dom-testing (~> 2.0)
17
17
  rails-html-sanitizer (~> 1.0, >= 1.2.0)
18
- actionview (6.0.3.2)
19
- activesupport (= 6.0.3.2)
18
+ actionview (6.0.3.4)
19
+ activesupport (= 6.0.3.4)
20
20
  builder (~> 3.1)
21
21
  erubi (~> 1.4)
22
22
  rails-dom-testing (~> 2.0)
23
23
  rails-html-sanitizer (~> 1.1, >= 1.2.0)
24
- activemodel (6.0.3.2)
25
- activesupport (= 6.0.3.2)
26
- activerecord (6.0.3.2)
27
- activemodel (= 6.0.3.2)
28
- activesupport (= 6.0.3.2)
29
- activesupport (6.0.3.2)
24
+ activemodel (6.0.3.4)
25
+ activesupport (= 6.0.3.4)
26
+ activerecord (6.0.3.4)
27
+ activemodel (= 6.0.3.4)
28
+ activesupport (= 6.0.3.4)
29
+ activesupport (6.0.3.4)
30
30
  concurrent-ruby (~> 1.0, >= 1.0.2)
31
31
  i18n (>= 0.7, < 2)
32
32
  minitest (~> 5.1)
@@ -34,21 +34,21 @@ GEM
34
34
  zeitwerk (~> 2.2, >= 2.2.2)
35
35
  autotest-suffix (1.1.0)
36
36
  builder (3.2.4)
37
- combustion (1.3.0)
37
+ combustion (1.3.1)
38
38
  activesupport (>= 3.0.0)
39
39
  railties (>= 3.0.0)
40
40
  thor (>= 0.14.6)
41
- concurrent-ruby (1.1.6)
41
+ concurrent-ruby (1.1.7)
42
42
  crass (1.0.6)
43
43
  erubi (1.9.0)
44
- i18n (1.8.3)
44
+ i18n (1.8.5)
45
45
  concurrent-ruby (~> 1.0)
46
- loofah (2.6.0)
46
+ loofah (2.7.0)
47
47
  crass (~> 1.0.2)
48
48
  nokogiri (>= 1.5.9)
49
49
  method_source (1.0.0)
50
50
  mini_portile2 (2.4.0)
51
- minitest (5.14.1)
51
+ minitest (5.14.2)
52
52
  minitest-autotest (1.1.1)
53
53
  minitest-server (~> 1.0)
54
54
  path_expander (~> 1.0)
@@ -56,7 +56,7 @@ GEM
56
56
  minitest (>= 4, < 6)
57
57
  minitest-server (1.0.6)
58
58
  minitest (~> 5.0)
59
- nokogiri (1.10.9)
59
+ nokogiri (1.10.10)
60
60
  mini_portile2 (~> 2.4.0)
61
61
  path_expander (1.1.0)
62
62
  rack (2.2.3)
@@ -67,19 +67,19 @@ GEM
67
67
  nokogiri (>= 1.6)
68
68
  rails-html-sanitizer (1.3.0)
69
69
  loofah (~> 2.3)
70
- railties (6.0.3.2)
71
- actionpack (= 6.0.3.2)
72
- activesupport (= 6.0.3.2)
70
+ railties (6.0.3.4)
71
+ actionpack (= 6.0.3.4)
72
+ activesupport (= 6.0.3.4)
73
73
  method_source
74
74
  rake (>= 0.8.7)
75
75
  thor (>= 0.20.3, < 2.0)
76
- rake (12.3.3)
76
+ rake (13.0.1)
77
77
  sqlite3 (1.4.2)
78
78
  thor (1.0.1)
79
79
  thread_safe (0.3.6)
80
- tzinfo (1.2.7)
80
+ tzinfo (1.2.8)
81
81
  thread_safe (~> 0.1)
82
- zeitwerk (2.3.1)
82
+ zeitwerk (2.4.1)
83
83
 
84
84
  PLATFORMS
85
85
  ruby
@@ -90,7 +90,7 @@ DEPENDENCIES
90
90
  minitest (~> 5.0)
91
91
  minitest-autotest
92
92
  minitest-focus
93
- rake (~> 12.0)
93
+ rake (~> 13.0)
94
94
  shreddies!
95
95
  sqlite3
96
96
 
data/README.md CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  Shreddies is a JSON serialization library for Rails that focuses on simplicity and speed. No more "magic" DSL's - just plain old Ruby objects! It's primarily intended to serialize Rails models as JSON, but will also work with pretty much anything at all.
4
4
 
5
+ Shreddies primary principle is to be explicit. So a serializer will return nothing until you define some methods. This gives you complete control and everything is a known quantity - no surprises.
6
+
5
7
  ## Installation
6
8
 
7
9
  Add this line to your application's Gemfile:
@@ -65,6 +67,8 @@ Model collections and array's are also supported:
65
67
  User.all.as_json
66
68
  ```
67
69
 
70
+ ### Collection and Single Modules
71
+
68
72
  You may find that you don't want or need to return as much data in collections of objects, or may want to include differtent data. So if a serializer defines a `Collection` module, and a collection or array is being rendered, then that Collection module will automatically be included:
69
73
 
70
74
  ```ruby
@@ -89,6 +93,40 @@ ArticleSerializer < Shreddies::Json
89
93
  end
90
94
  ```
91
95
 
96
+ ### ActiveRecord Associations
97
+
98
+ ActiveRecord associations are supported with no additional work on your part. Shreddies will simply call `#as_json` on any method that returns an ActiveRecord model or relation.
99
+
100
+ ```ruby
101
+ # app/serializers/user_serializer.rb
102
+ class UserSerializer < Shreddies::Json
103
+ delegate :articles
104
+
105
+ def latest_article
106
+ articles.latest
107
+ end
108
+ end
109
+ ```
110
+
111
+ And if you need to be specific about what you render, just call the serializer or `#as_json` directly:
112
+
113
+ ```ruby
114
+ # app/serializers/user_serializer.rb
115
+ class UserSerializer < Shreddies::Json
116
+ def articles
117
+ subject.articles.as_json index_by: :slug
118
+ end
119
+
120
+ def latest_article
121
+ LatestArticleSerializer.render articles.latest
122
+ end
123
+ end
124
+ ```
125
+
126
+ ### `before_render` callback
127
+
128
+ You can define a `#before_render` private method in your serializers, which will act as a callback. It receives the object to be output, and expects you to return the object, which allows you to modify it before rendering.
129
+
92
130
  ### Options
93
131
 
94
132
  Both `#as_json` and `.render` accepts an `options` hash, which will be forwarded to the serializer class, and available as `options`. This allows you to pass arbitrary options and use them in your serializer.
@@ -123,6 +161,28 @@ end
123
161
 
124
162
  The `Collection` and `Single` modules can be defined and they will be automatically included. The Collection module will be included when rendering an array or ActiveRecord collection (`ActiveRecord::Relation`), and the Single module will be included when rendering a single obejct.
125
163
 
164
+ #### `transform_keys` (default: true)
165
+
166
+ If false, the returned keys will not be transformed. The default is to deeply transform all keys to camelCase.
167
+
168
+ #### `except`
169
+
170
+ Pass one or more attribute names as a Symbol or Array of Symbols, and these will be excluded from the results:
171
+
172
+ ```ruby
173
+ User.all.as_json(except: [:first_name, :age])
174
+ ```
175
+
176
+ #### `only`
177
+
178
+ Pass one or more attribute names as a Symbol or Array of Symbols, and _ONLY_ these will be included in the results:
179
+
180
+ ```ruby
181
+ User.all.as_json(only: :first_name)
182
+ ```
183
+
184
+ > Attributes must still be defined within the Serializer.
185
+
126
186
  #### `index_by`
127
187
 
128
188
  Give this option a property of your serialized subject as a Symbol, and the returned collection will be a Hash keyed by that property.
@@ -44,11 +44,11 @@ module Shreddies
44
44
  super(*methods, to: to, prefix: prefix, allow_nil: allow_nil, private: private)
45
45
  end
46
46
 
47
- attr_reader :subject, :options, :from_collection
47
+ attr_reader :subject, :options
48
48
 
49
- def initialize(subject, options)
50
- @subject = subject
51
- @options = options
49
+ def initialize(subject, opts = {})
50
+ @subject = subject.is_a?(Hash) ? OpenStruct.new(subject) : subject
51
+ @options = { transform_keys: true }.merge(opts).with_indifferent_access
52
52
 
53
53
  extend_with_modules
54
54
  end
@@ -56,7 +56,7 @@ module Shreddies
56
56
  # Travel through the ancestors that are serializers (class name ends with "Serializer"), and
57
57
  # call all public instance methods, returning a hash.
58
58
  def as_json
59
- json = {}
59
+ output = {}.with_indifferent_access
60
60
  methods = Set.new(public_methods(false))
61
61
 
62
62
  self.class.ancestors.each do |ancestor|
@@ -65,22 +65,43 @@ module Shreddies
65
65
  end
66
66
  end
67
67
 
68
+ # Filter out methods using the `only` or `except` options.
69
+ if @options[:only]
70
+ @options[:only] = Array(@options[:only])
71
+ methods = methods.select { |x| @options[:only].include? x }
72
+ elsif @options[:except]
73
+ methods = methods.excluding(@options[:except])
74
+ end
75
+
68
76
  methods.map do |attr|
69
- json[attr.to_s.camelize :lower] = public_send(attr)
77
+ res = public_send(attr)
78
+ if res.is_a?(ActiveRecord::Relation) || res.is_a?(ActiveRecord::Base)
79
+ res = res.as_json(transform_keys: @options[:transform_keys])
80
+ end
81
+
82
+ output[attr] = res
70
83
  end
71
84
 
72
- json.deep_transform_keys { |key| key.to_s.camelize :lower }
85
+ output = before_render(output)
86
+
87
+ return output unless @options[:transform_keys]
88
+
89
+ output.deep_transform_keys { |key| key.to_s.camelize :lower }
73
90
  end
74
91
 
75
92
  private
76
93
 
94
+ def before_render(output)
95
+ output
96
+ end
97
+
77
98
  def extend_with_modules
78
99
  self.class.ancestors.reverse.each do |ancestor|
79
100
  next unless ancestor.to_s.end_with?('Serializer')
80
101
 
81
102
  # Extend with Collection module if it exists, and a collection is being rendered. Otherwise,
82
103
  # extend with the Single module if that exists.
83
- if options[:from_collection]
104
+ if @options[:from_collection]
84
105
  (collection_mod = "#{ancestor}::Collection".safe_constantize) && extend(collection_mod)
85
106
  else
86
107
  (single_mod = "#{ancestor}::Single".safe_constantize) && extend(single_mod)
@@ -88,11 +109,9 @@ module Shreddies
88
109
  end
89
110
 
90
111
  # Extend with the :module option if given.
91
- if options[:module]
92
- Array(options[:module]).each do |m|
93
- mod = m.is_a?(Module) ? m : "#{self.class}::#{m}".constantize
94
-
95
- extend mod
112
+ if @options[:module]
113
+ Array(@options[:module]).each do |m|
114
+ extend m.is_a?(Module) ? m : "#{self.class}::#{m}".constantize
96
115
  end
97
116
  end
98
117
  end
@@ -1,3 +1,3 @@
1
1
  module Shreddies
2
- VERSION = "0.2.0"
2
+ VERSION = "0.6.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: shreddies
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Joel Moss
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-07-14 00:00:00.000000000 Z
11
+ date: 2020-11-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -84,7 +84,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
84
84
  - !ruby/object:Gem::Version
85
85
  version: '0'
86
86
  requirements: []
87
- rubygems_version: 3.1.2
87
+ rubygems_version: 3.1.4
88
88
  signing_key:
89
89
  specification_version: 4
90
90
  summary: Stupid simple Rails model and object serializer