clowne 1.4.0 → 1.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (59) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +6 -0
  3. data/README.md +0 -2
  4. data/lib/clowne/adapters/active_record/associations/noop.rb +1 -1
  5. data/lib/clowne/adapters/base/association.rb +1 -1
  6. data/lib/clowne/adapters/sequel/associations/one_to_many.rb +0 -4
  7. data/lib/clowne/ext/record_key.rb +1 -1
  8. data/lib/clowne/version.rb +1 -1
  9. metadata +7 -113
  10. data/.codeclimate.yml +0 -7
  11. data/.gitattributes +0 -1
  12. data/.github/workflows/rspec-jruby.yml +0 -33
  13. data/.github/workflows/rspec-truffle.yml +0 -35
  14. data/.github/workflows/rspec.yml +0 -51
  15. data/.github/workflows/rubocop.yml +0 -20
  16. data/.gitignore +0 -16
  17. data/.rspec +0 -3
  18. data/.rubocop.yml +0 -29
  19. data/.rufo +0 -3
  20. data/Gemfile +0 -20
  21. data/Rakefile +0 -8
  22. data/bin/console +0 -14
  23. data/bin/setup +0 -8
  24. data/clowne.gemspec +0 -36
  25. data/docs/.nojekyll +0 -0
  26. data/docs/.rubocop.yml +0 -15
  27. data/docs/CNAME +0 -1
  28. data/docs/README.md +0 -131
  29. data/docs/_sidebar.md +0 -25
  30. data/docs/active_record.md +0 -33
  31. data/docs/after_clone.md +0 -53
  32. data/docs/after_persist.md +0 -77
  33. data/docs/architecture.md +0 -138
  34. data/docs/assets/docsify.min.js +0 -1
  35. data/docs/assets/prism-ruby.min.js +0 -1
  36. data/docs/assets/styles.css +0 -348
  37. data/docs/assets/vue.css +0 -1
  38. data/docs/clone_mapper.md +0 -59
  39. data/docs/customization.md +0 -63
  40. data/docs/exclude_association.md +0 -61
  41. data/docs/finalize.md +0 -31
  42. data/docs/from_v02_to_v1.md +0 -83
  43. data/docs/getting_started.md +0 -171
  44. data/docs/implicit_cloner.md +0 -33
  45. data/docs/include_association.md +0 -133
  46. data/docs/index.html +0 -29
  47. data/docs/init_as.md +0 -40
  48. data/docs/inline_configuration.md +0 -37
  49. data/docs/nullify.md +0 -33
  50. data/docs/operation.md +0 -55
  51. data/docs/parameters.md +0 -112
  52. data/docs/sequel.md +0 -50
  53. data/docs/supported_adapters.md +0 -10
  54. data/docs/testing.md +0 -194
  55. data/docs/traits.md +0 -25
  56. data/gemfiles/activerecord42.gemfile +0 -9
  57. data/gemfiles/jruby.gemfile +0 -10
  58. data/gemfiles/railsmaster.gemfile +0 -10
  59. data/lib/clowne/ext/yield_self_then.rb +0 -25
