adequate_serialization 1.0.0 → 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/push.yml +46 -0
- data/.mergify.yml +12 -0
- data/CHANGELOG.md +7 -2
- data/CODE_OF_CONDUCT.md +76 -0
- data/Gemfile +2 -2
- data/Gemfile.lock +92 -77
- data/LICENSE +1 -1
- data/README.md +41 -5
- data/adequate_serialization.gemspec +3 -2
- data/lib/adequate_serialization.rb +16 -2
- data/lib/adequate_serialization/attribute.rb +12 -0
- data/lib/adequate_serialization/inline_serializer.rb +8 -1
- data/lib/adequate_serialization/options.rb +1 -1
- data/lib/adequate_serialization/rails/cache_busting.rb +119 -0
- data/lib/adequate_serialization/rails/cache_refresh.rb +60 -0
- data/lib/adequate_serialization/rails/cache_visualization.rb +97 -0
- data/lib/adequate_serialization/rails/static/favicon.ico +0 -0
- data/lib/adequate_serialization/rails/static/index.html.erb +45 -0
- data/lib/adequate_serialization/serializer.rb +23 -0
- data/lib/adequate_serialization/version.rb +1 -1
- metadata +29 -8
- data/.github/main.workflow +0 -40
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 03131aa7cf99954e57efd860d550cf64fa3d796fa4a7c5b549dc160a75059e26
|
4
|
+
data.tar.gz: 34ad30c7accb106bd39e6682eaf0cd80f3cd4c7b22d8506aa25365ea1798886e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4177f51b69b61fc4a0f0eab2b1bbf4e4492683205790720745cdce8473c9cef662d78b92b03201a107fb7d36e3328a882ad9c68f8d8c78056f83fca3b667e61e
|
7
|
+
data.tar.gz: fa4c554c06075a3a57af62e092169fdd669d57ee98d38f1699178ad341f2341886fa2dcb0af64fe45f09b48c79496f47da9bde86ec28e3b625b68d934297db58
|
@@ -0,0 +1,46 @@
|
|
1
|
+
on: push
|
2
|
+
name: Push
|
3
|
+
jobs:
|
4
|
+
test:
|
5
|
+
name: Test
|
6
|
+
runs-on: ubuntu-latest
|
7
|
+
steps:
|
8
|
+
- uses: actions/checkout@master
|
9
|
+
- name: Install
|
10
|
+
uses: docker://culturehq/actions-bundler:latest
|
11
|
+
with:
|
12
|
+
args: install
|
13
|
+
- name: Test
|
14
|
+
uses: docker://culturehq/actions-bundler:latest
|
15
|
+
with:
|
16
|
+
args: exec rake test
|
17
|
+
lint:
|
18
|
+
name: Lint
|
19
|
+
runs-on: ubuntu-latest
|
20
|
+
steps:
|
21
|
+
- uses: actions/checkout@master
|
22
|
+
- name: Install
|
23
|
+
uses: docker://culturehq/actions-bundler:latest
|
24
|
+
with:
|
25
|
+
args: install
|
26
|
+
- name: Lint
|
27
|
+
uses: docker://culturehq/actions-bundler:latest
|
28
|
+
with:
|
29
|
+
args: exec rubocop --parallel
|
30
|
+
audit:
|
31
|
+
name: Audit
|
32
|
+
runs-on: ubuntu-latest
|
33
|
+
steps:
|
34
|
+
- uses: actions/checkout@master
|
35
|
+
- name: Install
|
36
|
+
uses: docker://culturehq/actions-bundler:latest
|
37
|
+
with:
|
38
|
+
args: install
|
39
|
+
- name: Update
|
40
|
+
uses: docker://culturehq/actions-bundler:latest
|
41
|
+
with:
|
42
|
+
args: exec bundle audit --update
|
43
|
+
- name: Audit
|
44
|
+
uses: docker://culturehq/actions-bundler:latest
|
45
|
+
with:
|
46
|
+
args: exec bundle audit
|
data/.mergify.yml
ADDED
data/CHANGELOG.md
CHANGED
@@ -6,6 +6,10 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) a
|
|
6
6
|
|
7
7
|
## [Unreleased]
|
8
8
|
|
9
|
+
## [1.0.1] - 2019-12-31
|
10
|
+
### Changed
|
11
|
+
- Fix up Ruby 2.7 warnings.
|
12
|
+
|
9
13
|
## [1.0.0] - 2019-03-25
|
10
14
|
### Added
|
11
15
|
- The ability to define serializers inline in the object they're serializing.
|
@@ -20,6 +24,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) a
|
|
20
24
|
### Changed
|
21
25
|
- No longer trigger another query when the `ActiveRecord` relation being serialized isn't loaded.
|
22
26
|
|
23
|
-
[
|
27
|
+
[unreleased]: https://github.com/CultureHQ/adequate_serialization/compare/v1.0.1...HEAD
|
28
|
+
[1.0.1]: https://github.com/CultureHQ/adequate_serialization/compare/v1.0.0...v1.0.1
|
24
29
|
[1.0.0]: https://github.com/CultureHQ/adequate_serialization/compare/v0.1.1...v1.0.0
|
25
|
-
[0.1.1]: https://github.com/CultureHQ/adequate_serialization/compare/
|
30
|
+
[0.1.1]: https://github.com/CultureHQ/adequate_serialization/compare/fcc7c7...v0.1.1
|
data/CODE_OF_CONDUCT.md
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
# Contributor Covenant Code of Conduct
|
2
|
+
|
3
|
+
## Our Pledge
|
4
|
+
|
5
|
+
In the interest of fostering an open and welcoming environment, we as
|
6
|
+
contributors and maintainers pledge to making participation in our project and
|
7
|
+
our community a harassment-free experience for everyone, regardless of age, body
|
8
|
+
size, disability, ethnicity, sex characteristics, gender identity and expression,
|
9
|
+
level of experience, education, socio-economic status, nationality, personal
|
10
|
+
appearance, race, religion, or sexual identity and orientation.
|
11
|
+
|
12
|
+
## Our Standards
|
13
|
+
|
14
|
+
Examples of behavior that contributes to creating a positive environment
|
15
|
+
include:
|
16
|
+
|
17
|
+
- Using welcoming and inclusive language
|
18
|
+
- Being respectful of differing viewpoints and experiences
|
19
|
+
- Gracefully accepting constructive criticism
|
20
|
+
- Focusing on what is best for the community
|
21
|
+
- Showing empathy towards other community members
|
22
|
+
|
23
|
+
Examples of unacceptable behavior by participants include:
|
24
|
+
|
25
|
+
- The use of sexualized language or imagery and unwelcome sexual attention or
|
26
|
+
advances
|
27
|
+
- Trolling, insulting/derogatory comments, and personal or political attacks
|
28
|
+
- Public or private harassment
|
29
|
+
- Publishing others' private information, such as a physical or electronic
|
30
|
+
address, without explicit permission
|
31
|
+
- Other conduct which could reasonably be considered inappropriate in a
|
32
|
+
professional setting
|
33
|
+
|
34
|
+
## Our Responsibilities
|
35
|
+
|
36
|
+
Project maintainers are responsible for clarifying the standards of acceptable
|
37
|
+
behavior and are expected to take appropriate and fair corrective action in
|
38
|
+
response to any instances of unacceptable behavior.
|
39
|
+
|
40
|
+
Project maintainers have the right and responsibility to remove, edit, or
|
41
|
+
reject comments, commits, code, wiki edits, issues, and other contributions
|
42
|
+
that are not aligned to this Code of Conduct, or to ban temporarily or
|
43
|
+
permanently any contributor for other behaviors that they deem inappropriate,
|
44
|
+
threatening, offensive, or harmful.
|
45
|
+
|
46
|
+
## Scope
|
47
|
+
|
48
|
+
This Code of Conduct applies both within project spaces and in public spaces
|
49
|
+
when an individual is representing the project or its community. Examples of
|
50
|
+
representing a project or community include using an official project e-mail
|
51
|
+
address, posting via an official social media account, or acting as an appointed
|
52
|
+
representative at an online or offline event. Representation of a project may be
|
53
|
+
further defined and clarified by project maintainers.
|
54
|
+
|
55
|
+
## Enforcement
|
56
|
+
|
57
|
+
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
58
|
+
reported by contacting the project team at support@culturehq.com. All
|
59
|
+
complaints will be reviewed and investigated and will result in a response that
|
60
|
+
is deemed necessary and appropriate to the circumstances. The project team is
|
61
|
+
obligated to maintain confidentiality with regard to the reporter of an incident.
|
62
|
+
Further details of specific enforcement policies may be posted separately.
|
63
|
+
|
64
|
+
Project maintainers who do not follow or enforce the Code of Conduct in good
|
65
|
+
faith may face temporary or permanent repercussions as determined by other
|
66
|
+
members of the project's leadership.
|
67
|
+
|
68
|
+
## Attribution
|
69
|
+
|
70
|
+
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
|
71
|
+
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
|
72
|
+
|
73
|
+
[homepage]: https://www.contributor-covenant.org
|
74
|
+
|
75
|
+
For answers to common questions about this code of conduct, see
|
76
|
+
https://www.contributor-covenant.org/faq
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,69 +1,82 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
adequate_serialization (1.0.
|
4
|
+
adequate_serialization (1.0.1)
|
5
5
|
|
6
6
|
GEM
|
7
7
|
remote: https://rubygems.org/
|
8
8
|
specs:
|
9
|
-
actioncable (
|
10
|
-
actionpack (=
|
9
|
+
actioncable (6.0.2.1)
|
10
|
+
actionpack (= 6.0.2.1)
|
11
11
|
nio4r (~> 2.0)
|
12
12
|
websocket-driver (>= 0.6.1)
|
13
|
-
|
14
|
-
actionpack (=
|
15
|
-
|
16
|
-
|
13
|
+
actionmailbox (6.0.2.1)
|
14
|
+
actionpack (= 6.0.2.1)
|
15
|
+
activejob (= 6.0.2.1)
|
16
|
+
activerecord (= 6.0.2.1)
|
17
|
+
activestorage (= 6.0.2.1)
|
18
|
+
activesupport (= 6.0.2.1)
|
19
|
+
mail (>= 2.7.1)
|
20
|
+
actionmailer (6.0.2.1)
|
21
|
+
actionpack (= 6.0.2.1)
|
22
|
+
actionview (= 6.0.2.1)
|
23
|
+
activejob (= 6.0.2.1)
|
17
24
|
mail (~> 2.5, >= 2.5.4)
|
18
25
|
rails-dom-testing (~> 2.0)
|
19
|
-
actionpack (
|
20
|
-
actionview (=
|
21
|
-
activesupport (=
|
22
|
-
rack (~> 2.0)
|
26
|
+
actionpack (6.0.2.1)
|
27
|
+
actionview (= 6.0.2.1)
|
28
|
+
activesupport (= 6.0.2.1)
|
29
|
+
rack (~> 2.0, >= 2.0.8)
|
23
30
|
rack-test (>= 0.6.3)
|
24
31
|
rails-dom-testing (~> 2.0)
|
25
|
-
rails-html-sanitizer (~> 1.0, >= 1.0
|
26
|
-
|
27
|
-
|
32
|
+
rails-html-sanitizer (~> 1.0, >= 1.2.0)
|
33
|
+
actiontext (6.0.2.1)
|
34
|
+
actionpack (= 6.0.2.1)
|
35
|
+
activerecord (= 6.0.2.1)
|
36
|
+
activestorage (= 6.0.2.1)
|
37
|
+
activesupport (= 6.0.2.1)
|
38
|
+
nokogiri (>= 1.8.5)
|
39
|
+
actionview (6.0.2.1)
|
40
|
+
activesupport (= 6.0.2.1)
|
28
41
|
builder (~> 3.1)
|
29
42
|
erubi (~> 1.4)
|
30
43
|
rails-dom-testing (~> 2.0)
|
31
|
-
rails-html-sanitizer (~> 1.
|
32
|
-
activejob (
|
33
|
-
activesupport (=
|
44
|
+
rails-html-sanitizer (~> 1.1, >= 1.2.0)
|
45
|
+
activejob (6.0.2.1)
|
46
|
+
activesupport (= 6.0.2.1)
|
34
47
|
globalid (>= 0.3.6)
|
35
|
-
activemodel (
|
36
|
-
activesupport (=
|
37
|
-
activerecord (
|
38
|
-
activemodel (=
|
39
|
-
activesupport (=
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
activerecord (=
|
48
|
+
activemodel (6.0.2.1)
|
49
|
+
activesupport (= 6.0.2.1)
|
50
|
+
activerecord (6.0.2.1)
|
51
|
+
activemodel (= 6.0.2.1)
|
52
|
+
activesupport (= 6.0.2.1)
|
53
|
+
activestorage (6.0.2.1)
|
54
|
+
actionpack (= 6.0.2.1)
|
55
|
+
activejob (= 6.0.2.1)
|
56
|
+
activerecord (= 6.0.2.1)
|
44
57
|
marcel (~> 0.3.1)
|
45
|
-
activesupport (
|
58
|
+
activesupport (6.0.2.1)
|
46
59
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
47
60
|
i18n (>= 0.7, < 2)
|
48
61
|
minitest (~> 5.1)
|
49
62
|
tzinfo (~> 1.1)
|
50
|
-
|
63
|
+
zeitwerk (~> 2.2)
|
51
64
|
ast (2.4.0)
|
52
|
-
builder (3.2.
|
65
|
+
builder (3.2.4)
|
53
66
|
bundler-audit (0.6.1)
|
54
67
|
bundler (>= 1.2.0, < 3)
|
55
68
|
thor (~> 0.18)
|
56
69
|
concurrent-ruby (1.1.5)
|
57
|
-
crass (1.0.
|
58
|
-
docile (1.3.
|
59
|
-
erubi (1.
|
70
|
+
crass (1.0.5)
|
71
|
+
docile (1.3.2)
|
72
|
+
erubi (1.9.0)
|
60
73
|
globalid (0.4.2)
|
61
74
|
activesupport (>= 4.2.0)
|
62
|
-
i18n (1.
|
75
|
+
i18n (1.7.0)
|
63
76
|
concurrent-ruby (~> 1.0)
|
64
|
-
jaro_winkler (1.5.
|
77
|
+
jaro_winkler (1.5.4)
|
65
78
|
json (2.2.0)
|
66
|
-
loofah (2.
|
79
|
+
loofah (2.4.0)
|
67
80
|
crass (~> 1.0.2)
|
68
81
|
nokogiri (>= 1.5.9)
|
69
82
|
mail (2.7.1)
|
@@ -72,75 +85,76 @@ GEM
|
|
72
85
|
mimemagic (~> 0.3.2)
|
73
86
|
method_source (0.9.2)
|
74
87
|
mimemagic (0.3.3)
|
75
|
-
mini_mime (1.0.
|
88
|
+
mini_mime (1.0.2)
|
76
89
|
mini_portile2 (2.4.0)
|
77
|
-
minitest (5.
|
78
|
-
nio4r (2.
|
79
|
-
nokogiri (1.10.
|
90
|
+
minitest (5.13.0)
|
91
|
+
nio4r (2.5.2)
|
92
|
+
nokogiri (1.10.7)
|
80
93
|
mini_portile2 (~> 2.4.0)
|
81
|
-
parallel (1.
|
82
|
-
parser (2.6.
|
94
|
+
parallel (1.19.1)
|
95
|
+
parser (2.6.5.0)
|
83
96
|
ast (~> 2.4.0)
|
84
|
-
|
85
|
-
rack (2.0.6)
|
97
|
+
rack (2.0.8)
|
86
98
|
rack-test (1.1.0)
|
87
99
|
rack (>= 1.0, < 3)
|
88
|
-
rails (
|
89
|
-
actioncable (=
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
100
|
+
rails (6.0.2.1)
|
101
|
+
actioncable (= 6.0.2.1)
|
102
|
+
actionmailbox (= 6.0.2.1)
|
103
|
+
actionmailer (= 6.0.2.1)
|
104
|
+
actionpack (= 6.0.2.1)
|
105
|
+
actiontext (= 6.0.2.1)
|
106
|
+
actionview (= 6.0.2.1)
|
107
|
+
activejob (= 6.0.2.1)
|
108
|
+
activemodel (= 6.0.2.1)
|
109
|
+
activerecord (= 6.0.2.1)
|
110
|
+
activestorage (= 6.0.2.1)
|
111
|
+
activesupport (= 6.0.2.1)
|
98
112
|
bundler (>= 1.3.0)
|
99
|
-
railties (=
|
113
|
+
railties (= 6.0.2.1)
|
100
114
|
sprockets-rails (>= 2.0.0)
|
101
115
|
rails-dom-testing (2.0.3)
|
102
116
|
activesupport (>= 4.2.0)
|
103
117
|
nokogiri (>= 1.6)
|
104
|
-
rails-html-sanitizer (1.0
|
105
|
-
loofah (~> 2.
|
106
|
-
railties (
|
107
|
-
actionpack (=
|
108
|
-
activesupport (=
|
118
|
+
rails-html-sanitizer (1.3.0)
|
119
|
+
loofah (~> 2.3)
|
120
|
+
railties (6.0.2.1)
|
121
|
+
actionpack (= 6.0.2.1)
|
122
|
+
activesupport (= 6.0.2.1)
|
109
123
|
method_source
|
110
124
|
rake (>= 0.8.7)
|
111
|
-
thor (>= 0.
|
125
|
+
thor (>= 0.20.3, < 2.0)
|
112
126
|
rainbow (3.0.0)
|
113
|
-
rake (
|
114
|
-
rubocop (0.
|
127
|
+
rake (13.0.1)
|
128
|
+
rubocop (0.78.0)
|
115
129
|
jaro_winkler (~> 1.5.1)
|
116
130
|
parallel (~> 1.10)
|
117
|
-
parser (>= 2.
|
118
|
-
psych (>= 3.1.0)
|
131
|
+
parser (>= 2.6)
|
119
132
|
rainbow (>= 2.2.2, < 4.0)
|
120
133
|
ruby-progressbar (~> 1.7)
|
121
|
-
unicode-display_width (>= 1.4.0, < 1.
|
122
|
-
ruby-progressbar (1.10.
|
123
|
-
simplecov (0.
|
134
|
+
unicode-display_width (>= 1.4.0, < 1.7)
|
135
|
+
ruby-progressbar (1.10.1)
|
136
|
+
simplecov (0.17.1)
|
124
137
|
docile (~> 1.1)
|
125
138
|
json (>= 1.8, < 3)
|
126
139
|
simplecov-html (~> 0.10.0)
|
127
140
|
simplecov-html (0.10.2)
|
128
|
-
sprockets (
|
141
|
+
sprockets (4.0.0)
|
129
142
|
concurrent-ruby (~> 1.0)
|
130
143
|
rack (> 1, < 3)
|
131
144
|
sprockets-rails (3.2.1)
|
132
145
|
actionpack (>= 4.0)
|
133
146
|
activesupport (>= 4.0)
|
134
147
|
sprockets (>= 3.0.0)
|
135
|
-
sqlite3 (1.
|
148
|
+
sqlite3 (1.4.2)
|
136
149
|
thor (0.20.3)
|
137
150
|
thread_safe (0.3.6)
|
138
151
|
tzinfo (1.2.5)
|
139
152
|
thread_safe (~> 0.1)
|
140
|
-
unicode-display_width (1.
|
141
|
-
websocket-driver (0.7.
|
153
|
+
unicode-display_width (1.6.0)
|
154
|
+
websocket-driver (0.7.1)
|
142
155
|
websocket-extensions (>= 0.1.0)
|
143
|
-
websocket-extensions (0.1.
|
156
|
+
websocket-extensions (0.1.4)
|
157
|
+
zeitwerk (2.2.2)
|
144
158
|
|
145
159
|
PLATFORMS
|
146
160
|
ruby
|
@@ -150,11 +164,12 @@ DEPENDENCIES
|
|
150
164
|
bundler (~> 2)
|
151
165
|
bundler-audit (~> 0.6)
|
152
166
|
minitest (~> 5)
|
153
|
-
|
154
|
-
|
155
|
-
|
167
|
+
rack-test (~> 1.1)
|
168
|
+
rails (~> 6.0)
|
169
|
+
rake (~> 13)
|
170
|
+
rubocop (~> 0.70)
|
156
171
|
simplecov (~> 0.16)
|
157
|
-
sqlite3 (
|
172
|
+
sqlite3 (~> 1.4)
|
158
173
|
|
159
174
|
BUNDLED WITH
|
160
|
-
2.
|
175
|
+
2.1.2
|
data/LICENSE
CHANGED
data/README.md
CHANGED
@@ -1,8 +1,24 @@
|
|
1
1
|
# AdequateSerialization
|
2
2
|
|
3
|
+
[![Build Status](https://github.com/CultureHQ/adequate_serialization/workflows/Push/badge.svg)](https://github.com/CultureHQ/adequate_serialization/actions)
|
3
4
|
[![Gem Version](https://img.shields.io/gem/v/adequate_serialization.svg)](https://github.com/CultureHQ/adeqaute_serialization)
|
4
5
|
|
5
|
-
|
6
|
+
`AdequateSerialization` allows you to define serializers that will convert your objects into simple hashes that are suitable for variable purposes such as caching or using in an HTTP response. It stems from the simple idea of giving slightly more control over the `as_json` method that gets called when objects are serialized using Rails' default controller serialization.
|
7
|
+
|
8
|
+
- [Installation](#installation)
|
9
|
+
- [Usage](#usage)
|
10
|
+
- [Defining attributes](#defining-attributes)
|
11
|
+
- [:if](#if)
|
12
|
+
- [:unless](#unless)
|
13
|
+
- [:optional](#optional)
|
14
|
+
- [Attaching objects](#attaching-objects)
|
15
|
+
- [Usage with Rails](#usage-with-rails)
|
16
|
+
- [Cache busting](#cache-busting)
|
17
|
+
- [Caching plain objects](#caching-plain-objects)
|
18
|
+
- [Advanced](#advanced)
|
19
|
+
- [Development](#development)
|
20
|
+
- [Contributing](#contributing)
|
21
|
+
- [License](#license)
|
6
22
|
|
7
23
|
## Installation
|
8
24
|
|
@@ -132,11 +148,31 @@ This relies on the objects to which you are attaching having an `id` attribute a
|
|
132
148
|
|
133
149
|
### Usage with Rails
|
134
150
|
|
135
|
-
If `::Rails` is defined when `adequate_serialization` is required, it will hook into
|
151
|
+
If `::Rails` is defined when `adequate_serialization` is required, it will hook into `ActiveRecord` in three ways:
|
136
152
|
|
137
|
-
1. By
|
138
|
-
2. By
|
139
|
-
3. By
|
153
|
+
1. By including `AdequateSerializer::Serializable` in `ActiveRecord::Base` so that all of your models will be serializable by overwriting `ActiveRecord::Base`'s `as_json` method, which by default will use `Rails.cache.fetch`.
|
154
|
+
2. By overwriting `ActiveRecord::Relation`'s `as_json` method to use the `AdequateSerializer::Rails::RelationSerializer` object, which by default will use the `Rails.cache.fetch_multi` method in order to more efficiently serialize all of the records in the relation.
|
155
|
+
3. By introducing cache busting behavior in the background using `ActiveJob` if you're serializing objects outside of a one-to-many relationship.
|
156
|
+
|
157
|
+
#### Cache busting
|
158
|
+
|
159
|
+
When using `adequate_serialization` with `rails`, each `attribute` call will check if you're serializing an association. If you are, then it will ensure you have appropriate caching behavior enabled:
|
160
|
+
|
161
|
+
* If it's a `has_many` or `has_one` association, then it will make sure that the inverse has the `touch: true` option on the association.
|
162
|
+
* If it's a `belongs_to` association, then it will add an `after_update_commit` hook to the inverse class that will loop through the associated objects and bust the association using an `ActiveJob` task.
|
163
|
+
|
164
|
+
You can visualize this cache busting behavior with a prebaked Rack application that is shipped with this gem by adding the following to your `config/routes.rb` file:
|
165
|
+
|
166
|
+
```ruby
|
167
|
+
if Rails.env.development?
|
168
|
+
mount AdequateSerialization::Rails::CacheVisualization,
|
169
|
+
at: '/cache_visualization'
|
170
|
+
end
|
171
|
+
```
|
172
|
+
|
173
|
+
This will allow you to view which caches will bust which others in development by navigating to your application's `/cache_visualization` path.
|
174
|
+
|
175
|
+
#### Caching plain objects
|
140
176
|
|
141
177
|
You can still use plain objects to be serialized, and if you want to take advantage of the caching behavior, you can define a `cache_key` method on the objects that you're serializing. This will cause `AdequateSerialization` to start putting them into the Rails cache.
|
142
178
|
|
@@ -24,7 +24,8 @@ Gem::Specification.new do |spec|
|
|
24
24
|
spec.add_development_dependency 'bundler', '~> 2'
|
25
25
|
spec.add_development_dependency 'bundler-audit', '~> 0.6'
|
26
26
|
spec.add_development_dependency 'minitest', '~> 5'
|
27
|
-
spec.add_development_dependency '
|
28
|
-
spec.add_development_dependency '
|
27
|
+
spec.add_development_dependency 'rack-test', '~> 1.1'
|
28
|
+
spec.add_development_dependency 'rake', '~> 13'
|
29
|
+
spec.add_development_dependency 'rubocop', '~> 0.70'
|
29
30
|
spec.add_development_dependency 'simplecov', '~> 0.16'
|
30
31
|
end
|
@@ -1,5 +1,13 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
module AdequateSerialization
|
4
|
+
class Error < StandardError
|
5
|
+
def initialize(message)
|
6
|
+
super(message.gsub("\n", ' '))
|
7
|
+
end
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
3
11
|
require 'adequate_serialization/attribute'
|
4
12
|
require 'adequate_serialization/decorator'
|
5
13
|
require 'adequate_serialization/inline_serializer'
|
@@ -12,8 +20,14 @@ require 'adequate_serialization/version'
|
|
12
20
|
require 'adequate_serialization/steps/step'
|
13
21
|
require 'adequate_serialization/steps/serialize_step'
|
14
22
|
|
15
|
-
if defined?(
|
23
|
+
if defined?(Rails)
|
24
|
+
require 'adequate_serialization/rails/cache_busting'
|
16
25
|
require 'adequate_serialization/rails/cache_step'
|
26
|
+
require 'adequate_serialization/rails/cache_visualization'
|
17
27
|
require 'adequate_serialization/rails/relation_serializer'
|
18
|
-
|
28
|
+
|
29
|
+
module AdequateSerialization
|
30
|
+
Serializer.singleton_class.prepend(CacheBusting)
|
31
|
+
ActiveRecord::Base.include(Serializable)
|
32
|
+
end
|
19
33
|
end
|
@@ -46,6 +46,10 @@ module AdequateSerialization
|
|
46
46
|
@condition = condition
|
47
47
|
end
|
48
48
|
|
49
|
+
def name
|
50
|
+
attribute.name
|
51
|
+
end
|
52
|
+
|
49
53
|
def serialize_to(serializer, response, model, includes)
|
50
54
|
return unless model.public_send(condition)
|
51
55
|
|
@@ -61,6 +65,10 @@ module AdequateSerialization
|
|
61
65
|
@condition = condition
|
62
66
|
end
|
63
67
|
|
68
|
+
def name
|
69
|
+
attribute.name
|
70
|
+
end
|
71
|
+
|
64
72
|
def serialize_to(serializer, response, model, includes)
|
65
73
|
return if model.public_send(condition)
|
66
74
|
|
@@ -75,6 +83,10 @@ module AdequateSerialization
|
|
75
83
|
@attribute = attribute
|
76
84
|
end
|
77
85
|
|
86
|
+
def name
|
87
|
+
attribute.name
|
88
|
+
end
|
89
|
+
|
78
90
|
def serialize_to(serializer, response, model, includes)
|
79
91
|
return unless includes.include?(attribute.name)
|
80
92
|
|
@@ -37,9 +37,16 @@ module AdequateSerialization
|
|
37
37
|
def included(base)
|
38
38
|
base.include(Serializable)
|
39
39
|
|
40
|
+
serializer_class = Class.new(Serializer)
|
41
|
+
|
42
|
+
# In order to validate the attribute, we need to define the `serializes`
|
43
|
+
# method before we evaluate the block
|
44
|
+
serializer_class.define_singleton_method(:serializes) { base }
|
45
|
+
serializer_class.class_eval(&block)
|
46
|
+
|
40
47
|
# No need to memoize within the method because the block will hold on to
|
41
48
|
# local variables for us.
|
42
|
-
serializer =
|
49
|
+
serializer = serializer_class.new
|
43
50
|
base.define_singleton_method(:serializer) { serializer }
|
44
51
|
end
|
45
52
|
end
|
@@ -0,0 +1,119 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module AdequateSerialization
|
4
|
+
module CacheBusting
|
5
|
+
class InverseNotFoundError < StandardError
|
6
|
+
def initialize(record, association)
|
7
|
+
super(<<~MSG)
|
8
|
+
In order to be able to bust the associated cache for #{record}'s
|
9
|
+
`#{association}` association, that association must have an inverse.
|
10
|
+
Currently it doesn't, which means Rails was unable to determine the
|
11
|
+
name of the inverse association. You can fix this by adding the
|
12
|
+
inverse_of option to the association declaration.
|
13
|
+
MSG
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
class TouchNotFoundError < StandardError
|
18
|
+
def initialize(record, associated, inverse)
|
19
|
+
super(<<~MSG)
|
20
|
+
#{record} serializes all of the associated #{associated} records,
|
21
|
+
which means when #{associated} updates it needs to notify #{record} in
|
22
|
+
order to bust the cache. This can be accomplished by adding the
|
23
|
+
`touch: true` option to #{associated}'s #{inverse} association.
|
24
|
+
MSG
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
class ActiveJobNotFoundError < Error
|
29
|
+
def initialize(record, association)
|
30
|
+
super(<<~MSG)
|
31
|
+
In order to be able to bust the associated cache for #{record}'s
|
32
|
+
`#{association}` association, AdequateSerialization enqueues a
|
33
|
+
background job (since there are potentially multiple records on the
|
34
|
+
association). In order to use the background job, it must have access
|
35
|
+
to ActiveJob.
|
36
|
+
MSG
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
using(
|
41
|
+
Module.new do
|
42
|
+
refine ActiveRecord::Base.singleton_class do
|
43
|
+
def setup_serialize_association(association_name)
|
44
|
+
unless defined?(ActiveJob)
|
45
|
+
raise ActiveJobNotFoundError.new(name, association_name)
|
46
|
+
end
|
47
|
+
|
48
|
+
require 'adequate_serialization/rails/cache_refresh'
|
49
|
+
extend(CacheRefresh) unless respond_to?(:serialize_association)
|
50
|
+
|
51
|
+
serialize_association(association_name)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
refine ActiveRecord::Reflection::AssociationReflection do
|
56
|
+
def setup
|
57
|
+
# If the association is polymorphic, we can't rely on the inverse
|
58
|
+
# to tell us information about cache busting because there are
|
59
|
+
# multiple inverse associations.
|
60
|
+
return if polymorphic?
|
61
|
+
|
62
|
+
unless inverse_of
|
63
|
+
raise InverseNotFoundError.new(active_record.name, name)
|
64
|
+
end
|
65
|
+
|
66
|
+
inverse_of.macro == :belongs_to ? setup_belongs_to : setup_has_some
|
67
|
+
end
|
68
|
+
|
69
|
+
private
|
70
|
+
|
71
|
+
# Ensures that the `belongs_to` association has the `touch` option
|
72
|
+
# enabled in order to bust the parent's cache
|
73
|
+
def setup_belongs_to
|
74
|
+
return if inverse_of.options[:touch]
|
75
|
+
|
76
|
+
record = active_record.name
|
77
|
+
raise TouchNotFoundError.new(record, klass.name, inverse_of.name)
|
78
|
+
end
|
79
|
+
|
80
|
+
# Hooks into the serialized class and adds cache busting behavior on
|
81
|
+
# commit that will loop through the associated records
|
82
|
+
def setup_has_some
|
83
|
+
active_record.setup_serialize_association(name)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
refine ActiveRecord::Reflection::ThroughReflection do
|
88
|
+
def setup
|
89
|
+
unless inverse_of
|
90
|
+
raise InverseNotFoundError.new(active_record.name, name)
|
91
|
+
end
|
92
|
+
|
93
|
+
klass.setup_serialize_association(inverse_of.name)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
)
|
98
|
+
|
99
|
+
# Used as a shim for the `setup` API in the case that an attribute on the
|
100
|
+
# serializer does not represent an association.
|
101
|
+
module NullAssociation
|
102
|
+
def self.setup; end
|
103
|
+
end
|
104
|
+
|
105
|
+
# Overrides the previous `attribute` declaration to add some addition
|
106
|
+
# validation in the case that we're serializing an ActiveRecord object.
|
107
|
+
def attribute(*names, &block)
|
108
|
+
record = serializes
|
109
|
+
|
110
|
+
if record < ActiveRecord::Base
|
111
|
+
(names.last.is_a?(Hash) ? names[0..-2] : names).each do |attribute|
|
112
|
+
(record.reflect_on_association(attribute) || NullAssociation).setup
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
super
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module AdequateSerialization
|
4
|
+
module CacheRefresh
|
5
|
+
class CacheRefreshJob < ActiveJob::Base
|
6
|
+
using(
|
7
|
+
Module.new do
|
8
|
+
# The association will return a relation if it's a `has_many` or a
|
9
|
+
# `has_many_through` regardless of how many associated records exist.
|
10
|
+
refine ActiveRecord::Relation do
|
11
|
+
def refresh
|
12
|
+
return unless any?
|
13
|
+
|
14
|
+
update_all(updated_at: Time.now)
|
15
|
+
find_each(&:as_json)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
# The association will return a record if it's a `has_one` and it was
|
20
|
+
# previously created.
|
21
|
+
refine ActiveRecord::Base do
|
22
|
+
def refresh
|
23
|
+
touch
|
24
|
+
as_json
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
# The association will return a `nil` if it's a `has_one` and it was
|
29
|
+
# not yet created.
|
30
|
+
refine NilClass do
|
31
|
+
def refresh; end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
)
|
35
|
+
|
36
|
+
queue_as :default
|
37
|
+
discard_on ActiveJob::DeserializationError
|
38
|
+
|
39
|
+
def perform(record)
|
40
|
+
record.class.serialized_associations.each do |association|
|
41
|
+
record.public_send(association).refresh
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def self.extended(base)
|
47
|
+
base.after_update_commit { CacheRefreshJob.perform_later(self) }
|
48
|
+
end
|
49
|
+
|
50
|
+
def serialize_association(association)
|
51
|
+
serialized_associations << association
|
52
|
+
end
|
53
|
+
|
54
|
+
# The associations that serialize this object in their responses, so that we
|
55
|
+
# know to bust their cache when this object is updated.
|
56
|
+
def serialized_associations
|
57
|
+
@serialized_associations ||= []
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module AdequateSerialization
|
4
|
+
module Rails
|
5
|
+
class CacheVisualization
|
6
|
+
using(
|
7
|
+
Module.new do
|
8
|
+
refine ActiveRecord::Reflection::AbstractReflection do
|
9
|
+
def to_dot
|
10
|
+
"#{klass.name} -> #{active_record.name} [label=\"#{name}\"];"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
)
|
15
|
+
|
16
|
+
STATIC = File.expand_path('static', __dir__)
|
17
|
+
FILES = %w[/favicon.ico].freeze
|
18
|
+
|
19
|
+
attr_reader :app, :server
|
20
|
+
|
21
|
+
def initialize
|
22
|
+
@server = Rack::File.new(STATIC)
|
23
|
+
end
|
24
|
+
|
25
|
+
def call(env)
|
26
|
+
if env[Rack::PATH_INFO] == '/'
|
27
|
+
render_index(env)
|
28
|
+
elsif FILES.include?(env[Rack::PATH_INFO])
|
29
|
+
server.call(env)
|
30
|
+
else
|
31
|
+
[404, { 'Content-Type' => 'text/plain' }, ['Not Found']]
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.call(env)
|
36
|
+
(@app ||= new).call(env)
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def to_dot
|
42
|
+
<<~EODOT
|
43
|
+
digraph attributes {
|
44
|
+
node [shape = circle];
|
45
|
+
#{reflections.map(&:to_dot).join("\n ")}
|
46
|
+
}
|
47
|
+
EODOT
|
48
|
+
end
|
49
|
+
|
50
|
+
def to_svg
|
51
|
+
svg =
|
52
|
+
IO.popen('dot -Tsvg', 'w+') do |f|
|
53
|
+
f.write(to_dot)
|
54
|
+
f.close_write
|
55
|
+
f.readlines
|
56
|
+
end
|
57
|
+
|
58
|
+
3.times { svg.shift }
|
59
|
+
svg.join.gsub(/(height|width)="[^"]*"/, '')
|
60
|
+
end
|
61
|
+
|
62
|
+
def render_index(env)
|
63
|
+
content = File.read(File.join(STATIC, 'index.html.erb'))
|
64
|
+
locals = { svg: to_svg, script_name: env[Rack::SCRIPT_NAME] }
|
65
|
+
|
66
|
+
result = ERB.new(content).result_with_hash(locals)
|
67
|
+
[200, { 'Content-Type' => 'text/html' }, [result]]
|
68
|
+
end
|
69
|
+
|
70
|
+
def serializers
|
71
|
+
::Rails.application.eager_load!
|
72
|
+
base = Serializer
|
73
|
+
|
74
|
+
ObjectSpace.each_object(base.singleton_class).select do |serializer|
|
75
|
+
serializer < base &&
|
76
|
+
serializer.name &&
|
77
|
+
serializer.serializes < ActiveRecord::Base
|
78
|
+
rescue AdequateSerialization::Serializer::ClassNotFoundError
|
79
|
+
false
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def reflections
|
84
|
+
serializers.each_with_object([]) do |serializer, selected|
|
85
|
+
serializer.attributes.each do |attribute|
|
86
|
+
serializes = serializer.serializes
|
87
|
+
reflection = serializes.reflect_on_association(attribute.name)
|
88
|
+
|
89
|
+
next if !reflection || reflection.polymorphic?
|
90
|
+
|
91
|
+
selected << reflection
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
Binary file
|
@@ -0,0 +1,45 @@
|
|
1
|
+
<!doctype html>
|
2
|
+
<html lang="en">
|
3
|
+
<head>
|
4
|
+
<meta charset="utf-8">
|
5
|
+
<meta name="viewport" content="initial-scale=1, maximum-scale=5">
|
6
|
+
<title>AdequateSerialization</title>
|
7
|
+
<link rel="shortcut icon" href="favicon.ico">
|
8
|
+
<style type="text/css">
|
9
|
+
html,
|
10
|
+
body {
|
11
|
+
font-family: Verdana, Geneva, sans-serif;
|
12
|
+
line-height: 1.2em;
|
13
|
+
margin: 0;
|
14
|
+
padding: 0;
|
15
|
+
}
|
16
|
+
|
17
|
+
main {
|
18
|
+
padding: 0 1em 1em;
|
19
|
+
}
|
20
|
+
</style>
|
21
|
+
</head>
|
22
|
+
<body data-script="<%= script_name %>">
|
23
|
+
<main>
|
24
|
+
<h1>AdequateSerialization</h1>
|
25
|
+
<p>
|
26
|
+
Below is a visualization of the associations that you are serializing.
|
27
|
+
The arrows represent which cache will get busted when you update an
|
28
|
+
object.
|
29
|
+
</p>
|
30
|
+
<p>
|
31
|
+
For instance, if you have an arrow pointing from
|
32
|
+
<code>Post</code> to <code>Comment</code>, it would mean that when
|
33
|
+
<code>Comment</code> objects are serialized they are serializing
|
34
|
+
<code>Post</code> objects as part of their response. In this case
|
35
|
+
<code>Post</code> objects need to bust the cache of their associated
|
36
|
+
<code>Comment</code> objects when they are updated.
|
37
|
+
<code>AdequateSerialization</code> takes care of this by enqueuing a
|
38
|
+
background job.
|
39
|
+
</p>
|
40
|
+
<div id="svg">
|
41
|
+
<%= svg %>
|
42
|
+
</div>
|
43
|
+
</main>
|
44
|
+
</body>
|
45
|
+
</html>
|
@@ -2,6 +2,17 @@
|
|
2
2
|
|
3
3
|
module AdequateSerialization
|
4
4
|
class Serializer
|
5
|
+
class ClassNotFoundError < Error
|
6
|
+
def initialize(serializer, serializes)
|
7
|
+
super(<<~MSG)
|
8
|
+
AdequateSerialization was unable to find the associated class to
|
9
|
+
serialize for #{serializer}. It expected to find a class named
|
10
|
+
#{serializes}. This could mean that it was incorrectly named, or that
|
11
|
+
you have yet to create the class that it will serialize.
|
12
|
+
MSG
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
5
16
|
class << self
|
6
17
|
def attributes
|
7
18
|
@attributes ||= []
|
@@ -20,6 +31,18 @@ module AdequateSerialization
|
|
20
31
|
|
21
32
|
@attributes = attributes + additions
|
22
33
|
end
|
34
|
+
|
35
|
+
def serializes
|
36
|
+
return @serializes if defined?(@serializes)
|
37
|
+
|
38
|
+
class_name = name.gsub(/Serializer\z/, '')
|
39
|
+
|
40
|
+
begin
|
41
|
+
@serializes = const_get(class_name)
|
42
|
+
rescue NameError
|
43
|
+
raise ClassNotFoundError.new(name, class_name)
|
44
|
+
end
|
45
|
+
end
|
23
46
|
end
|
24
47
|
|
25
48
|
def serialize(model, opts = Options.null)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: adequate_serialization
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kevin Deisz
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-
|
11
|
+
date: 2019-12-31 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -52,34 +52,48 @@ dependencies:
|
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '5'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rack-test
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '1.1'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '1.1'
|
55
69
|
- !ruby/object:Gem::Dependency
|
56
70
|
name: rake
|
57
71
|
requirement: !ruby/object:Gem::Requirement
|
58
72
|
requirements:
|
59
73
|
- - "~>"
|
60
74
|
- !ruby/object:Gem::Version
|
61
|
-
version: '
|
75
|
+
version: '13'
|
62
76
|
type: :development
|
63
77
|
prerelease: false
|
64
78
|
version_requirements: !ruby/object:Gem::Requirement
|
65
79
|
requirements:
|
66
80
|
- - "~>"
|
67
81
|
- !ruby/object:Gem::Version
|
68
|
-
version: '
|
82
|
+
version: '13'
|
69
83
|
- !ruby/object:Gem::Dependency
|
70
84
|
name: rubocop
|
71
85
|
requirement: !ruby/object:Gem::Requirement
|
72
86
|
requirements:
|
73
87
|
- - "~>"
|
74
88
|
- !ruby/object:Gem::Version
|
75
|
-
version: '0.
|
89
|
+
version: '0.70'
|
76
90
|
type: :development
|
77
91
|
prerelease: false
|
78
92
|
version_requirements: !ruby/object:Gem::Requirement
|
79
93
|
requirements:
|
80
94
|
- - "~>"
|
81
95
|
- !ruby/object:Gem::Version
|
82
|
-
version: '0.
|
96
|
+
version: '0.70'
|
83
97
|
- !ruby/object:Gem::Dependency
|
84
98
|
name: simplecov
|
85
99
|
requirement: !ruby/object:Gem::Requirement
|
@@ -101,10 +115,12 @@ executables: []
|
|
101
115
|
extensions: []
|
102
116
|
extra_rdoc_files: []
|
103
117
|
files:
|
104
|
-
- ".github/
|
118
|
+
- ".github/workflows/push.yml"
|
105
119
|
- ".gitignore"
|
120
|
+
- ".mergify.yml"
|
106
121
|
- ".rubocop.yml"
|
107
122
|
- CHANGELOG.md
|
123
|
+
- CODE_OF_CONDUCT.md
|
108
124
|
- Gemfile
|
109
125
|
- Gemfile.lock
|
110
126
|
- LICENSE
|
@@ -118,8 +134,13 @@ files:
|
|
118
134
|
- lib/adequate_serialization/decorator.rb
|
119
135
|
- lib/adequate_serialization/inline_serializer.rb
|
120
136
|
- lib/adequate_serialization/options.rb
|
137
|
+
- lib/adequate_serialization/rails/cache_busting.rb
|
138
|
+
- lib/adequate_serialization/rails/cache_refresh.rb
|
121
139
|
- lib/adequate_serialization/rails/cache_step.rb
|
140
|
+
- lib/adequate_serialization/rails/cache_visualization.rb
|
122
141
|
- lib/adequate_serialization/rails/relation_serializer.rb
|
142
|
+
- lib/adequate_serialization/rails/static/favicon.ico
|
143
|
+
- lib/adequate_serialization/rails/static/index.html.erb
|
123
144
|
- lib/adequate_serialization/serializable.rb
|
124
145
|
- lib/adequate_serialization/serializer.rb
|
125
146
|
- lib/adequate_serialization/steps.rb
|
@@ -145,7 +166,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
145
166
|
- !ruby/object:Gem::Version
|
146
167
|
version: '0'
|
147
168
|
requirements: []
|
148
|
-
rubygems_version: 3.
|
169
|
+
rubygems_version: 3.1.2
|
149
170
|
signing_key:
|
150
171
|
specification_version: 4
|
151
172
|
summary: Serializes objects adequately
|
data/.github/main.workflow
DELETED
@@ -1,40 +0,0 @@
|
|
1
|
-
workflow "Main" {
|
2
|
-
on = "push"
|
3
|
-
resolves = "Publish"
|
4
|
-
}
|
5
|
-
|
6
|
-
action "Install" {
|
7
|
-
uses = "docker://culturehq/actions-bundler:latest"
|
8
|
-
args = "install"
|
9
|
-
}
|
10
|
-
|
11
|
-
action "Audit" {
|
12
|
-
needs = "Install"
|
13
|
-
uses = "docker://culturehq/actions-bundler:latest"
|
14
|
-
args = "exec bundle audit"
|
15
|
-
}
|
16
|
-
|
17
|
-
action "Lint" {
|
18
|
-
needs = "Install"
|
19
|
-
uses = "docker://culturehq/actions-bundler:latest"
|
20
|
-
args = "exec rubocop --parallel"
|
21
|
-
}
|
22
|
-
|
23
|
-
action "Test" {
|
24
|
-
needs = "Install"
|
25
|
-
uses = "docker://culturehq/actions-bundler:latest"
|
26
|
-
args = "exec rake test"
|
27
|
-
}
|
28
|
-
|
29
|
-
action "Tag" {
|
30
|
-
needs = ["Audit", "Lint", "Test"]
|
31
|
-
uses = "actions/bin/filter@master"
|
32
|
-
args = "tag"
|
33
|
-
}
|
34
|
-
|
35
|
-
action "Publish" {
|
36
|
-
needs = "Tag"
|
37
|
-
uses = "docker://culturehq/actions-bundler:latest"
|
38
|
-
args = "build release:rubygem_push"
|
39
|
-
secrets = ["BUNDLE_GEM__PUSH_KEY"]
|
40
|
-
}
|