clowne 1.4.0 → 1.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +6 -0
- data/README.md +0 -2
- data/lib/clowne/adapters/active_record/associations/noop.rb +1 -1
- data/lib/clowne/adapters/base/association.rb +1 -1
- data/lib/clowne/adapters/sequel/associations/one_to_many.rb +0 -4
- data/lib/clowne/ext/record_key.rb +1 -1
- data/lib/clowne/version.rb +1 -1
- metadata +7 -113
- data/.codeclimate.yml +0 -7
- data/.gitattributes +0 -1
- data/.github/workflows/rspec-jruby.yml +0 -33
- data/.github/workflows/rspec-truffle.yml +0 -35
- data/.github/workflows/rspec.yml +0 -51
- data/.github/workflows/rubocop.yml +0 -20
- data/.gitignore +0 -16
- data/.rspec +0 -3
- data/.rubocop.yml +0 -29
- data/.rufo +0 -3
- data/Gemfile +0 -20
- data/Rakefile +0 -8
- data/bin/console +0 -14
- data/bin/setup +0 -8
- data/clowne.gemspec +0 -36
- data/docs/.nojekyll +0 -0
- data/docs/.rubocop.yml +0 -15
- data/docs/CNAME +0 -1
- data/docs/README.md +0 -131
- data/docs/_sidebar.md +0 -25
- data/docs/active_record.md +0 -33
- data/docs/after_clone.md +0 -53
- data/docs/after_persist.md +0 -77
- data/docs/architecture.md +0 -138
- data/docs/assets/docsify.min.js +0 -1
- data/docs/assets/prism-ruby.min.js +0 -1
- data/docs/assets/styles.css +0 -348
- data/docs/assets/vue.css +0 -1
- data/docs/clone_mapper.md +0 -59
- data/docs/customization.md +0 -63
- data/docs/exclude_association.md +0 -61
- data/docs/finalize.md +0 -31
- data/docs/from_v02_to_v1.md +0 -83
- data/docs/getting_started.md +0 -171
- data/docs/implicit_cloner.md +0 -33
- data/docs/include_association.md +0 -133
- data/docs/index.html +0 -29
- data/docs/init_as.md +0 -40
- data/docs/inline_configuration.md +0 -37
- data/docs/nullify.md +0 -33
- data/docs/operation.md +0 -55
- data/docs/parameters.md +0 -112
- data/docs/sequel.md +0 -50
- data/docs/supported_adapters.md +0 -10
- data/docs/testing.md +0 -194
- data/docs/traits.md +0 -25
- data/gemfiles/activerecord42.gemfile +0 -9
- data/gemfiles/jruby.gemfile +0 -10
- data/gemfiles/railsmaster.gemfile +0 -10
- data/lib/clowne/ext/yield_self_then.rb +0 -25
data/docs/assets/styles.css
DELETED
@@ -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
|
-
```
|
data/docs/customization.md
DELETED
@@ -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
|
-
```
|
data/docs/exclude_association.md
DELETED
@@ -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).
|
data/docs/from_v02_to_v1.md
DELETED
@@ -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
|
-
```
|