@@ -1,348 +0,0 @@
1
- @font-face {
2
- font-weight: 400;
3
- font-style: normal;
4
- font-family: "Stem Text";
5
- src: url("//cdn.evilmartians.com/front/fonts/subset-StemText-Regular.woff") format("woff");
6
- }
7
- @font-face {
8
- font-weight: 700;
9
- font-style: normal;
10
- font-family: "Stem Text";
11
- src: url("//cdn.evilmartians.com/front/fonts/subset-StemText-Bold.woff") format("woff");
12
- }
13
-
14
- @font-face {
15
- font-family: "Fira Code";
16
- src: url("./fonts/FiraCode-Regular.woff") format("woff");
17
- }
18
-
19
- :root {
20
- --theme-color: #9FA628;
21
- --theme-color-light: rgb(238, 240, 226);
22
- --theme-color-dark: rgba(159, 166, 40, .8);
23
- --theme-color-secondary: #c5c224;
24
- --theme-color-secondary-dark: #719805;
25
- --theme-color-secondary-light: #cff642;
26
-
27
- --text-color-base: #363636;
28
- --text-color-secondary: #646473;
29
- }
30
-
31
- ::selection {
32
- background: var(--theme-color-light);
33
- }
34
-
35
- body {
36
- font-size: 100%;
37
- font: 18px/30px "Stem Text", "Arial", sans-serif;
38
- color: var(--text-color-base);
39
- }
40
-
41
- * {
42
- text-decoration: none !important;
43
- }
44
-
45
- a {
46
- transition: all 0.3s linear;
47
- border-bottom: none !important;
48
- }
49
-
50
- .github-corner svg {
51
- fill: var(--theme-color-secondary);
52
- }
53
-
54
- .chart-container {
55
- padding: 1em 0;
56
- text-align: center;
57
- }
58
-
59
- .sidebar {
60
- border: none;
61
- background-color: var(--theme-color-secondary);
62
- color: #fff;
63
- width: 20%;
64
- display: flex;
65
- flex-direction: column;
66
- }
67
-
68
- body.close .sidebar {
69
- transform: translateX(-100%);
70
- }
71
-
72
- .sidebar .sidebar-nav {
73
- order: 3;
74
- }
75
-
76
- .sidebar ul li a {
77
- color: rgba(255,255,255,0.8);
78
- color: var(--theme-color-light);
79
- font-size: 1rem;
80
- }
81
-
82
- .sidebar ul li.active>a {
83
- border-width: 0.1rem;
84
- }
85
-
86
- .sidebar ul li a:hover {
87
- text-decoration: none;
88
- color: rgba(255,255,255,1);
89
- }
90
-
91
- .sidebar .sidebar-nav ul li.active>a {
92
- color: #fff;
93
- border-right: 0.2rem solid var(--theme-color-secondary-light);
94
- }
95
-
96
- .sidebar > h1 {
97
- order: 1;
98
- font-size: 2rem;
99
- margin-top: 1.5rem;
100
- }
101
-
102
- /* search plugin related */
103
-
104
- .sidebar .search {
105
- order: 2;
106
- margin: 1.5rem 0 0 0;
107
- border: none;
108
- margin-top: 20px;
109
- margin-bottom: 20px;
110
- padding: 6px;
111
- }
112
-
113
- .sidebar .search .input-wrap {
114
- border: none;
115
- position: relative;
116
- }
117
-
118
- .sidebar .search .clear-button.show {
119
- display: block;
120
- position: absolute;
121
- right: 4px;
122
- top: 8px;
123
- }
124
-
125
- body .sidebar-toggle {
126
- background: none;
127
- bottom: 1rem;
128
- left: 1rem;
129
- cursor: pointer;
130
- width: 1.5rem;
131
- height: 1.5rem;
132
- padding: 0;
133
- }
134
-
135
- body .sidebar-toggle span {
136
- transition: all 0.3s linear;
137
- background-color: white;
138
- height: 0.25rem;
139
- width: 1.5rem;
140
- position: absolute;
141
- left: 0;
142
- margin: 0;
143
- transform-origin: 0;
144
- }
145
-
146
- body.close .sidebar-toggle {
147
- width: 1.5rem;
148
- height: 1.5rem;
149
- }
150
-
151
- body.close .sidebar-toggle span {
152
- transform-origin: center;
153
- background-color: var(--theme-color-secondary);
154
- }
155
-
156
- body .sidebar-toggle span:nth-child(1) { top:0; }
157
- body .sidebar-toggle span:nth-child(2) { top:0.65rem; }
158
- body .sidebar-toggle span:nth-child(3) { top:1.25rem; }
159
-
160
- .sidebar-toggle .sidebar-toggle-button:hover { opacity: 1; }
161
-
162
- .sidebar-toggle:hover span:nth-child(1) { transform: rotate(45deg); width: 1.75rem; }
163
- .sidebar-toggle:hover span:nth-child(2) { opacity: 0; }
164
- .sidebar-toggle:hover span:nth-child(3) { transform: rotate(-45deg); width: 1.75rem; }
165
-
166
- .close .sidebar-toggle:hover span:nth-child(1) { transform:rotate(0); width:1.5rem; top:0.65rem; }
167
- .close .sidebar-toggle:hover span:nth-child(2) { opacity: 1; transform:rotate(90deg); }
168
- .close .sidebar-toggle:hover span:nth-child(3) { transform:rotate(0); width:1.5rem; top:0.65rem; }
169
-
170
- th {
171
- text-align: left;
172
- }
173
-
174
- .markdown-section blockquote {
175
- margin: 1em 0;
176
- }
177
-
178
- .markdown-section em,
179
- .markdown-section blockquote {
180
- color: var(--text-color-tertiary);
181
- }
182
-
183
- .anchor {
184
- position: relative;
185
- }
186
-
187
- section.cover .cover-main {
188
- margin: 20vh 20vw;
189
- }
190
-
191
- .app-name-link {
192
- white-space: nowrap;
193
- }
194
-
195
- .app-sub-sidebar li:before {
196
- display: none;
197
- }
198
-
199
- .markdown-section pre,
200
- .markdown-section pre > code {
201
- background-color: #2E2E46;
202
- color: rgba(255,255,255,0.75);
203
- font-size: 1em;
204
- line-height: 1.5;
205
- }
206
-
207
- .markdown-section code {
208
- display: inline-block;
209
- font-family: 'Fira Code', monospace;
210
- }
211
-
212
- .markdown-section pre {
213
- padding: 2rem;
214
- }
215
-
216
- .markdown-section pre > code {
217
- padding: 0;
218
- }
219
-
220
- .markdown-section hr {
221
- border-bottom: 5px solid transparent;
222
- }
223
-
224
-
225
- .markdown-section {
226
- max-width: 75rem;
227
- padding: 1rem 3rem;
228
- }
229
-
230
- .markdown-section ol, .markdown-section p, .markdown-section ul {
231
- line-height: inherit;
232
- }
233
-
234
- .markdown-section code {
235
- color: inherit;
236
- border-radius: 0;
237
- font-size: 0.9em;
238
- padding: 4px 10px;
239
- margin: 1px 0px;
240
- /* color: #111; */
241
- }
242
-
243
- .markdown-section table {
244
- display: table;
245
- }
246
-
247
- .markdown-section table tr {
248
- border-width: 0.2rem 0;
249
- border-style: solid;
250
- border-color: #F1F1F2;
251
- }
252
-
253
- .markdown-section table tr:nth-child(2n) {
254
- background-color: transparent;
255
- }
256
-
257
- .markdown-section table td,
258
- .markdown-section table th {
259
- border: none;
260
- padding: 1.5rem 0.5rem;
261
- text-align: left;
262
- }
263
-
264
- .markdown-section table td p {
265
- margin: 0;
266
- }
267
-
268
- .markdown-section a {
269
- text-decoration: none;
270
- border-bottom: 0.1rem solid var(--theme-color-light);
271
- transition: all 0.3s ease;
272
- }
273
-
274
- .markdown-section a:hover {
275
- border-color: var(--theme-color);
276
- color: var(--theme-color-dark);
277
- }
278
-
279
-
280
- /* Badges */
281
- .markdown-section > p:first-child > a {
282
- border: none;
283
- }
284
-
285
- .docsify-copy-code-button {
286
- background: var(--theme-color);
287
- }
288
-
289
- .sidebar::-webkit-scrollbar {
290
- width:0;
291
- }
292
-
293
- @media (max-width: 768px) {
294
- aside.sidebar {
295
- width: 300px;
296
- }
297
-
298
- body.close .sidebar {
299
- transform: translateX(300px);
300
- }
301
-
302
- body .sidebar-toggle span {
303
- background-color: var(--theme-color-secondary);
304
- }
305
-
306
-
307
- body.close .sidebar-toggle span {
308
- background-color: white;
309
- }
310
-
311
- .sidebar-toggle:hover span:nth-child(1), .sidebar-toggle:hover span:nth-child(2), .sidebar-toggle:hover span:nth-child(3) {
312
- transform: none;
313
- width: 1.5rem;
314
- opacity: 1;
315
- }
316
-
317
- .close .sidebar-toggle span:nth-child(1), .close .sidebar-toggle:hover span:nth-child(1) {
318
- transform: rotate(45deg);
319
- width: 1.75rem;
320
- top: 0.65rem;
321
- }
322
-
323
- .close .sidebar-toggle span:nth-child(2), .close .sidebar-toggle:hover span:nth-child(2) {
324
- opacity: 0;
325
- }
326
-
327
- .close .sidebar-toggle span:nth-child(3), .close .sidebar-toggle:hover span:nth-child(3) {
328
- transform: rotate(-45deg);
329
- width: 1.75rem;
330
- top: 0.65rem;
331
- }
332
-
333
- body.close .sidebar-toggle {
334
- background: none;
335
- }
336
- }
337
-
338
- @media (min-width: 1200px) {
339
- body {
340
- font-size: 112.5%;
341
- }
342
- }
343
-
344
- @media (min-width: 1400px) {
345
- body {
346
- font-size: 125%;
347
- }
348
- }
data/docs/assets/vue.css DELETED
@@ -1 +0,0 @@
1
- @import url("https://fonts.googleapis.com/css?family=Roboto+Mono|Source+Sans+Pro:300,400,600");*{-webkit-font-smoothing:antialiased;-webkit-overflow-scrolling:touch;-webkit-tap-highlight-color:rgba(0,0,0,0);-webkit-text-size-adjust:none;-webkit-touch-callout:none;box-sizing:border-box}body:not(.ready){overflow:hidden}body:not(.ready) .app-nav,body:not(.ready)>nav,body:not(.ready) [data-cloak]{display:none}div#app{font-size:30px;font-weight:lighter;margin:40vh auto;text-align:center}div#app:empty:before{content:"Loading..."}.emoji{height:1.2rem;vertical-align:middle}.progress{background-color:var(--theme-color,#42b983);height:2px;left:0;position:fixed;right:0;top:0;transition:width .2s,opacity .4s;width:0;z-index:5}.search .search-keyword,.search a:hover{color:var(--theme-color,#42b983)}.search .search-keyword{font-style:normal;font-weight:700}body,html{height:100%}body{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;color:#34495e;font-family:Source Sans Pro,Helvetica Neue,Arial,sans-serif;font-size:15px;letter-spacing:0;margin:0;overflow-x:hidden}img{max-width:100%}a[disabled]{cursor:not-allowed;opacity:.6}kbd{border:1px solid #ccc;border-radius:3px;display:inline-block;font-size:12px!important;line-height:12px;margin-bottom:3px;padding:3px 5px;vertical-align:middle}li input[type=checkbox]{margin:0 .2em .25em 0;vertical-align:middle}.app-nav{margin:25px 60px 0 0;position:absolute;right:0;text-align:right;z-index:2}.app-nav.no-badge{margin-right:25px}.app-nav p{margin:0}.app-nav>a{margin:0 1rem;padding:5px 0}.app-nav li,.app-nav ul{display:inline-block;list-style:none;margin:0}.app-nav a{color:inherit;font-size:16px;text-decoration:none;transition:color .3s}.app-nav a.active,.app-nav a:hover{color:var(--theme-color,#42b983)}.app-nav a.active{border-bottom:2px solid var(--theme-color,#42b983)}.app-nav li{display:inline-block;margin:0 1rem;padding:5px 0;position:relative}.app-nav li ul{background-color:#fff;border:1px solid #ddd;border-bottom-color:#ccc;border-radius:4px;box-sizing:border-box;display:none;max-height:calc(100vh - 61px);overflow-y:auto;padding:10px 0;position:absolute;right:-15px;text-align:left;top:100%;white-space:nowrap}.app-nav li ul li{display:block;font-size:14px;line-height:1rem;margin:0;margin:8px 14px;white-space:nowrap}.app-nav li ul a{display:block;font-size:inherit;margin:0;padding:0}.app-nav li ul a.active{border-bottom:0}.app-nav li:hover ul{display:block}.github-corner{border-bottom:0;position:fixed;right:0;text-decoration:none;top:0;z-index:1}.github-corner:hover .octo-arm{animation:a .56s ease-in-out}.github-corner svg{color:#fff;fill:var(--theme-color,#42b983);height:80px;width:80px}main{display:block;position:relative;width:100vw;height:100%;z-index:0}main.hidden{display:none}.anchor{display:inline-block;text-decoration:none;transition:all .3s}.anchor span{color:#34495e}.anchor:hover{text-decoration:underline}.sidebar{border-right:1px solid rgba(0,0,0,.07);overflow-y:auto;padding:40px 0 0;position:absolute;top:0;bottom:0;left:0;transition:transform .25s ease-out;width:300px;z-index:3}.sidebar>h1{margin:0 auto 1rem;font-size:1.5rem;font-weight:300;text-align:center}.sidebar>h1 a{color:inherit;text-decoration:none}.sidebar>h1 .app-nav{display:block;position:static}.sidebar .sidebar-nav{line-height:2em;padding-bottom:40px}.sidebar li.collapse .app-sub-sidebar{display:none}.sidebar ul{margin:0 0 0 15px;padding:0}.sidebar li>p{font-weight:700;margin:0}.sidebar ul,.sidebar ul li{list-style:none}.sidebar ul li a{border-bottom:none;display:block}.sidebar ul li ul{padding-left:20px}.sidebar::-webkit-scrollbar{width:4px}.sidebar::-webkit-scrollbar-thumb{background:transparent;border-radius:4px}.sidebar:hover::-webkit-scrollbar-thumb{background:hsla(0,0%,53%,.4)}.sidebar:hover::-webkit-scrollbar-track{background:hsla(0,0%,53%,.1)}.sidebar-toggle{background-color:transparent;background-color:hsla(0,0%,100%,.8);border:0;outline:none;padding:10px;position:absolute;bottom:0;left:0;text-align:center;transition:opacity .3s;width:284px;z-index:4}.sidebar-toggle .sidebar-toggle-button:hover{opacity:.4}.sidebar-toggle span{background-color:var(--theme-color,#42b983);display:block;margin-bottom:4px;width:16px;height:2px}body.sticky .sidebar,body.sticky .sidebar-toggle{position:fixed}.content{padding-top:60px;position:absolute;top:0;right:0;bottom:0;left:300px;transition:left .25s ease}.markdown-section{margin:0 auto;max-width:800px;padding:30px 15px 40px;position:relative}.markdown-section>*{box-sizing:border-box;font-size:inherit}.markdown-section>:first-child{margin-top:0!important}.markdown-section hr{border:none;border-bottom:1px solid #eee;margin:2em 0}.markdown-section iframe{border:1px solid #eee;width:1px;min-width:100%}.markdown-section table{border-collapse:collapse;border-spacing:0;display:block;margin-bottom:1rem;overflow:auto;width:100%}.markdown-section th{font-weight:700}.markdown-section td,.markdown-section th{border:1px solid #ddd;padding:6px 13px}.markdown-section tr{border-top:1px solid #ccc}.markdown-section p.tip,.markdown-section tr:nth-child(2n){background-color:#f8f8f8}.markdown-section p.tip{border-bottom-right-radius:2px;border-left:4px solid #f66;border-top-right-radius:2px;margin:2em 0;padding:12px 24px 12px 30px;position:relative}.markdown-section p.tip:before{background-color:#f66;border-radius:100%;color:#fff;content:"!";font-family:Dosis,Source Sans Pro,Helvetica Neue,Arial,sans-serif;font-size:14px;font-weight:700;left:-12px;line-height:20px;position:absolute;height:20px;width:20px;text-align:center;top:14px}.markdown-section p.tip code{background-color:#efefef}.markdown-section p.tip em{color:#34495e}.markdown-section p.warn{background:rgba(66,185,131,.1);border-radius:2px;padding:1rem}.markdown-section ul.task-list>li{list-style-type:none}body.close .sidebar{transform:translateX(-300px)}body.close .sidebar-toggle{width:auto}body.close .content{left:0}@media print{.app-nav,.github-corner,.sidebar,.sidebar-toggle{display:none}}@media screen and (max-width:768px){.github-corner,.sidebar,.sidebar-toggle{position:fixed}.app-nav{margin-top:16px}.app-nav li ul{top:30px}main{height:auto;overflow-x:hidden}.sidebar{left:-300px;transition:transform .25s ease-out}.content{left:0;max-width:100vw;position:static;padding-top:20px;transition:transform .25s ease}.app-nav,.github-corner{transition:transform .25s ease-out}.sidebar-toggle{background-color:transparent;width:auto;padding:30px 30px 10px 10px}body.close .sidebar{transform:translateX(300px)}body.close .sidebar-toggle{background-color:hsla(0,0%,100%,.8);transition:background-color 1s;width:284px;padding:10px}body.close .content{transform:translateX(300px)}body.close .app-nav,body.close .github-corner{display:none}.github-corner:hover .octo-arm{animation:none}.github-corner .octo-arm{animation:a .56s ease-in-out}}@keyframes a{0%,to{transform:rotate(0)}20%,60%{transform:rotate(-25deg)}40%,80%{transform:rotate(10deg)}}section.cover{-ms-flex-align:center;align-items:center;background-position:50%;background-repeat:no-repeat;background-size:cover;height:100vh;display:none}section.cover.show{display:-ms-flexbox;display:flex}section.cover.has-mask .mask{background-color:#fff;opacity:.8;position:absolute;top:0;height:100%;width:100%}section.cover .cover-main{-ms-flex:1;flex:1;margin:-20px 16px 0;text-align:center;z-index:1}section.cover a{color:inherit}section.cover a,section.cover a:hover{text-decoration:none}section.cover p{line-height:1.5rem;margin:1em 0}section.cover h1{color:inherit;font-size:2.5rem;font-weight:300;margin:.625rem 0 2.5rem;position:relative;text-align:center}section.cover h1 a{display:block}section.cover h1 small{bottom:-.4375rem;font-size:1rem;position:absolute}section.cover blockquote{font-size:1.5rem;text-align:center}section.cover ul{line-height:1.8;list-style-type:none;margin:1em auto;max-width:500px;padding:0}section.cover .cover-main>p:last-child a{border:1px solid var(--theme-color,#42b983);border-radius:2rem;box-sizing:border-box;color:var(--theme-color,#42b983);display:inline-block;font-size:1.05rem;letter-spacing:.1rem;margin:.5rem 1rem;padding:.75em 2rem;text-decoration:none;transition:all .15s ease}section.cover .cover-main>p:last-child a:last-child{background-color:var(--theme-color,#42b983);color:#fff}section.cover .cover-main>p:last-child a:last-child:hover{color:inherit;opacity:.8}section.cover .cover-main>p:last-child a:hover{color:inherit}section.cover blockquote>p>a{border-bottom:2px solid var(--theme-color,#42b983);transition:color .3s}section.cover blockquote>p>a:hover{color:var(--theme-color,#42b983)}.sidebar,body{background-color:#fff}.sidebar{color:#364149}.sidebar li{margin:6px 0}.sidebar ul li a{color:#505d6b;font-size:14px;font-weight:400;overflow:hidden;text-decoration:none;text-overflow:ellipsis;white-space:nowrap}.sidebar ul li a:hover{text-decoration:underline}.sidebar ul li ul{padding:0}.sidebar ul li.active>a{border-right:2px solid;color:var(--theme-color,#42b983);font-weight:600}.app-sub-sidebar li:before{content:"-";padding-right:4px;float:left}.markdown-section h1,.markdown-section h2,.markdown-section h3,.markdown-section h4,.markdown-section strong{color:#2c3e50;font-weight:600}.markdown-section a{color:var(--theme-color,#42b983);font-weight:600}.markdown-section h1{font-size:2rem;margin:0 0 1rem}.markdown-section h2{font-size:1.75rem;margin:45px 0 .8rem}.markdown-section h3{font-size:1.5rem;margin:40px 0 .6rem}.markdown-section h4{font-size:1.25rem}.markdown-section h5{font-size:1rem}.markdown-section h6{color:#777;font-size:1rem}.markdown-section figure,.markdown-section p{margin:1.2em 0}.markdown-section ol,.markdown-section p,.markdown-section ul{line-height:1.6rem;word-spacing:.05rem}.markdown-section ol,.markdown-section ul{padding-left:1.5rem}.markdown-section blockquote{border-left:4px solid var(--theme-color,#42b983);color:#858585;margin:2em 0;padding-left:20px}.markdown-section blockquote p{font-weight:600;margin-left:0}.markdown-section iframe{margin:1em 0}.markdown-section em{color:#7f8c8d}.markdown-section code{border-radius:2px;color:#e96900;font-size:.8rem;margin:0 2px;padding:3px 5px;white-space:pre-wrap}.markdown-section code,.markdown-section pre{background-color:#f8f8f8;font-family:Roboto Mono,Monaco,courier,monospace}.markdown-section pre{-moz-osx-font-smoothing:initial;-webkit-font-smoothing:initial;line-height:1.5rem;margin:1.2em 0;overflow:auto;padding:0 1.4rem;position:relative;word-wrap:normal}.token.cdata,.token.comment,.token.doctype,.token.prolog{color:#8e908c}.token.namespace{opacity:.7}.token.boolean,.token.number{color:#c76b29}.token.punctuation{color:#525252}.token.property{color:#c08b30}.token.tag{color:#2973b7}.token.string{color:var(--theme-color,#42b983)}.token.selector{color:#6679cc}.token.attr-name{color:#2973b7}.language-css .token.string,.style .token.string,.token.entity,.token.url{color:#22a2c9}.token.attr-value,.token.control,.token.directive,.token.unit{color:var(--theme-color,#42b983)}.token.function,.token.keyword{color:#e96900}.token.atrule,.token.regex,.token.statement{color:#22a2c9}.token.placeholder,.token.variable{color:#3d8fd1}.token.deleted{text-decoration:line-through}.token.inserted{border-bottom:1px dotted #202746;text-decoration:none}.token.italic{font-style:italic}.token.bold,.token.important{font-weight:700}.token.important{color:#c94922}.token.entity{cursor:help}.markdown-section pre>code{-moz-osx-font-smoothing:initial;-webkit-font-smoothing:initial;background-color:#f8f8f8;border-radius:2px;color:#525252;display:block;font-family:Roboto Mono,Monaco,courier,monospace;font-size:.8rem;line-height:inherit;margin:0 2px;max-width:inherit;overflow:inherit;padding:2.2em 5px;white-space:inherit}.markdown-section code:after,.markdown-section code:before{letter-spacing:.05rem}code .token{-moz-osx-font-smoothing:initial;-webkit-font-smoothing:initial;min-height:1.5rem}pre:after{color:#ccc;content:attr(data-lang);font-size:.6rem;font-weight:600;height:15px;line-height:15px;padding:5px 10px 0;position:absolute;right:0;text-align:right;top:0}
data/docs/clone_mapper.md DELETED
@@ -1,59 +0,0 @@
1
- # Clone mapper
2
-
3
- *Notice: `after_persist` supported only with [`active_record`](active_record.md) adapter.*
4
-
5
- In [`after_persist`](after_persist.md) documenation you can find interisting code:
6
-
7
- ```ruby
8
- class UserCloner < Clowne::Cloner
9
- # ...
10
- after_persist do |origin, clone, mapper:, **|
11
- cloned_bio = mapper.clone_of(origin.bio)
12
- clone.update(bio_id: cloned_bio.id)
13
- end
14
- end
15
- ```
16
-
17
- What is it `mapper:` and how it works?
18
-
19
- `mapper:` is an instance of `Clowne::Utils::CloneMapper`. Active Record pattern gives us an opportunity to build our cloning tool on objects, so while cloning, we remember origin records and their clones and can use these relations after saving with `Clowne::Utils::CloneMapper`.
20
-
21
- It perfectly works, and we can use the mapper to fix broken associations.
22
- There is only one small nuance - we can get `#clone_of` only for the record that participated in a cloning process, and this limits the functionality of the `after_persist` callbacks.
23
-
24
- But `Clowne is built with extensibility in mind™` and Clowne provides the ability to use your custom mapper:
25
-
26
- ```ruby
27
- class CustomMapper < Clowne::Utils::CloneMapper
28
- def initialize(dependencies)
29
- super()
30
- # inject dependencies if need
31
- # or fetch it from other place (e.g. from DB)
32
- @default_bios = dependencies.index_by(&:title)
33
- end
34
-
35
- def clone_of(record)
36
- super(record) || fallback(record)
37
- end
38
-
39
- private
40
-
41
- def fallback(record)
42
- # put some mapping logic here
43
- return if record.is_a?(Post)
44
-
45
- @default_bios[record.title]
46
- end
47
- end
48
-
49
- # now we can use it:
50
-
51
- class Post < ActiveRecord::Base
52
- # add simple scope
53
- # scope :default_bios, -> {...}
54
- end
55
-
56
- user = User.last
57
- operation = UserCloner.call(user, mapper: CustomMapper.new(Post.default_bios))
58
- operation.persist
59
- ```
@@ -1,63 +0,0 @@
1
- # Customization
2
-
3
- Clowne is built with extensibility in mind. You can create your own DSL commands and resolvers.
4
-
5
- Let's consider an example.
6
-
7
- Suppose that you want to add the `include_all` declaration to automagically include all associations (for ActiveRecord).
8
-
9
- First, you should add a custom declaration:
10
-
11
- ```ruby
12
- # Extend from Base declaration
13
- class IncludeAll < Clowne::Declarations::Base # :nodoc: all
14
- def compile(plan)
15
- # Just add all_associations declaration (self) to plan
16
- plan.set(:all_associations, self)
17
- end
18
- end
19
-
20
- # Register our declrations, i.e. extend DSL
21
- Clowne::Declarations.add :include_all, IncludeAll
22
- ```
23
-
24
- See more on `plan` in [architecture overview](architecture.md).
25
-
26
- Secondly, register a resolver:
27
-
28
- ```ruby
29
- class AllAssociations
30
- # This method is called when all_associations command is applied.
31
- #
32
- # source – source record
33
- # record – target record (our clone)
34
- # declaration – declaration object
35
- # params – custom params passed to cloner
36
- def call(source, record, declaration, params:)
37
- source.class.reflections.each_value do |_name, reflection|
38
- # Exclude belongs_to associations
39
- next if reflection.macro == :belongs_to
40
-
41
- # Resolve and apply association cloner
42
- cloner_class = Clowne::Adapters::ActiveRecord::Associations.cloner_for(reflection)
43
- cloner_class.new(reflection, source, declaration, params).call(record)
44
- end
45
- record
46
- end
47
- end
48
-
49
- # Finally, register the resolver
50
- Clowne::Adapters::ActiveRecord.register_resolver(
51
- :all_associations, AllAssociations
52
- )
53
- ```
54
-
55
- Now you can use it likes this:
56
-
57
- ```ruby
58
- class UserCloner < Clowne::Cloner
59
- adapter :active_record
60
-
61
- include_all
62
- end
63
- ```
@@ -1,61 +0,0 @@
1
- # Exclude Association
2
-
3
- Clowne doesn't include any association by default and doesn't provide _magic_ `include_all` declaration (although you can [add one by yourself](customization.md)).
4
-
5
- Nevertheless, sometimes you might want to exclude already added associations (when inheriting a cloner or using [traits](traits.md)).
6
-
7
- Consider an example:
8
-
9
- ```ruby
10
- class UserCloner < Clowne::Cloner
11
- include_association :posts
12
-
13
- trait :without_posts do
14
- exclude_association :posts
15
- end
16
- end
17
-
18
- # copy user and posts
19
- clone = UserCloner.call(user).to_record
20
- clone.posts.count == user.posts.count
21
- # => true
22
-
23
- # copy only user
24
- clone2 = UserCloner.call(user, traits: :without_posts).to_record
25
- clone2.posts
26
- # => []
27
- ```
28
-
29
- **NOTE**: once excluded association cannot be re-included, e.g. the following cloner:
30
-
31
- ```ruby
32
- class UserCloner < Clowne::Cloner
33
- exclude_association :comments
34
-
35
- trait :with_comments do
36
- # That wouldn't work
37
- include_association :comments
38
- end
39
- end
40
-
41
- clone = UserCloner.call(user, traits: :with_comments).to_record
42
- clone.comments.empty?
43
- # => true
44
- ```
45
-
46
- Why so? That allows us to have a deterministic cloning plan when combining multiple traits
47
- (or inheriting cloners).
48
-
49
- ## Exclude multiple associations
50
-
51
- It's possible to exclude multiple associations at once the same way as [`include_associations`](include_association.md):
52
-
53
- ```ruby
54
- class UserCloner < Clowne::Cloner
55
- include_associations :accounts, :posts, :comments
56
-
57
- trait :without_posts do
58
- exclude_associations :posts, :comments
59
- end
60
- end
61
- ```
data/docs/finalize.md DELETED
@@ -1,31 +0,0 @@
1
- # Finalization
2
-
3
- To apply custom transformations to the cloned record, you can use the `finalize` declaration:
4
-
5
- ```ruby
6
- class UserCloner < Clowne::Cloner
7
- finalize do |_source, record, **_params|
8
- record.name = "This is copy!"
9
- end
10
-
11
- trait :change_email do
12
- finalize do |_source, record, **params|
13
- record.email = params[:email]
14
- end
15
- end
16
- end
17
-
18
- cloned = UserCloner.call(user).to_record
19
- cloned.name
20
- # => 'This is copy!'
21
- cloned.email == "clone@example.com"
22
- # => false
23
-
24
- cloned2 = UserCloner.call(user, traits: :change_email).to_record
25
- cloned2.name
26
- # => 'This is copy!'
27
- cloned2.email
28
- # => 'clone@example.com'
29
- ```
30
-
31
- Finalization blocks are called at the end of the [cloning process](getting_started?id=execution-order).
@@ -1,83 +0,0 @@
1
- # From v0.2.x to v1.0.0
2
-
3
- The breaking change of v1.0 is the return of a unified [`result object`](operation.md) for all adapters.
4
-
5
- ## ActiveRecord
6
-
7
- ### Update code to work with [`Operation`](operation.md)
8
-
9
- ```ruby
10
- # Before
11
- clone = UserCloner.call(user)
12
- # => <#User id: nil, ...>
13
- clone.save!
14
- # => true
15
-
16
- # After
17
- clone = UserCloner.call(user)
18
- # => <#Clowne::Utils::Operation ...>
19
- clone = clone.to_record
20
- # => <#User id: 2, ...>
21
- clone.save!
22
- # => true
23
-
24
- # After (even better because of using full functionality)
25
- operation = UserCloner.call(user)
26
- # => <#Clowne::Utils::Operation ...>
27
- operation.persist!
28
- # => true
29
- clone = operation.to_record
30
- # => <#User id: 2, ...>
31
- clone.persisted?
32
- # => true
33
- ```
34
-
35
- ### Move post-processing cloning logic into [`after_persist`](after_persist.md) callback (if you have it)
36
-
37
- *Notice: `after_persist` supported only with [`active_record`](active_record.md) adapter.*
38
-
39
- ```ruby
40
- # Before
41
- clone = UserCloner.call(user)
42
- clone.save!
43
- # do something with persisted clone
44
-
45
- # After
46
- class UserCloner < Clowne::Cloner
47
- # ...
48
- after_persist do |origin, clone, **|
49
- # do something with persisted clone
50
- end
51
- end
52
-
53
- clone = UserCloner.call(user).tap(&:persist).to_record
54
- ```
55
- ## Sequel
56
-
57
- ### Use `to_record` instead of `to_model`
58
-
59
- ```ruby
60
- # Before
61
- record_wrapper = UserCloner.call(user)
62
- clone = record_wrapper.to_model
63
- clone.new?
64
- # => true
65
-
66
- # After
67
- operation = UserCloner.call(user)
68
- clone = operation.to_record
69
- clone.new?
70
- # => true
71
- ```
72
-
73
- ### Use `operation#persist` instead of converting to model and calling `#save`
74
-
75
- ```ruby
76
- # Before
77
- record_wrapper = UserCloner.call(user)
78
- clone = record_wrapper.to_model
79
- clone.save
80
-
81
- # After
82
- clone = UserCloner.call(user).tap(&:persist).to_record
83
- ```