bullet_train 1.0.38 → 1.0.41
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/controllers/concerns/sessions/controller_base.rb +11 -7
- data/app/views/layouts/mailer.html.erb +360 -0
- data/docs/indirection.md +2 -52
- data/docs/overriding.md +53 -0
- data/docs/super-scaffolding.md +3 -3
- data/lib/bullet_train/version.rb +1 -1
- metadata +3 -3
- data/config/locales/en/user_mailer.en.yml +0 -36
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 87bfe6b6ae9a8c873f110f0360c436e333cb68f0d6f0bb14fd4a458f4747aa29
|
4
|
+
data.tar.gz: 3b76e560de7117ae70b7af138937a3cdb96396fab8d660313335ca374f6fb35a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 41a7e50329932973e67dab25af3c0182bc6365ca57b4e8f859a4f691a9e202b0d248383960154a7aa84a0476d013204a1a802bd36b76a9936a3118897b00c1ae
|
7
|
+
data.tar.gz: 62cf5ad94c650779f7639f5a3eaf71d9a5b5f0885822c3ea5d9c5769532a7ebc358e86fbf866ccdd99a855feb512dc52c55d4931a1f87106c96e4f93dcf53244
|
@@ -2,14 +2,18 @@ module Sessions::ControllerBase
|
|
2
2
|
extend ActiveSupport::Concern
|
3
3
|
|
4
4
|
included do
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
5
|
+
# TODO I'm not sure why the sign-in page started throwing a `ActionController::InvalidAuthenticityToken`. I'm doing
|
6
|
+
# this as a temporary workaround, but this shouldn't be here long-term.
|
7
|
+
skip_before_action :verify_authenticity_token, only: [:create]
|
8
|
+
end
|
9
|
+
|
10
|
+
def pre_otp
|
11
|
+
if (@email = params["user"]["email"].downcase.strip.presence)
|
12
|
+
@user = User.find_by(email: @email)
|
13
|
+
end
|
9
14
|
|
10
|
-
|
11
|
-
|
12
|
-
end
|
15
|
+
respond_to do |format|
|
16
|
+
format.js
|
13
17
|
end
|
14
18
|
end
|
15
19
|
end
|
@@ -4,6 +4,366 @@
|
|
4
4
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
5
5
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
6
6
|
<title>Welcome to <%= t('application.name') %>!</title>
|
7
|
+
<% # TODO This is not what we want to do long-term. Would love to see this powered by Tailwind CSS. %>
|
8
|
+
<style type="text/css">
|
9
|
+
*:not(br):not(tr):not(html) {
|
10
|
+
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
|
11
|
+
box-sizing: border-box;
|
12
|
+
}
|
13
|
+
|
14
|
+
body {
|
15
|
+
width: 100% !important;
|
16
|
+
height: 100%;
|
17
|
+
margin: 0;
|
18
|
+
line-height: 1.4;
|
19
|
+
background-color: #F6F7F8;
|
20
|
+
color: #3E4B5B;
|
21
|
+
font-size: 16px;
|
22
|
+
-webkit-text-size-adjust: none;
|
23
|
+
}
|
24
|
+
|
25
|
+
p,
|
26
|
+
ul,
|
27
|
+
ol,
|
28
|
+
blockquote {
|
29
|
+
line-height: 1.4;
|
30
|
+
text-align: left;
|
31
|
+
}
|
32
|
+
|
33
|
+
a {
|
34
|
+
color: #047BF8;
|
35
|
+
}
|
36
|
+
|
37
|
+
a img {
|
38
|
+
border: none;
|
39
|
+
}
|
40
|
+
/* Layout ------------------------------ */
|
41
|
+
|
42
|
+
.email-wrapper {
|
43
|
+
width: 100%;
|
44
|
+
margin: 0;
|
45
|
+
padding: 0;
|
46
|
+
background-color: #F6F7F8;
|
47
|
+
}
|
48
|
+
|
49
|
+
.email-content {
|
50
|
+
width: 100%;
|
51
|
+
margin: 0;
|
52
|
+
padding: 0;
|
53
|
+
}
|
54
|
+
/* Masthead ----------------------- */
|
55
|
+
|
56
|
+
.email-masthead {
|
57
|
+
padding: 25px 0;
|
58
|
+
text-align: center;
|
59
|
+
}
|
60
|
+
|
61
|
+
.email-masthead_logo {
|
62
|
+
width: 94px;
|
63
|
+
}
|
64
|
+
|
65
|
+
.email-masthead_name {
|
66
|
+
font-size: 16px;
|
67
|
+
/*font-weight: bold;*/
|
68
|
+
color: #bbbfc3;
|
69
|
+
text-decoration: none;
|
70
|
+
/*text-shadow: 0 1px 0 white;*/
|
71
|
+
}
|
72
|
+
/* Body ------------------------------ */
|
73
|
+
|
74
|
+
.email-body {
|
75
|
+
width: 100%;
|
76
|
+
margin: 0;
|
77
|
+
padding: 0;
|
78
|
+
border-top: 1px solid #EDEFF2;
|
79
|
+
border-bottom: 1px solid #EDEFF2;
|
80
|
+
background-color: #FFFFFF;
|
81
|
+
|
82
|
+
}
|
83
|
+
|
84
|
+
.email-body_inner {
|
85
|
+
width: 570px;
|
86
|
+
margin: 0 auto;
|
87
|
+
padding: 0;
|
88
|
+
background-color: #FFFFFF;
|
89
|
+
}
|
90
|
+
|
91
|
+
.email-footer {
|
92
|
+
width: 570px;
|
93
|
+
margin: 0 auto;
|
94
|
+
padding: 0;
|
95
|
+
text-align: center;
|
96
|
+
}
|
97
|
+
|
98
|
+
.email-footer p {
|
99
|
+
color: #AAAAAA;
|
100
|
+
}
|
101
|
+
|
102
|
+
.body-action {
|
103
|
+
width: 100%;
|
104
|
+
margin: 30px auto;
|
105
|
+
padding: 0;
|
106
|
+
text-align: center;
|
107
|
+
}
|
108
|
+
|
109
|
+
.body-sub {
|
110
|
+
margin-top: 25px;
|
111
|
+
padding-top: 25px;
|
112
|
+
border-top: 1px solid #EDEFF2;
|
113
|
+
}
|
114
|
+
|
115
|
+
.content-cell {
|
116
|
+
padding: 35px;
|
117
|
+
}
|
118
|
+
|
119
|
+
.preheader {
|
120
|
+
display: none !important;
|
121
|
+
}
|
122
|
+
/* Attribute list ------------------------------ */
|
123
|
+
|
124
|
+
.attributes {
|
125
|
+
margin: 0 0 21px;
|
126
|
+
}
|
127
|
+
|
128
|
+
.attributes_content {
|
129
|
+
background-color: #EDEFF2;
|
130
|
+
padding: 16px;
|
131
|
+
}
|
132
|
+
|
133
|
+
.attributes_item {
|
134
|
+
padding: 0;
|
135
|
+
}
|
136
|
+
/* Related Items ------------------------------ */
|
137
|
+
|
138
|
+
.related {
|
139
|
+
width: 100%;
|
140
|
+
margin: 0;
|
141
|
+
padding: 25px 0 0 0;
|
142
|
+
}
|
143
|
+
|
144
|
+
.related_item {
|
145
|
+
padding: 10px 0;
|
146
|
+
color: #3E4B5B;
|
147
|
+
font-size: 15px;
|
148
|
+
line-height: 18px;
|
149
|
+
}
|
150
|
+
|
151
|
+
.related_item-title {
|
152
|
+
display: block;
|
153
|
+
margin: .5em 0 0;
|
154
|
+
}
|
155
|
+
|
156
|
+
.related_item-thumb {
|
157
|
+
display: block;
|
158
|
+
padding-bottom: 10px;
|
159
|
+
}
|
160
|
+
|
161
|
+
.related_heading {
|
162
|
+
border-top: 1px solid #EDEFF2;
|
163
|
+
text-align: center;
|
164
|
+
padding: 25px 0 10px;
|
165
|
+
}
|
166
|
+
/* Discount Code ------------------------------ */
|
167
|
+
|
168
|
+
.discount {
|
169
|
+
width: 100%;
|
170
|
+
margin: 0;
|
171
|
+
padding: 24px;
|
172
|
+
background-color: #EDEFF2;
|
173
|
+
border: 2px dashed #9BA2AB;
|
174
|
+
}
|
175
|
+
|
176
|
+
.discount_heading {
|
177
|
+
text-align: center;
|
178
|
+
}
|
179
|
+
|
180
|
+
.discount_body {
|
181
|
+
text-align: center;
|
182
|
+
font-size: 15px;
|
183
|
+
}
|
184
|
+
/* Social Icons ------------------------------ */
|
185
|
+
|
186
|
+
.social {
|
187
|
+
width: auto;
|
188
|
+
}
|
189
|
+
|
190
|
+
.social td {
|
191
|
+
padding: 0;
|
192
|
+
width: auto;
|
193
|
+
}
|
194
|
+
|
195
|
+
.social_icon {
|
196
|
+
height: 20px;
|
197
|
+
margin: 0 8px 10px 8px;
|
198
|
+
padding: 0;
|
199
|
+
}
|
200
|
+
/* Data table ------------------------------ */
|
201
|
+
|
202
|
+
.purchase {
|
203
|
+
width: 100%;
|
204
|
+
margin: 0;
|
205
|
+
padding: 35px 0;
|
206
|
+
}
|
207
|
+
|
208
|
+
.purchase_content {
|
209
|
+
width: 100%;
|
210
|
+
margin: 0;
|
211
|
+
padding: 25px 0 0 0;
|
212
|
+
}
|
213
|
+
|
214
|
+
.purchase_item {
|
215
|
+
padding: 10px 0;
|
216
|
+
color: #3E4B5B;
|
217
|
+
font-size: 15px;
|
218
|
+
line-height: 18px;
|
219
|
+
}
|
220
|
+
|
221
|
+
.purchase_heading {
|
222
|
+
padding-bottom: 8px;
|
223
|
+
border-bottom: 1px solid #EDEFF2;
|
224
|
+
}
|
225
|
+
|
226
|
+
.purchase_heading p {
|
227
|
+
margin: 0;
|
228
|
+
color: #9BA2AB;
|
229
|
+
font-size: 12px;
|
230
|
+
}
|
231
|
+
|
232
|
+
.purchase_footer {
|
233
|
+
padding-top: 15px;
|
234
|
+
border-top: 1px solid #EDEFF2;
|
235
|
+
}
|
236
|
+
|
237
|
+
.purchase_total {
|
238
|
+
margin: 0;
|
239
|
+
text-align: right;
|
240
|
+
/*font-weight: bold;*/
|
241
|
+
color: #3E4B5B;
|
242
|
+
}
|
243
|
+
|
244
|
+
.purchase_total--label {
|
245
|
+
padding: 0 15px 0 0;
|
246
|
+
}
|
247
|
+
/* Utilities ------------------------------ */
|
248
|
+
|
249
|
+
.align-right {
|
250
|
+
text-align: right;
|
251
|
+
}
|
252
|
+
|
253
|
+
.align-left {
|
254
|
+
text-align: left;
|
255
|
+
}
|
256
|
+
|
257
|
+
.align-center {
|
258
|
+
text-align: center;
|
259
|
+
}
|
260
|
+
/*Media Queries ------------------------------ */
|
261
|
+
|
262
|
+
@media only screen and (max-width: 600px) {
|
263
|
+
.email-body_inner,
|
264
|
+
.email-footer {
|
265
|
+
width: 100% !important;
|
266
|
+
}
|
267
|
+
}
|
268
|
+
|
269
|
+
@media only screen and (max-width: 500px) {
|
270
|
+
.button {
|
271
|
+
width: 100% !important;
|
272
|
+
}
|
273
|
+
}
|
274
|
+
/* Buttons ------------------------------ */
|
275
|
+
|
276
|
+
.button {
|
277
|
+
background-color: #047BF8;
|
278
|
+
border-top: 10px solid #047BF8;
|
279
|
+
border-right: 18px solid #047BF8;
|
280
|
+
border-bottom: 10px solid #047BF8;
|
281
|
+
border-left: 18px solid #047BF8;
|
282
|
+
display: inline-block;
|
283
|
+
color: #FFF;
|
284
|
+
text-decoration: none;
|
285
|
+
border-radius: 3px;
|
286
|
+
-webkit-text-size-adjust: none;
|
287
|
+
line-height: 22px;
|
288
|
+
font-size: 16px;
|
289
|
+
color: #FFF;
|
290
|
+
}
|
291
|
+
|
292
|
+
.button--link {
|
293
|
+
background-color: transparent;
|
294
|
+
border-top: 10px solid transparent;
|
295
|
+
border-right: 18px solid transparent;
|
296
|
+
border-bottom: 10px solid transparent;
|
297
|
+
border-left: 18px solid transparent;
|
298
|
+
display: inline-block;
|
299
|
+
color: #047BF8;
|
300
|
+
text-decoration: underline;
|
301
|
+
border-radius: 3px;
|
302
|
+
/*box-shadow: 0 2px 3px rgba(0, 0, 0, 0.16);*/
|
303
|
+
-webkit-text-size-adjust: none;
|
304
|
+
}
|
305
|
+
|
306
|
+
.button--green {
|
307
|
+
background-color: #22BC66;
|
308
|
+
border-top: 10px solid #22BC66;
|
309
|
+
border-right: 18px solid #22BC66;
|
310
|
+
border-bottom: 10px solid #22BC66;
|
311
|
+
border-left: 18px solid #22BC66;
|
312
|
+
}
|
313
|
+
|
314
|
+
.button--red {
|
315
|
+
background-color: #FF6136;
|
316
|
+
border-top: 10px solid #FF6136;
|
317
|
+
border-right: 18px solid #FF6136;
|
318
|
+
border-bottom: 10px solid #FF6136;
|
319
|
+
border-left: 18px solid #FF6136;
|
320
|
+
}
|
321
|
+
/* Type ------------------------------ */
|
322
|
+
|
323
|
+
h1 {
|
324
|
+
margin-top: 0;
|
325
|
+
color: #3E4B5B;
|
326
|
+
font-size: 19px;
|
327
|
+
font-weight: bold;
|
328
|
+
text-align: left;
|
329
|
+
}
|
330
|
+
|
331
|
+
h2 {
|
332
|
+
margin-top: 0;
|
333
|
+
color: #3E4B5B;
|
334
|
+
font-size: 16px;
|
335
|
+
font-weight: bold;
|
336
|
+
text-align: left;
|
337
|
+
}
|
338
|
+
|
339
|
+
h3 {
|
340
|
+
margin-top: 0;
|
341
|
+
color: #3E4B5B;
|
342
|
+
font-size: 14px;
|
343
|
+
font-weight: bold;
|
344
|
+
text-align: left;
|
345
|
+
}
|
346
|
+
|
347
|
+
p {
|
348
|
+
margin-top: 0;
|
349
|
+
color: #3E4B5B;
|
350
|
+
font-size: 16px;
|
351
|
+
line-height: 1.5em;
|
352
|
+
text-align: left;
|
353
|
+
}
|
354
|
+
|
355
|
+
p.sub {
|
356
|
+
font-size: 12px;
|
357
|
+
}
|
358
|
+
|
359
|
+
p.center {
|
360
|
+
text-align: center;
|
361
|
+
}
|
362
|
+
|
363
|
+
.body-action.less-footer {
|
364
|
+
margin-bottom: 10px;
|
365
|
+
}
|
366
|
+
</style>
|
7
367
|
</head>
|
8
368
|
<body>
|
9
369
|
<% if content_for? :preheader %>
|
data/docs/indirection.md
CHANGED
@@ -1,53 +1,3 @@
|
|
1
|
-
#
|
1
|
+
# Overriding Framework Defaults
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
In software development, indirection is everywhere and takes many forms.
|
6
|
-
|
7
|
-
For example, in vanilla Rails development, you introduce a type of indirection when you extract a button label out of a view file and use the `t` helper to render the string from a translation YAML file. In the future, when another developer goes to update the button label, they will first open the view, they'll see `t(".submit")` and then have to reason a little bit about which translation file they need to open up in order to update that label.
|
8
|
-
|
9
|
-
Our goal in Bullet Train is to improve developer experience, not reduce it, so it was important that along with any instances of indirection we were introducing, we also included new tooling to ensure it was never a burden to developers. Thankfully, in practice we found that some of this new tooling improves even layers of indirection that have always been with us in Rails development.
|
10
|
-
|
11
|
-
## Solving Indirection in Views
|
12
|
-
|
13
|
-
### Resolving Partial Paths with `bin/resolve`
|
14
|
-
|
15
|
-
Even in vanilla Rails development, when you're looking at a view file, the path you see passed to a `render` call isn't the actual file name of the partial that will be rendered. This is even more true in Bullet Train where certain partial paths are [magically served from theme gems](/docs/themes.md).
|
16
|
-
|
17
|
-
`bin/resolve` makes it easy to figure out where where a partial is being served from:
|
18
|
-
|
19
|
-
```
|
20
|
-
$ bin/resolve shared/box
|
21
|
-
```
|
22
|
-
|
23
|
-
### Exposing Rendered Views with Xray
|
24
|
-
|
25
|
-
> TODO Is this still true in Rails 7? Does it not do something like this by default now?
|
26
|
-
|
27
|
-
If you're looking at a rendered view in the browser, it can be hard to know which file to open in order to make a change. To help, Bullet Train includes [Xray](https://github.com/brentd/xray-rails) by default, so you can right click on any element you see, select "Inspect Element", and you'll see comments in the HTML source telling you which file is powering a particular portion of the view, like this:
|
28
|
-
|
29
|
-
```
|
30
|
-
<!--XRAY START 90 /Users/andrewculver/.rbenv/versions/3.1.1/lib/ruby/gems/3.1.0/gems/bullet_train-themes-light-1.0.10/app/views/themes/light/workflow/_box.html.erb-->
|
31
|
-
```
|
32
|
-
|
33
|
-
Note that in the example above, the view in question isn't actually coming from the application repository. Instead, it's being included from the `bullet_train-themes-light` package. For instructions on how to customize it, see [Overriding the Framework](/docs/override).
|
34
|
-
|
35
|
-
### Drilling Down on Translation Keys
|
36
|
-
|
37
|
-
Even in vanilla Rails applications, extracting strings from view files into I18N translation YAML files introduces a layer of indirection. Bullet Train tries to improve the resulting DX with a couple tools that make it easier to figure out where a translation you see in your browser is coming from.
|
38
|
-
|
39
|
-
#### Show Translation Keys in the Browser with `?show_locales=true`
|
40
|
-
|
41
|
-
You can see the full translation key of any string on the page by adding `?show_locales=true` to the URL.
|
42
|
-
|
43
|
-
#### Log Translation Keys to the Console with `?log_locales=true`
|
44
|
-
|
45
|
-
You can also log all the translation key for anything being rendered to the console by adding `?log_locales=true` to the request URL. This can make it easier to copy and paste translation keys for strings that are rendered in non-selectable UI elements.
|
46
|
-
|
47
|
-
#### Resolving Translation Keys with `bin/resolve`
|
48
|
-
|
49
|
-
Once you have the full I18N translation key, you can use `bin/resolve` to figure out which package and file it's coming from. At that point, if you need to customize it, you can also use the `--eject` option to copy the the framework for customization in your local application:
|
50
|
-
|
51
|
-
```
|
52
|
-
$ bin/resolve en.account.onboarding.user_details.edit.header --eject --open
|
53
|
-
```
|
3
|
+
> TODO This section needs to be written.
|
data/docs/overriding.md
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
# Dealing with Indirection
|
2
|
+
|
3
|
+
## The Problem with Indirection
|
4
|
+
|
5
|
+
In software development, indirection is everywhere and takes many forms.
|
6
|
+
|
7
|
+
For example, in vanilla Rails development, you introduce a type of indirection when you extract a button label out of a view file and use the `t` helper to render the string from a translation YAML file. In the future, when another developer goes to update the button label, they will first open the view, they'll see `t(".submit")` and then have to reason a little bit about which translation file they need to open up in order to update that label.
|
8
|
+
|
9
|
+
Our goal in Bullet Train is to improve developer experience, not reduce it, so it was important that along with any instances of indirection we were introducing, we also included new tooling to ensure it was never a burden to developers. Thankfully, in practice we found that some of this new tooling improves even layers of indirection that have always been with us in Rails development.
|
10
|
+
|
11
|
+
## Solving Indirection in Views
|
12
|
+
|
13
|
+
### Resolving Partial Paths with `bin/resolve`
|
14
|
+
|
15
|
+
Even in vanilla Rails development, when you're looking at a view file, the path you see passed to a `render` call isn't the actual file name of the partial that will be rendered. This is even more true in Bullet Train where certain partial paths are [magically served from theme gems](/docs/themes.md).
|
16
|
+
|
17
|
+
`bin/resolve` makes it easy to figure out where where a partial is being served from:
|
18
|
+
|
19
|
+
```
|
20
|
+
$ bin/resolve shared/box
|
21
|
+
```
|
22
|
+
|
23
|
+
### Exposing Rendered Views with Xray
|
24
|
+
|
25
|
+
> TODO Is this still true in Rails 7? Does it not do something like this by default now?
|
26
|
+
|
27
|
+
If you're looking at a rendered view in the browser, it can be hard to know which file to open in order to make a change. To help, Bullet Train includes [Xray](https://github.com/brentd/xray-rails) by default, so you can right click on any element you see, select "Inspect Element", and you'll see comments in the HTML source telling you which file is powering a particular portion of the view, like this:
|
28
|
+
|
29
|
+
```
|
30
|
+
<!--XRAY START 90 /Users/andrewculver/.rbenv/versions/3.1.1/lib/ruby/gems/3.1.0/gems/bullet_train-themes-light-1.0.10/app/views/themes/light/workflow/_box.html.erb-->
|
31
|
+
```
|
32
|
+
|
33
|
+
Note that in the example above, the view in question isn't actually coming from the application repository. Instead, it's being included from the `bullet_train-themes-light` package. For instructions on how to customize it, see [Overriding the Framework](/docs/override).
|
34
|
+
|
35
|
+
### Drilling Down on Translation Keys
|
36
|
+
|
37
|
+
Even in vanilla Rails applications, extracting strings from view files into I18N translation YAML files introduces a layer of indirection. Bullet Train tries to improve the resulting DX with a couple tools that make it easier to figure out where a translation you see in your browser is coming from.
|
38
|
+
|
39
|
+
#### Show Translation Keys in the Browser with `?show_locales=true`
|
40
|
+
|
41
|
+
You can see the full translation key of any string on the page by adding `?show_locales=true` to the URL.
|
42
|
+
|
43
|
+
#### Log Translation Keys to the Console with `?log_locales=true`
|
44
|
+
|
45
|
+
You can also log all the translation key for anything being rendered to the console by adding `?log_locales=true` to the request URL. This can make it easier to copy and paste translation keys for strings that are rendered in non-selectable UI elements.
|
46
|
+
|
47
|
+
#### Resolving Translation Keys with `bin/resolve`
|
48
|
+
|
49
|
+
Once you have the full I18N translation key, you can use `bin/resolve` to figure out which package and file it's coming from. At that point, if you need to customize it, you can also use the `--eject` option to copy the the framework for customization in your local application:
|
50
|
+
|
51
|
+
```
|
52
|
+
$ bin/resolve en.account.onboarding.user_details.edit.header --eject --open
|
53
|
+
```
|
data/docs/super-scaffolding.md
CHANGED
@@ -154,7 +154,7 @@ rails g migration add_lead_to_projects lead:references
|
|
154
154
|
Then, to add the field, we specify the following:
|
155
155
|
|
156
156
|
```
|
157
|
-
bin/super-scaffold crud-field Project lead_id:super_select
|
157
|
+
bin/super-scaffold crud-field Project lead_id:super_select{class_name=Membership}
|
158
158
|
rake db:migrate
|
159
159
|
```
|
160
160
|
|
@@ -199,7 +199,7 @@ rails g model Projects::AppliedTag project:references tag:references
|
|
199
199
|
We're not going to scaffold this model with the typical `crud` scaffolder, but some preparation is needed before we can use it with the `crud-field` scaffolder, so we need to do the following:
|
200
200
|
|
201
201
|
```
|
202
|
-
bin/super-scaffold join-model Projects::AppliedTag project_id
|
202
|
+
bin/super-scaffold join-model Projects::AppliedTag project_id{class_name=Project} tag_id{class_name=Projects::Tag}
|
203
203
|
```
|
204
204
|
|
205
205
|
All we're doing here is specifying the name of the join model, and the two attributes and class names of the models it joins. Note again that we specify the `_id` suffix on both of the attributes.
|
@@ -207,7 +207,7 @@ All we're doing here is specifying the name of the join model, and the two attri
|
|
207
207
|
Now that the join model has been prepared, we can use the `crud-field` scaffolder to create the multi-select field:
|
208
208
|
|
209
209
|
```
|
210
|
-
bin/super-scaffold crud-field Project tag_ids:super_select
|
210
|
+
bin/super-scaffold crud-field Project tag_ids:super_select{class_name=Projects::Tag}
|
211
211
|
rake db:migrate
|
212
212
|
```
|
213
213
|
|
data/lib/bullet_train/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bullet_train
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.41
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrew Culver
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-03-
|
11
|
+
date: 2022-03-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -497,7 +497,6 @@ files:
|
|
497
497
|
- config/locales/en/onboarding/user_email.en.yml
|
498
498
|
- config/locales/en/roles.en.yml
|
499
499
|
- config/locales/en/teams.en.yml
|
500
|
-
- config/locales/en/user_mailer.en.yml
|
501
500
|
- config/locales/en/users.en.yml
|
502
501
|
- config/routes.rb
|
503
502
|
- db/migrate/20161115160419_devise_create_users.rb
|
@@ -552,6 +551,7 @@ files:
|
|
552
551
|
- docs/namespacing.md
|
553
552
|
- docs/oauth.md
|
554
553
|
- docs/onboarding.md
|
554
|
+
- docs/overriding.md
|
555
555
|
- docs/permissions.md
|
556
556
|
- docs/seeds.md
|
557
557
|
- docs/super-scaffolding.md
|
@@ -1,36 +0,0 @@
|
|
1
|
-
en:
|
2
|
-
user_mailer:
|
3
|
-
signature: &SIGNATURE
|
4
|
-
html:
|
5
|
-
<p>If you have any questions, please don't hesitate to <a href="mailto:%{support_email}">send us an email</a>.</p>
|
6
|
-
<p>Thanks,<br>Bullet Train, Inc.</p>
|
7
|
-
invited:
|
8
|
-
subject: Invitation to join %{team_name} on Bullet Train!
|
9
|
-
preview: '%{inviter_name} has sent you this invitation.'
|
10
|
-
heading: You're invited!
|
11
|
-
body:
|
12
|
-
html:
|
13
|
-
<p>
|
14
|
-
%{inviter_name} has invited you to join %{team_name} on Bullet Train.
|
15
|
-
You can join %{team_name} by clicking the button below.
|
16
|
-
</p>
|
17
|
-
cta:
|
18
|
-
label: Join %{team_name}
|
19
|
-
signature:
|
20
|
-
<<: *SIGNATURE
|
21
|
-
welcome:
|
22
|
-
subject: Welcome to the Bullet Train demo!
|
23
|
-
preview: This is the default Bullet Train welcome email. Check out the layout!
|
24
|
-
heading: Welcome to Bullet Train!
|
25
|
-
body:
|
26
|
-
html:
|
27
|
-
<p>This is the default welcome email for Bullet Train!</p>
|
28
|
-
<p>If you have any questions about Bullet Train, just reply to this email!</p>
|
29
|
-
<p>It was important to us that Bullet Train applications have a good looking, branded email template by default.</p>
|
30
|
-
<p>Thankfully our friends at <a href="https://postmarkapp.com">Postmark</a> made the foundation of this email template <a href="https://github.com/wildbit/postmark-templates">freely available</a>. From there, we've customized it slightly to better match the default Bullet Train look-and-feel.</p>
|
31
|
-
cta:
|
32
|
-
heading: What's next?
|
33
|
-
body: You can use the following link to always return to your Bullet Train account dashboard.
|
34
|
-
label: View Your Account Dashboard
|
35
|
-
signature:
|
36
|
-
<<: *SIGNATURE
|