WEBVTT

1
00:00:00.540 --> 00:00:01.770
Welcome to Ruby on Rails!

2
00:00:01.770 --> 00:00:04.770
If you are looking to go from Hello World to IPO,

3
00:00:04.770 --> 00:00:07.080
you’ve come to just the right place.

4
00:00:07.080 --> 00:00:08.730
I’m gonna build a simple application

5
00:00:08.730 --> 00:00:11.010
that shows you the basics of Ruby on Rails

6
00:00:11.010 --> 00:00:13.500
and how you put it into production.

7
00:00:13.500 --> 00:00:15.120
Let’s go!

8
00:00:15.120 --> 00:00:17.340
We’re gonna start by running Rail’s new blog.

9
00:00:17.340 --> 00:00:19.230
To get the basic Rails skeleton,

10
00:00:19.230 --> 00:00:20.730
let’s hop into that skeleton,

11
00:00:20.730 --> 00:00:23.610
and then we’re gonna generate a scaffold for a post.

12
00:00:23.610 --> 00:00:26.820
That post is just going to have a title that’s a string

13
00:00:26.820 --> 00:00:28.020
and a body that’s a text,

14
00:00:28.020 --> 00:00:30.330
and as you can see here from what’s being generated,

15
00:00:30.330 --> 00:00:34.200
we have everything that we need to set up a basic interface

16
00:00:34.200 --> 00:00:36.060
for that post scaffold.

17
00:00:36.060 --> 00:00:40.350
There is a migration that’ll set things up in the database.

18
00:00:40.350 --> 00:00:43.380
There is a controller, there are views, there’s a model,

19
00:00:43.380 --> 00:00:46.800
there’s even testing stubs and adjacent API on top.

20
00:00:46.800 --> 00:00:48.690
So, let’s run that migration,

21
00:00:48.690 --> 00:00:50.910
and as you can see here, we created the posts

22
00:00:50.910 --> 00:00:53.220
in the main schema file,

23
00:00:53.220 --> 00:00:57.450
and now, we’re ready to have a look at the application

24
00:00:57.450 --> 00:01:00.360
that was generated here with the post scaffold.

25
00:01:00.360 --> 00:01:02.820
So, let’s jump into the post controller first.

26
00:01:02.820 --> 00:01:05.310
The controller is really what guides

27
00:01:05.310 --> 00:01:09.450
all the inbound actions you get into a Rails application,

28
00:01:09.450 --> 00:01:13.530
you’ll have the user hitting /posts or /postnew,

29
00:01:13.530 --> 00:01:17.280
and it gets routed into the post controller!

30
00:01:17.280 --> 00:01:19.620
All post controllers follow the same convention.

31
00:01:19.620 --> 00:01:23.190
There are seven actions, you have index, show, new,

32
00:01:23.190 --> 00:01:27.000
edit, create, and update and destroy!

33
00:01:27.000 --> 00:01:28.410
So, these form

34
00:01:28.410 --> 00:01:30.330
a basic setup

35
00:01:30.330 --> 00:01:34.110
for configuring everything that’s needed for a resource

36
00:01:34.110 --> 00:01:36.720
to be exposed to the web.

37
00:01:36.720 --> 00:01:37.920
And if you scroll down here,

38
00:01:37.920 --> 00:01:40.860
you can see we have everything served in two flavors,

39
00:01:40.860 --> 00:01:44.820
we have both the HTML setup that’ll render views directly,

40
00:01:44.820 --> 00:01:49.530
and then you have JSON that’ll render for an API.

41
00:01:49.530 --> 00:01:51.420
And as you can see here, we’re also setting up

42
00:01:51.420 --> 00:01:53.760
a new post for some of those actions

43
00:01:53.760 --> 00:01:56.790
that require that, we’re gonna find it straight off an ID

44
00:01:56.790 --> 00:01:59.850
passed in through the URL, and the post parameters

45
00:01:59.850 --> 00:02:01.950
are the ones we’re using when we’re creating

46
00:02:01.950 --> 00:02:04.203
and updating the application.

47
00:02:05.040 --> 00:02:06.990
If we jump into the post model,

48
00:02:06.990 --> 00:02:09.000
you’ll see there’s actually nothing here.

49
00:02:09.000 --> 00:02:10.260
Everything in the post model

50
00:02:10.260 --> 00:02:12.810
is made available through introspection.

51
00:02:12.810 --> 00:02:16.950
So, a new post model will look at the schema for that table,

52
00:02:16.950 --> 00:02:20.970
and it will know that there is a title and there is a body,

53
00:02:20.970 --> 00:02:22.140
and we can access that title

54
00:02:22.140 --> 00:02:25.530
in that body directly through this post object.

55
00:02:25.530 --> 00:02:27.870
And as it descends from application record,

56
00:02:27.870 --> 00:02:30.300
we can run everything from updates and destroys,

57
00:02:30.300 --> 00:02:31.950
and what have you.

58
00:02:31.950 --> 00:02:35.250
This is also where we’re gonna put our specific logic

59
00:02:35.250 --> 00:02:36.870
that’s particular to this application

60
00:02:36.870 --> 00:02:41.070
beyond just the management of attributes.

61
00:02:41.070 --> 00:02:41.903
And then finally,

62
00:02:41.903 --> 00:02:44.490
we have the views that are being generated.

63
00:02:44.490 --> 00:02:47.640
If we hop in here and have a look at the index view,

64
00:02:47.640 --> 00:02:50.837
you can see this is where we will list all the posts

65
00:02:50.837 --> 00:02:51.990
that are in the system.

66
00:02:51.990 --> 00:02:56.190
And Rails uses ERB, which is essentially embedded Ruby.

67
00:02:56.190 --> 00:03:00.180
So, you mix HTML with Ruby in line,

68
00:03:00.180 --> 00:03:02.910
and you can split out more complicated functions

69
00:03:02.910 --> 00:03:03.960
into helper methods.

70
00:03:03.960 --> 00:03:08.960
But otherwise, this is the clearest cut setup in Rails

71
00:03:09.180 --> 00:03:13.653
that is the default for integrating HTML and Ruby.

72
00:03:15.330 --> 00:03:16.710
Now if we hop over

73
00:03:16.710 --> 00:03:18.690
and start up our development server,

74
00:03:18.690 --> 00:03:21.360
you do that with just bin/dev.

75
00:03:21.360 --> 00:03:24.240
If we were running a Rails application

76
00:03:24.240 --> 00:03:27.600
that also had auxiliary watcher processes

77
00:03:27.600 --> 00:03:30.390
such as one for ES build or for Tailwind,

78
00:03:30.390 --> 00:03:32.430
bin dev would start those as well.

79
00:03:32.430 --> 00:03:35.580
But this version of our Rails blog,

80
00:03:35.580 --> 00:03:38.880
it’s just going to be built with all vanilla, no build

81
00:03:38.880 --> 00:03:43.410
set up so we only need to start the Puma, Ruby web server,

82
00:03:43.410 --> 00:03:45.870
and we can hop over into the browser and see here.

83
00:03:45.870 --> 00:03:46.950
This is the thing you’re gonna see

84
00:03:46.950 --> 00:03:48.660
when you start up a new Rails application,

85
00:03:48.660 --> 00:03:50.310
it’ll tell you which version you’re on,

86
00:03:50.310 --> 00:03:52.440
both for the Ruby version, the Rails version,

87
00:03:52.440 --> 00:03:53.700
and the Rack version

88
00:03:53.700 --> 00:03:58.260
that’s running on localhost:3000 S by default.

89
00:03:58.260 --> 00:04:01.020
But if we do slash posts here,

90
00:04:01.020 --> 00:04:04.380
you’ll see the scaffold interface that we generated.

91
00:04:04.380 --> 00:04:05.670
Now, this is the index action,

92
00:04:05.670 --> 00:04:07.500
the one we just looked at in the view

93
00:04:07.500 --> 00:04:08.760
and from the controller.

94
00:04:08.760 --> 00:04:12.540
But if we click the New, you see here we have a form

95
00:04:12.540 --> 00:04:16.440
for creating the new post with its title and its body.

96
00:04:16.440 --> 00:04:20.430
It’s quite basic, to put it mildly right now,

97
00:04:20.430 --> 00:04:22.710
but all the actions are mapped out.

98
00:04:22.710 --> 00:04:23.790
This scaffold interface

99
00:04:23.790 --> 00:04:26.520
is not meant for shipping into production,

100
00:04:26.520 --> 00:04:30.210
it is meant to showing you how to build a Rails application

101
00:04:30.210 --> 00:04:32.850
with the basics, and then you make it look pretty,

102
00:04:32.850 --> 00:04:34.020
you make it look nice.

103
00:04:34.020 --> 00:04:35.940
But oh yeah!

104
00:04:35.940 --> 00:04:37.290
Let me show you real (chuckling) quick here,

105
00:04:37.290 --> 00:04:39.270
if you do a /post.json,

106
00:04:39.270 --> 00:04:42.150
you’re gonna get that automatic API as well,

107
00:04:42.150 --> 00:04:43.890
as I showed you in the controller,

108
00:04:43.890 --> 00:04:44.910
there are two different paths,

109
00:04:44.910 --> 00:04:46.800
you have HTML, and you have JSON.

110
00:04:46.800 --> 00:04:50.280
You could also have added XML in there or another path,

111
00:04:50.280 --> 00:04:53.790
but by default, you just get these two different variants,

112
00:04:53.790 --> 00:04:55.593
the HTML and the JSON variant.

113
00:04:56.580 --> 00:04:58.840
Now if we hop back into

114
00:05:00.150 --> 00:05:03.720
our editor here, I can add a little bit of styling

115
00:05:03.720 --> 00:05:07.710
to make this look slightly nicer than the very basic layout

116
00:05:07.710 --> 00:05:10.440
that you get with the scaffold.

117
00:05:10.440 --> 00:05:12.750
By default, I like to use simple CSS.

118
00:05:12.750 --> 00:05:17.750
It is simply a individual file that’s being included,

119
00:05:17.820 --> 00:05:19.080
I don’t have to compile anything here,

120
00:05:19.080 --> 00:05:21.630
I’m just referencing it straight off their CDN.

121
00:05:21.630 --> 00:05:24.390
And if we save that and reload,

122
00:05:24.390 --> 00:05:26.280
you can see it just looks a little nicer.

123
00:05:26.280 --> 00:05:29.610
Now, Rails has a bunch of different ways you can do the CSS,

124
00:05:29.610 --> 00:05:32.190
there’s also a path where you can use Tailwind.

125
00:05:32.190 --> 00:05:34.140
Lots of people like that for good reason,

126
00:05:34.140 --> 00:05:36.930
and there are a bunch of different options,

127
00:05:36.930 --> 00:05:39.270
all the major CSS frameworks are available,

128
00:05:39.270 --> 00:05:42.630
but by default, we ship with a no build, as I said,

129
00:05:42.630 --> 00:05:45.870
intention and simple CSS just makes things look prettier

130
00:05:45.870 --> 00:05:48.480
without having to adorn anything with classes,

131
00:05:48.480 --> 00:05:49.800
or what have you.

132
00:05:49.800 --> 00:05:52.080
Now, lemme show you one of the first features here.

133
00:05:52.080 --> 00:05:57.080
If we do raise exception inside the index action,

134
00:05:57.300 --> 00:06:01.830
you will see that Rails provides some really nice interface

135
00:06:01.830 --> 00:06:03.030
for dealing with that exception,

136
00:06:03.030 --> 00:06:05.100
seeing exactly where it happened.

137
00:06:05.100 --> 00:06:07.080
If I’m reloading here, you can see the line,

138
00:06:07.080 --> 00:06:10.260
it was raised on the source code that’s around it,

139
00:06:10.260 --> 00:06:11.910
you can see a full trace.

140
00:06:11.910 --> 00:06:14.700
And down here, we even have a console!

141
00:06:14.700 --> 00:06:17.550
So, you can interact with the instance variables

142
00:06:17.550 --> 00:06:19.260
that have been set for this index action,

143
00:06:19.260 --> 00:06:22.920
here’s just at posts that’s been made available.

144
00:06:22.920 --> 00:06:25.260
And you can help diagnose whatever issue

145
00:06:25.260 --> 00:06:26.520
that it is that you have!

146
00:06:26.520 --> 00:06:27.900
But let’s remove that again,

147
00:06:27.900 --> 00:06:30.510
and then let’s look at the console from another angle.

148
00:06:30.510 --> 00:06:31.800
Now, you can get the console

149
00:06:31.800 --> 00:06:33.720
as I just showed you when an exception is raised,

150
00:06:33.720 --> 00:06:35.370
but you can also get the console

151
00:06:35.370 --> 00:06:37.350
if you just run rails console!

152
00:06:37.350 --> 00:06:39.750
Now you have access to your entire domain model.

153
00:06:39.750 --> 00:06:42.480
So if we find the first post that we created, we can update

154
00:06:42.480 --> 00:06:45.000
that post straight here from the console,

155
00:06:45.000 --> 00:06:49.440
if we hop back, you see, title is now changed from CLI.

156
00:06:49.440 --> 00:06:52.800
This is exceptionally helpful for interacting

157
00:06:52.800 --> 00:06:56.220
with your domain model, updating things on the fly,

158
00:06:56.220 --> 00:06:58.650
and as you will see later, updating things

159
00:06:58.650 --> 00:07:01.410
even once you’ve deployed this to production!

160
00:07:01.410 --> 00:07:03.240
Now, let’s install something else here,

161
00:07:03.240 --> 00:07:04.980
let’s install action_text,

162
00:07:04.980 --> 00:07:07.320
that is one of the frameworks that’s part of Rails,

163
00:07:07.320 --> 00:07:08.580
but it’s not set up by default,

164
00:07:08.580 --> 00:07:12.510
but you can set it up by running rails action_text:install,

165
00:07:12.510 --> 00:07:15.390
that’s going to give you a WYSIWYG editor

166
00:07:15.390 --> 00:07:16.920
that’s currently powered by Trix!

167
00:07:16.920 --> 00:07:18.810
The open source, what you see

168
00:07:18.810 --> 00:07:21.210
is what you get editor made in JavaScript!

169
00:07:21.210 --> 00:07:24.060
And it also sets up active storage!

170
00:07:24.060 --> 00:07:27.660
Active storage is a way to deal with attachments

171
00:07:27.660 --> 00:07:30.660
and other files in your Rails application.

172
00:07:30.660 --> 00:07:32.700
When you run it through action_text:install,

173
00:07:32.700 --> 00:07:33.750
it’ll automatically set up

174
00:07:33.750 --> 00:07:36.420
those active storage tables that we need,

175
00:07:36.420 --> 00:07:39.030
there is one for the blob,

176
00:07:39.030 --> 00:07:41.400
and then we have one for text here.

177
00:07:41.400 --> 00:07:43.230
We run migrations to set that up again,

178
00:07:43.230 --> 00:07:46.320
and now that we’ve run action_text:install,

179
00:07:46.320 --> 00:07:47.730
it also added a couple of gems,

180
00:07:47.730 --> 00:07:49.770
so we need to restart our development server.

181
00:07:49.770 --> 00:07:52.053
I do that just by exiting out

182
00:07:52.053 --> 00:07:53.790
and then just running the server again!

183
00:07:53.790 --> 00:07:55.870
If we then hop into our

184
00:07:57.360 --> 00:08:00.090
post model, we can declare that that post model

185
00:08:00.090 --> 00:08:01.860
has rich text body.

186
00:08:01.860 --> 00:08:04.170
We’re gonna convert the plain text body

187
00:08:04.170 --> 00:08:07.410
that we had just a second ago to a rich text body

188
00:08:07.410 --> 00:08:10.470
that is accessible through the WYSIWYG editor,

189
00:08:10.470 --> 00:08:11.370
and that accepts

190
00:08:11.370 --> 00:08:15.033
those active storage attachments and uploads.

191
00:08:16.590 --> 00:08:17.670
But before we can do that,

192
00:08:17.670 --> 00:08:20.880
let’s change the text area we had in the form here

193
00:08:20.880 --> 00:08:24.210
for our new post to be a rich text area.

194
00:08:24.210 --> 00:08:25.890
That’s basically all you have to change,

195
00:08:25.890 --> 00:08:29.040
and let’s save that and hop back into creating a new post.

196
00:08:29.040 --> 00:08:33.930
As you can see here, there is now a full WYSIWYG interface

197
00:08:33.930 --> 00:08:35.430
for creating the body.

198
00:08:35.430 --> 00:08:39.150
It comes with a default set of styles for the toolbar,

199
00:08:39.150 --> 00:08:40.020
you can change those,

200
00:08:40.020 --> 00:08:42.390
those styles are generated straight into your application,

201
00:08:42.390 --> 00:08:44.310
so you can make it look nice for yourself.

202
00:08:44.310 --> 00:08:47.895
Let’s give some bold and italic text here, you see,

203
00:08:47.895 --> 00:08:48.750
that was all that was needed.

204
00:08:48.750 --> 00:08:51.270
But I think what’s even nicer to look at here

205
00:08:51.270 --> 00:08:54.390
is if we do an upload and we add a file,

206
00:08:54.390 --> 00:08:57.390
you will see that that file gets added with a preview

207
00:08:57.390 --> 00:09:00.360
directly to the WYSIWYG editor.

208
00:09:00.360 --> 00:09:01.407
And if we save that

209
00:09:01.407 --> 00:09:04.710
and we update the post, it is added to the post itself.

210
00:09:04.710 --> 00:09:05.850
And that then went through

211
00:09:05.850 --> 00:09:09.660
the whole process of doing a direct upload of the file

212
00:09:09.660 --> 00:09:11.310
when we dropped it into the editor,

213
00:09:11.310 --> 00:09:13.450
that uploads it straight to active text

214
00:09:14.610 --> 00:09:16.620
or (indistinct) storage, excuse me.

215
00:09:16.620 --> 00:09:21.450
And then, we have access to that, and rendering it directly

216
00:09:21.450 --> 00:09:24.360
from whatever storage backend active storage is using.

217
00:09:24.360 --> 00:09:26.040
In this example, we’re just storing on disk,

218
00:09:26.040 --> 00:09:29.220
but you could be storing your active storage in S3

219
00:09:29.220 --> 00:09:31.110
or another object storage.

220
00:09:31.110 --> 00:09:35.790
Now, let’s add a bit of custom JavaScript.

221
00:09:35.790 --> 00:09:38.100
Rails by default ships with Hotwire!

222
00:09:38.100 --> 00:09:39.750
Hotwire gives you Turbo,

223
00:09:39.750 --> 00:09:42.690
which is a way of accelerating page changes

224
00:09:42.690 --> 00:09:44.220
and updates is that your application

225
00:09:44.220 --> 00:09:48.390
will feel as fast and as smooth as a single page application

226
00:09:48.390 --> 00:09:50.190
without you basically having to write

227
00:09:50.190 --> 00:09:51.750
any JavaScript at all.

228
00:09:51.750 --> 00:09:54.690
And then, there’s the stimulus framework

229
00:09:54.690 --> 00:09:57.300
for creating that additional functionality

230
00:09:57.300 --> 00:09:58.980
that you might need in a really simple way.

231
00:09:58.980 --> 00:10:03.150
You can have a look at hotwire.dev to see more about that,

232
00:10:03.150 --> 00:10:04.620
but what we’re gonna add here is

233
00:10:04.620 --> 00:10:06.210
a little piece of JavaScript

234
00:10:06.210 --> 00:10:08.460
to just add some additional functionality,

235
00:10:08.460 --> 00:10:11.130
pulling something in from NPN!

236
00:10:11.130 --> 00:10:15.210
So, we can do that using the import map pin command.

237
00:10:15.210 --> 00:10:17.070
And as you see, now that I hop back into

238
00:10:17.070 --> 00:10:18.540
our config import map,

239
00:10:18.540 --> 00:10:22.770
we’ve added the local text pin at the bottom, version 302.

240
00:10:22.770 --> 00:10:24.690
It pulled that straight off NPN,

241
00:10:24.690 --> 00:10:28.320
it downloaded that as a vendor dependency

242
00:10:28.320 --> 00:10:30.360
that we can check into our version control system.

243
00:10:30.360 --> 00:10:33.540
And now, we don’t have any runtime dependency whatsoever

244
00:10:33.540 --> 00:10:36.150
on NPN, or anything else like that.

245
00:10:36.150 --> 00:10:37.320
You don’t need anything

246
00:10:37.320 --> 00:10:40.260
beyond what Rails ship you with already

247
00:10:40.260 --> 00:10:44.250
because Rails 8 is all no build by default!

248
00:10:44.250 --> 00:10:47.190
That means there’s not a transpiler,

249
00:10:47.190 --> 00:10:48.840
that means there’s not a bundler,

250
00:10:48.840 --> 00:10:53.280
these files are shipped directly to the browser over HTTP2,

251
00:10:53.280 --> 00:10:54.903
so it’s nice and fast.

252
00:10:55.860 --> 00:10:59.910
And the import map is what allows us to refer to these files

253
00:10:59.910 --> 00:11:02.550
by their logical names while still doing

254
00:11:02.550 --> 00:11:06.240
far future digesting, so that they load really quick,

255
00:11:06.240 --> 00:11:08.790
and such that they’re easily compatible with CDNs

256
00:11:08.790 --> 00:11:10.140
and all that good stuff.

257
00:11:10.140 --> 00:11:11.400
But now that we’ve added that,

258
00:11:11.400 --> 00:11:14.520
let’s have a look at our application JS file.

259
00:11:14.520 --> 00:11:16.020
That’s the default setup that you have

260
00:11:16.020 --> 00:11:18.330
that the scaffold is going to use.

261
00:11:18.330 --> 00:11:20.550
And as you can see, we’re using turbo-rails,

262
00:11:20.550 --> 00:11:22.320
we’re including all the stimulus controllers,

263
00:11:22.320 --> 00:11:23.160
if we have any.

264
00:11:23.160 --> 00:11:26.700
We’re including trix and action text to give the WYSIWYG,

265
00:11:26.700 --> 00:11:31.140
and now we’re gonna add that local text package as well.

266
00:11:31.140 --> 00:11:34.110
And we’re gonna start local time here.

267
00:11:34.110 --> 00:11:36.420
And in the local time, we’re gonna use it,

268
00:11:36.420 --> 00:11:39.120
and we’re gonna use it for adding

269
00:11:39.120 --> 00:11:41.070
the updated at timestamp here.

270
00:11:41.070 --> 00:11:44.700
And as you can see here, we’re just adding a time tag

271
00:11:44.700 --> 00:11:49.700
that’s just a vanilla HTML tag that has a data local time,

272
00:11:50.250 --> 00:11:54.120
that’s what activates the local time JavaScript set up.

273
00:11:54.120 --> 00:11:55.740
And we will give it a format

274
00:11:55.740 --> 00:11:59.010
for what it should do with that UTC timestamp,

275
00:11:59.010 --> 00:12:03.090
and turning it into a local time that we can have a look at.

276
00:12:03.090 --> 00:12:07.380
So if I reload here, you see it is November 13th,

277
00:12:07.380 --> 00:12:10.620
by the time of my recording at 3:28 PM

278
00:12:10.620 --> 00:12:14.280
in my local time zone, but actually underneath, the time tag

279
00:12:14.280 --> 00:12:16.530
is gonna be in UTC.

280
00:12:16.530 --> 00:12:19.320
That means we can cache this, and anyone around the world

281
00:12:19.320 --> 00:12:22.560
will still get the time displayed in their local time.

282
00:12:22.560 --> 00:12:23.730
Just a nice feature.

283
00:12:23.730 --> 00:12:27.510
But really, what’s unique here for Rails

284
00:12:27.510 --> 00:12:29.580
is the fact that we’re using no build by default!

285
00:12:29.580 --> 00:12:31.590
So if I go over here in the inspector

286
00:12:31.590 --> 00:12:33.870
and look at the JavaScript files that are included,

287
00:12:33.870 --> 00:12:37.200
you can see we have the application js file

288
00:12:37.200 --> 00:12:39.720
with a little digest stamp on there.

289
00:12:39.720 --> 00:12:42.810
If we change anything that application js file,

290
00:12:42.810 --> 00:12:44.310
the digest is going to change,

291
00:12:44.310 --> 00:12:46.890
and the browser will redownload just that part!

292
00:12:46.890 --> 00:12:49.170
But everything else, turbo and stimulus,

293
00:12:49.170 --> 00:12:51.930
if they’re not changing, we’re not downloading that.

294
00:12:51.930 --> 00:12:53.130
That is why no build

295
00:12:53.130 --> 00:12:56.640
is such an efficient way of dealing with caching.

296
00:12:56.640 --> 00:12:59.130
But we can also have a look at a specific file,

297
00:12:59.130 --> 00:13:02.010
you’ll see it matches exactly what we have back there.

298
00:13:02.010 --> 00:13:03.600
That’s not a development setup!

299
00:13:03.600 --> 00:13:05.790
That is what we’re shipping in production.

300
00:13:05.790 --> 00:13:09.480
There is no minification, there’s no transpilation,

301
00:13:09.480 --> 00:13:10.590
there’s none of that nonsense

302
00:13:10.590 --> 00:13:11.910
because you just don’t need it.

303
00:13:11.910 --> 00:13:14.940
We’re G sipping or Brotli-ing this stuff

304
00:13:14.940 --> 00:13:17.070
so that it transports really quickly,

305
00:13:17.070 --> 00:13:18.450
but we’re allowing you

306
00:13:18.450 --> 00:13:21.240
to view source on an entire application.

307
00:13:21.240 --> 00:13:23.580
If you look at something like hey.com,

308
00:13:23.580 --> 00:13:26.910
you’ll see this technique in use on a major application,

309
00:13:26.910 --> 00:13:29.400
and you can view all of the JavaScript that we use

310
00:13:29.400 --> 00:13:33.420
to build that application, and that’s the default for Rails.

311
00:13:33.420 --> 00:13:35.190
Now again, if you don’t want any of this stuff,

312
00:13:35.190 --> 00:13:39.450
there is a way using JS bundler dash Rails

313
00:13:39.450 --> 00:13:41.460
to set things up in a more traditional way

314
00:13:41.460 --> 00:13:43.740
using ES build and what have you.

315
00:13:43.740 --> 00:13:46.290
But this is a wonderful way of developing

316
00:13:46.290 --> 00:13:48.270
modern web applications.

317
00:13:48.270 --> 00:13:53.010
Alright! Now let’s add some comments to our blogging system!

318
00:13:53.010 --> 00:13:54.720
And I’m gonna use a different generator here,

319
00:13:54.720 --> 00:13:56.700
I’m gonna use a resource generator

320
00:13:56.700 --> 00:13:57.720
that is a little lighter

321
00:13:57.720 --> 00:13:59.070
than the one we were using for scaffold

322
00:13:59.070 --> 00:14:00.690
that doesn’t generate a bunch of views,

323
00:14:00.690 --> 00:14:03.090
and doesn’t generate all sorts of actions

324
00:14:03.090 --> 00:14:06.180
in the controller by default, but it does generate

325
00:14:06.180 --> 00:14:07.290
the new model that we need,

326
00:14:07.290 --> 00:14:11.340
the comment model, it generates a migration for that,

327
00:14:11.340 --> 00:14:13.290
create comments, and it generates

328
00:14:13.290 --> 00:14:16.800
just some empty placeholders for the comments controller

329
00:14:16.800 --> 00:14:19.440
and for the view action.

330
00:14:19.440 --> 00:14:22.415
So, let’s run the migration for that,

331
00:14:22.415 --> 00:14:23.340
that sets up the comments table.

332
00:14:23.340 --> 00:14:25.950
You can see here the schema that we’ve now built up.

333
00:14:25.950 --> 00:14:29.220
We’ve added a number of tables for action text

334
00:14:29.220 --> 00:14:30.930
and action storage.

335
00:14:30.930 --> 00:14:33.960
And then, we have added a comments table.

336
00:14:33.960 --> 00:14:35.730
That’s as you see here.

337
00:14:35.730 --> 00:14:37.380
As we had it in the migration

338
00:14:37.380 --> 00:14:41.550
where we were just referencing the post as a foreign key,

339
00:14:41.550 --> 00:14:44.010
and then we had the content as text.

340
00:14:44.010 --> 00:14:47.130
And then, Rails by default also adds two timestamps

341
00:14:47.130 --> 00:14:50.733
that it keeps track of by itself, created ad and updated ad.

342
00:14:51.690 --> 00:14:55.083
And below that, you had the post that we added originally.

343
00:14:56.040 --> 00:15:00.870
Alright, if we hop into that comments controller,

344
00:15:00.870 --> 00:15:01.770
it was empty.

345
00:15:01.770 --> 00:15:03.780
As you can see there, I’m gonna pay something in

346
00:15:03.780 --> 00:15:05.490
that actually makes this stuff work!

347
00:15:05.490 --> 00:15:08.940
You’ll see one principle of the controller setup we have

348
00:15:08.940 --> 00:15:10.976
is that we have these callbacks.

349
00:15:10.976 --> 00:15:12.450
Before action, we’re gonna set posts.

350
00:15:12.450 --> 00:15:15.510
So before all the actions, we’re going to reflect

351
00:15:15.510 --> 00:15:17.880
the fact that this is a nested resource.

352
00:15:17.880 --> 00:15:21.840
The comments is something that belongs to a post,

353
00:15:21.840 --> 00:15:25.530
and we will pull out the post ID from the params,

354
00:15:25.530 --> 00:15:28.350
that’s what’s being parsed in as part of the URL,

355
00:15:28.350 --> 00:15:30.000
and we will fetch that post,

356
00:15:30.000 --> 00:15:32.490
and now we will create the comments

357
00:15:32.490 --> 00:15:36.000
associated with that post based on the parameters

358
00:15:36.000 --> 00:15:38.700
that are expected as comment content.

359
00:15:38.700 --> 00:15:40.710
And then after it’s created,

360
00:15:40.710 --> 00:15:43.440
we will redirect back to the post!

361
00:15:43.440 --> 00:15:44.273
So,

362
00:15:45.150 --> 00:15:47.940
let’s actually also (chuckling) create

363
00:15:47.940 --> 00:15:50.730
the other direction of this association.

364
00:15:50.730 --> 00:15:53.070
You saw a comment belongs to a post,

365
00:15:53.070 --> 00:15:57.450
but then we’re also gonna make the post has many comments.

366
00:15:57.450 --> 00:15:59.820
Now, we have a bidirectional association

367
00:15:59.820 --> 00:16:02.070
that we can work with in both ways.

368
00:16:02.070 --> 00:16:05.610
Now, we’re also gonna add a number of partials here.

369
00:16:05.610 --> 00:16:07.470
This is the templating system,

370
00:16:07.470 --> 00:16:10.140
basically, a sub-routine that you can refer to.

371
00:16:10.140 --> 00:16:11.220
There’s gonna be three of them.

372
00:16:11.220 --> 00:16:12.450
There’s gonna be the comments

373
00:16:12.450 --> 00:16:14.430
that includes the entire comment section.

374
00:16:14.430 --> 00:16:15.930
We’re gonna reference that

375
00:16:15.930 --> 00:16:18.420
in our post show in just a second.

376
00:16:18.420 --> 00:16:20.350
And within that, we’re gonna refer to

377
00:16:21.210 --> 00:16:23.430
another partial for an individual comment,

378
00:16:23.430 --> 00:16:26.430
and another partial again for the new setup.

379
00:16:26.430 --> 00:16:28.170
So, let’s paste some of that in here.

380
00:16:28.170 --> 00:16:31.246
You can see this is for the entire collection,

381
00:16:31.246 --> 00:16:33.134
it just has an H2 for the comments,

382
00:16:33.134 --> 00:16:34.380
and we render the post comments.

383
00:16:34.380 --> 00:16:37.140
This again uses Rails’ convention

384
00:16:37.140 --> 00:16:38.880
over configuration approach.

385
00:16:38.880 --> 00:16:42.630
It’ll automatically know that the comment model

386
00:16:42.630 --> 00:16:46.650
should map to view slash comment slash comment,

387
00:16:46.650 --> 00:16:49.350
so it can look up the right partial file to use.

388
00:16:49.350 --> 00:16:51.810
And then below that, we have the form

389
00:16:51.810 --> 00:16:55.200
that we’re referencing with the comments new.

390
00:16:55.200 --> 00:16:58.650
So, let’s hop in and paste in the individual comment.

391
00:16:58.650 --> 00:17:02.820
As you can see here, we just give it a div,

392
00:17:02.820 --> 00:17:05.853
that has a dom ID so that we can reference it.

393
00:17:07.187 --> 00:17:08.020
We are pacing in the comment,

394
00:17:08.020 --> 00:17:09.780
and we’re using that same time tag as we were using

395
00:17:09.780 --> 00:17:13.650
with the post, but this time, we are going to use time ago,

396
00:17:13.650 --> 00:17:15.930
so we get that nice two minutes ago

397
00:17:15.930 --> 00:17:17.340
on when something went posted

398
00:17:17.340 --> 00:17:21.123
rather than a local time spelled out with AMPM set up.

399
00:17:21.960 --> 00:17:25.170
And then finally, let’s paste in the form

400
00:17:25.170 --> 00:17:27.022
that we’re gonna use.

401
00:17:27.022 --> 00:17:28.890
That form is going off a model,

402
00:17:28.890 --> 00:17:31.620
the new comment, but it’s nested underneath the post,

403
00:17:31.620 --> 00:17:33.840
is that we automatically can deduce

404
00:17:33.840 --> 00:17:37.230
which URL that we should post this new form to.

405
00:17:37.230 --> 00:17:39.750
And your comment is just gonna be a text area for content.

406
00:17:39.750 --> 00:17:42.750
We could have made this a rich text field as well,

407
00:17:42.750 --> 00:17:46.740
but let’s keep things simple and just keep it in plain text!

408
00:17:46.740 --> 00:17:50.310
Now that we have that up, we can hop in

409
00:17:50.310 --> 00:17:54.330
and hook it all up into the show action for the posts!

410
00:17:54.330 --> 00:17:56.520
That’s gonna reference that common slot comments,

411
00:17:56.520 --> 00:17:58.970
that includes both the comments and the new form!

412
00:17:59.910 --> 00:18:02.790
Alright, let’s save that and hop back into our browser.

413
00:18:02.790 --> 00:18:04.590
Oop! I made a mistake here!

414
00:18:04.590 --> 00:18:06.480
When we generated the resource,

415
00:18:06.480 --> 00:18:09.180
it added a route for the new comments,

416
00:18:09.180 --> 00:18:12.990
but that route was not nested by default.

417
00:18:12.990 --> 00:18:16.200
We actually need to go into our routes.rb,

418
00:18:16.200 --> 00:18:17.160
and then see here,

419
00:18:17.160 --> 00:18:20.130
that resource we added needs to be nested.

420
00:18:20.130 --> 00:18:23.640
When it is nested, we get the fact

421
00:18:23.640 --> 00:18:27.210
that it’s gonna be slash post slash one slash comments,

422
00:18:27.210 --> 00:18:30.210
and we have the association is set up nicely.

423
00:18:30.210 --> 00:18:31.530
Now, let’s reload!

424
00:18:31.530 --> 00:18:33.810
Now, it works, we have our comments field underneath,

425
00:18:33.810 --> 00:18:35.220
we can add the first comment.

426
00:18:35.220 --> 00:18:36.870
And as you can see here,

427
00:18:36.870 --> 00:18:39.030
this is my first comment a second ago

428
00:18:39.030 --> 00:18:41.943
that was the local time doing its time ago conversion.

429
00:18:43.380 --> 00:18:46.740
Now, let’s set things up to be dynamic,

430
00:18:46.740 --> 00:18:49.500
such that when we add a new comment

431
00:18:49.500 --> 00:18:53.820
to one of these, it’s going to update the other as well.

432
00:18:53.820 --> 00:18:58.820
This is how we use web sockets in Rails using action cable,

433
00:18:59.430 --> 00:19:02.490
one of the frameworks that we have to create updates

434
00:19:02.490 --> 00:19:05.040
that are distributed automatically

435
00:19:05.040 --> 00:19:07.530
without folks having to reload their browser.

436
00:19:07.530 --> 00:19:10.920
So if we scroll down to the bottom here, we are ready.

437
00:19:10.920 --> 00:19:12.630
The first thing we’re gonna do, we’re gonna add

438
00:19:12.630 --> 00:19:15.090
a turbo stream from post

439
00:19:15.090 --> 00:19:19.530
to the show files to the show template.

440
00:19:19.530 --> 00:19:21.780
That’s gonna set up the web socket connection

441
00:19:21.780 --> 00:19:24.750
and subscribe us to a channel named after

442
00:19:24.750 --> 00:19:27.900
that particular post that’s pasted in.

443
00:19:27.900 --> 00:19:30.060
And if we hop into our comment,

444
00:19:30.060 --> 00:19:32.500
we can set up a broadcast_to

445
00:19:33.600 --> 00:19:35.070
for that post.

446
00:19:35.070 --> 00:19:37.860
The broadcast to will broadcast all updates

447
00:19:37.860 --> 00:19:40.410
made to that comment, whether a new comment is updated

448
00:19:40.410 --> 00:19:43.800
or an existing comment is changed in some way

449
00:19:43.800 --> 00:19:44.910
or even one deleted,

450
00:19:44.910 --> 00:19:47.910
and send it back out to a channel

451
00:19:47.910 --> 00:19:51.300
on action cable named after the post association

452
00:19:51.300 --> 00:19:53.250
that this comment belongs to!

453
00:19:53.250 --> 00:19:54.840
And that is basically it.

454
00:19:54.840 --> 00:19:56.400
Now if I go over here

455
00:19:56.400 --> 00:19:59.070
and I add a comment to one of these,

456
00:19:59.070 --> 00:20:02.160
you see the comment was added on the left immediately

457
00:20:02.160 --> 00:20:02.993
at the same time.

458
00:20:02.993 --> 00:20:05.970
That’s all web sockets automatically happening

459
00:20:05.970 --> 00:20:07.653
through action cable.

460
00:20:08.490 --> 00:20:10.940
And we can do it of course the other way as well.

461
00:20:12.128 --> 00:20:13.050
Alright, that is very neat.

462
00:20:13.050 --> 00:20:15.903
Now, let’s go to production!

463
00:20:16.839 --> 00:20:17.672
Because of course, you’re not just here

464
00:20:17.672 --> 00:20:20.940
to create a Hello World app that runs on your own machine,

465
00:20:20.940 --> 00:20:23.460
you want to get this out into the world!

466
00:20:23.460 --> 00:20:27.660
And Rails8 and forward ships with Kamal,

467
00:20:27.660 --> 00:20:32.040
a simple tool for deploying your web application anywhere.

468
00:20:32.040 --> 00:20:34.080
And there’s a default configuration file

469
00:20:34.080 --> 00:20:37.050
in config/deploy.yml that we can use,

470
00:20:37.050 --> 00:20:38.790
it’s prefilled a little bit,

471
00:20:38.790 --> 00:20:40.980
it has the service name of the name of reaction,

472
00:20:40.980 --> 00:20:44.400
but we need to rename, for example, your user,

473
00:20:44.400 --> 00:20:46.080
the name of the image to go

474
00:20:46.080 --> 00:20:49.890
to my name of where I store this on Docker Hub.

475
00:20:49.890 --> 00:20:52.020
You can see we changed that down in the registry as well

476
00:20:52.020 --> 00:20:53.670
and the name of the container image.

477
00:20:53.670 --> 00:20:57.000
Now, I’m gonna deploy this on my own little hoppy server.

478
00:20:57.000 --> 00:20:59.580
And that hoppy server is currently wiped.

479
00:20:59.580 --> 00:21:04.380
It is completely clean, and Ubuntu 2404

480
00:21:04.380 --> 00:21:06.810
setup that has nothing on it already,

481
00:21:06.810 --> 00:21:08.340
this is part of the magic of Kamal,

482
00:21:08.340 --> 00:21:12.450
you can spin up a new VM anywhere in the cloud

483
00:21:12.450 --> 00:21:15.570
or use your own hardware and point Kamal straight to it,

484
00:21:15.570 --> 00:21:17.940
and you’ll be going in no time!

485
00:21:17.940 --> 00:21:19.410
So, this server exists

486
00:21:19.410 --> 00:21:22.950
on this address, demo@exitsoftware.io

487
00:21:22.950 --> 00:21:27.120
And I will then fill out the host as a C name

488
00:21:27.120 --> 00:21:28.350
to that machine.

489
00:21:28.350 --> 00:21:29.850
But we’re using Alpha here,

490
00:21:29.850 --> 00:21:33.240
if I had deployed another application called Bravo

491
00:21:33.240 --> 00:21:35.610
to the same server, Kamal would set it up,

492
00:21:35.610 --> 00:21:37.500
so it’s like I host two applications

493
00:21:37.500 --> 00:21:40.113
or any number of applications on that same server!

494
00:21:41.310 --> 00:21:44.430
Now, we will also need to have a look at the secrets here,

495
00:21:44.430 --> 00:21:46.650
that is in dockyml/secrets,

496
00:21:46.650 --> 00:21:48.990
because the register that I’m using,

497
00:21:48.990 --> 00:21:52.020
that is Docker Hub, needs of course a password,

498
00:21:52.020 --> 00:21:54.030
it is using my username but also needs a password.

499
00:21:54.030 --> 00:21:55.050
And you can pull that password

500
00:21:55.050 --> 00:21:56.070
from a bunch of different places,

501
00:21:56.070 --> 00:21:59.370
you can pull it from a credential store like one password,

502
00:21:59.370 --> 00:22:02.070
you can pull it straight out of GitHub command,

503
00:22:02.070 --> 00:22:03.870
as you can see here with the GitHub token above,

504
00:22:03.870 --> 00:22:06.180
or you can pull things out of ENV.

505
00:22:06.180 --> 00:22:09.450
I’m pulling it out of ENV with my Kamal registry password

506
00:22:09.450 --> 00:22:12.090
that I’ve already set up on my personal bash.

507
00:22:12.090 --> 00:22:13.830
And then, the Rails master key

508
00:22:13.830 --> 00:22:16.170
that does the decoding of any credentials

509
00:22:16.170 --> 00:22:17.670
we’ve set for Rails,

510
00:22:17.670 --> 00:22:21.330
it’s just using a cat straight out of config master key.

511
00:22:21.330 --> 00:22:22.680
You’ll need to change that

512
00:22:22.680 --> 00:22:24.180
if you’re working with other people of course,

513
00:22:24.180 --> 00:22:25.013
because you don’t wanna check

514
00:22:25.013 --> 00:22:28.500
that master key into your Git repository,

515
00:22:28.500 --> 00:22:30.660
you’re gonna wanna pull that out of one password

516
00:22:30.660 --> 00:22:31.890
when you go for real.

517
00:22:31.890 --> 00:22:34.170
But this is all we basically need,

518
00:22:34.170 --> 00:22:38.280
we are now ready to check in the entire project into Git!

519
00:22:38.280 --> 00:22:40.770
Kamal uses Git for keeping track of versions,

520
00:22:40.770 --> 00:22:43.020
and we can now run Kamal setup!

521
00:22:43.020 --> 00:22:45.360
And that’ll connect to that remote server,

522
00:22:45.360 --> 00:22:47.310
and it’ll install Docker if it’s missing,

523
00:22:47.310 --> 00:22:49.350
it’ll build the Docker file

524
00:22:49.350 --> 00:22:51.390
or the Docker container off the Docker file

525
00:22:51.390 --> 00:22:53.310
that Rails ship with by default,

526
00:22:53.310 --> 00:22:55.230
there’s nothing you need to set up there.

527
00:22:55.230 --> 00:22:57.930
And it will deploy it, push it out,

528
00:22:57.930 --> 00:23:01.110
do it in a red green deployment

529
00:23:01.110 --> 00:23:03.600
or blue green deployment such that there is no gap

530
00:23:03.600 --> 00:23:05.850
in that deployment as you set things up.

531
00:23:05.850 --> 00:23:08.610
And as you can see here, I sped things up a little bit,

532
00:23:08.610 --> 00:23:11.310
but it was about 80 seconds on my Linux machine

533
00:23:11.310 --> 00:23:13.470
from a cold boot to do that.

534
00:23:13.470 --> 00:23:17.880
Now, we can hop back in here and go to alphaexitsoftware.io

535
00:23:17.880 --> 00:23:19.080
and see, whoops!

536
00:23:19.080 --> 00:23:20.793
There was a 404 here!

537
00:23:21.660 --> 00:23:24.270
That’s because if we go back to our route (chuckling) file,

538
00:23:24.270 --> 00:23:26.250
I have not defined route!

539
00:23:26.250 --> 00:23:27.870
And in production, you’re not gonna get

540
00:23:27.870 --> 00:23:30.660
that screen we saw with the Rails version

541
00:23:30.660 --> 00:23:32.940
and the Ruby version, that is only for development.

542
00:23:32.940 --> 00:23:34.050
So in production, you actually need

543
00:23:34.050 --> 00:23:35.550
to manually specify the route.

544
00:23:35.550 --> 00:23:38.160
So, we can go down here, and uncomment this,

545
00:23:38.160 --> 00:23:41.190
that sets what the route is going to be,

546
00:23:41.190 --> 00:23:43.890
we’re just gonna point it to post stud index.

547
00:23:43.890 --> 00:23:47.310
We can save that, check in that save change,

548
00:23:47.310 --> 00:23:49.350
and then we can run Kamal deploy again!

549
00:23:49.350 --> 00:23:51.510
And that’s basically the rhythm you will be in

550
00:23:51.510 --> 00:23:53.100
when you’re working on a Rails application

551
00:23:53.100 --> 00:23:54.900
and you’re deploying to production.

552
00:23:54.900 --> 00:23:57.960
If we go back here and reload not in production, boom!

553
00:23:57.960 --> 00:24:01.020
We are live in production with our whole setup,

554
00:24:01.020 --> 00:24:02.220
everything is working,

555
00:24:02.220 --> 00:24:06.270
we can upload the active storage files directly to it.

556
00:24:06.270 --> 00:24:07.383
By default,

557
00:24:08.520 --> 00:24:11.700
Kamal will use a docker volume to start these things up,

558
00:24:11.700 --> 00:24:12.930
but of course, you can configure that,

559
00:24:12.930 --> 00:24:17.400
and as I said, you can use S3 if you’d like as well!

560
00:24:17.400 --> 00:24:19.650
Common system is of course there as well,

561
00:24:19.650 --> 00:24:20.970
let’s add one of those comments,

562
00:24:20.970 --> 00:24:23.010
and now we have the entire application

563
00:24:23.010 --> 00:24:25.710
running in production, wasn’t that easy?

564
00:24:25.710 --> 00:24:28.950
Now, let’s add authentication to things as well.

565
00:24:28.950 --> 00:24:31.110
Authentication is one of the newer features in Rails,

566
00:24:31.110 --> 00:24:32.940
it basically gives you a default setup

567
00:24:32.940 --> 00:24:37.020
for tracking sessions, tracking passwords,

568
00:24:37.020 --> 00:24:39.840
and even doing password resets.

569
00:24:39.840 --> 00:24:43.110
What it does not give you is a signup flow,

570
00:24:43.110 --> 00:24:45.210
because that’s usually quite specific

571
00:24:45.210 --> 00:24:46.590
to a given application.

572
00:24:46.590 --> 00:24:49.620
So, we leave that as an exercise for the reader!

573
00:24:49.620 --> 00:24:52.740
But as you can see here, it adds a handful of migrations,

574
00:24:52.740 --> 00:24:56.100
one for users, and one for sessions!

575
00:24:56.100 --> 00:24:58.920
So, we’re gonna run Rails db:migrate again!

576
00:24:58.920 --> 00:25:01.110
And then, we are going to hop in here

577
00:25:01.110 --> 00:25:05.070
and have a look at what was actually generated.

578
00:25:05.070 --> 00:25:06.510
We have the sessions controller,

579
00:25:06.510 --> 00:25:08.070
that’s probably the most important.

580
00:25:08.070 --> 00:25:08.940
You can see here,

581
00:25:08.940 --> 00:25:13.500
it allows unauthenticated access to just new and create.

582
00:25:13.500 --> 00:25:15.150
Everything else by default

583
00:25:15.150 --> 00:25:17.430
will be behind the authentication lock!

584
00:25:17.430 --> 00:25:19.140
There’s also a rate limit to make sure

585
00:25:19.140 --> 00:25:23.910
that people don’t bombard you with attempts to log into

586
00:25:23.910 --> 00:25:25.320
users do not have access to.

587
00:25:25.320 --> 00:25:27.210
And then, we do the authentication

588
00:25:27.210 --> 00:25:29.610
using the email address and passwords,

589
00:25:29.610 --> 00:25:31.470
and start a new session from there.

590
00:25:31.470 --> 00:25:32.340
If we hop to the session,

591
00:25:32.340 --> 00:25:36.123
you can see it just is very basic Rails active record.

592
00:25:37.590 --> 00:25:39.220
Now, we’re gonna set up

593
00:25:40.110 --> 00:25:42.630
a default user that the systems should have

594
00:25:42.630 --> 00:25:45.030
as we’re working with it to allow us

595
00:25:45.030 --> 00:25:47.280
to log in since we don’t have that signup flow.

596
00:25:47.280 --> 00:25:49.020
So that’s just gonna be my email address

597
00:25:49.020 --> 00:25:50.820
and 1, 2, 3 password!

598
00:25:50.820 --> 00:25:53.160
We can hop back into our CLI

599
00:25:53.160 --> 00:25:56.670
and run Rails db:seed, that’s gonna run that file

600
00:25:56.670 --> 00:25:58.740
I just showed you and set things up.

601
00:25:58.740 --> 00:26:00.960
Now, if we hop back onto local host

602
00:26:00.960 --> 00:26:02.160
and we try to log in

603
00:26:02.160 --> 00:26:04.200
with first the wrong (chuckling) password,

604
00:26:04.200 --> 00:26:05.340
we’re actually gonna see something here

605
00:26:05.340 --> 00:26:08.460
when I added the authentication, it added another gem,

606
00:26:08.460 --> 00:26:09.480
it added bccrypt,

607
00:26:09.480 --> 00:26:12.720
that’s what we’re using to keep password secure,

608
00:26:12.720 --> 00:26:14.490
so we have to hop back in here

609
00:26:14.490 --> 00:26:17.160
and restart our development server!

610
00:26:17.160 --> 00:26:20.370
As we edit a new dependency, we can hop back in, reload,

611
00:26:20.370 --> 00:26:21.960
and now we’re good to go here.

612
00:26:21.960 --> 00:26:26.550
As you can see, I first tried to put in a wrong password,

613
00:26:26.550 --> 00:26:27.450
we’re gonna get this screen,

614
00:26:27.450 --> 00:26:29.520
try another email address or password.

615
00:26:29.520 --> 00:26:32.943
But if I log in with 1, 2, 3, boom, I’m in!

616
00:26:33.900 --> 00:26:37.110
Now, let’s add a way to sign out to

617
00:26:37.110 --> 00:26:38.410
the main

618
00:26:40.140 --> 00:26:41.130
layout here!

619
00:26:41.130 --> 00:26:43.860
We can add that with a button to sign out.

620
00:26:43.860 --> 00:26:45.270
It’s gonna hit the session path,

621
00:26:45.270 --> 00:26:48.990
and it’s gonna use a method of delete to delete that session

622
00:26:48.990 --> 00:26:51.030
if we’re authenticated, as you can see there.

623
00:26:51.030 --> 00:26:52.740
So, it’s not gonna show that button

624
00:26:52.740 --> 00:26:54.030
if we’re not already authenticated,

625
00:26:54.030 --> 00:26:58.200
which is good because this layout is also used for login.

626
00:26:58.200 --> 00:26:59.940
All right, let’s save that and hop back,

627
00:26:59.940 --> 00:27:02.880
and see a reload here, now, we have a a sign out button,

628
00:27:02.880 --> 00:27:06.540
and we can sign out, and that’s all us, it should be,

629
00:27:06.540 --> 00:27:07.980
let’s deploy this to production,

630
00:27:07.980 --> 00:27:10.890
we’re gonna just check this thing

631
00:27:10.890 --> 00:27:12.840
into Git, deploy it straight to production,

632
00:27:12.840 --> 00:27:16.440
go back to our alpha software, boom, dhh 123.

633
00:27:16.440 --> 00:27:18.900
Oops! That didn’t work! Why did that not work?

634
00:27:18.900 --> 00:27:21.870
Because we had not run our DB seeds!

635
00:27:21.870 --> 00:27:24.150
Now, I could run DB seeds in production,

636
00:27:24.150 --> 00:27:25.510
but lemme show you another way of doing it.

637
00:27:25.510 --> 00:27:26.880
Kamal also gives you a way

638
00:27:26.880 --> 00:27:29.910
to start a console on the server side

639
00:27:29.910 --> 00:27:32.610
that is just like the console I showed you earlier

640
00:27:32.610 --> 00:27:34.680
that ran in development!

641
00:27:34.680 --> 00:27:38.400
You can see here, it reminds you that you are in production.

642
00:27:38.400 --> 00:27:41.040
So, be careful when you (chuckling) create things

643
00:27:41.040 --> 00:27:43.710
that are gonna be created on the server side

644
00:27:43.710 --> 00:27:45.120
in your real database.

645
00:27:45.120 --> 00:27:46.230
The database, by the way?

646
00:27:46.230 --> 00:27:47.340
We haven’t talked much about that,

647
00:27:47.340 --> 00:27:49.320
and that is because we’re using SQLite.

648
00:27:49.320 --> 00:27:51.030
So, there is nothing to configure,

649
00:27:51.030 --> 00:27:55.230
there’s nothing to set up, SQLite is now a suitable database

650
00:27:55.230 --> 00:27:56.610
for production with Rails.

651
00:27:56.610 --> 00:27:58.920
We have tuned it with all the right pragmas

652
00:27:58.920 --> 00:28:00.240
and everything that you need

653
00:28:00.240 --> 00:28:03.030
to run SQLite well in production,

654
00:28:03.030 --> 00:28:05.490
you of course still need to set up a way to back that up,

655
00:28:05.490 --> 00:28:09.150
but everything else is preconfigured for you.

656
00:28:09.150 --> 00:28:11.970
So now, we’ve created that user in production

657
00:28:11.970 --> 00:28:14.850
using our Kamal console!

658
00:28:14.850 --> 00:28:18.720
I can log in with that user, 1, 2, 3, and boom,

659
00:28:18.720 --> 00:28:22.680
we are in with production authentication

660
00:28:22.680 --> 00:28:24.750
for the entire system.

661
00:28:24.750 --> 00:28:25.583
All right!

662
00:28:25.583 --> 00:28:26.520
One last thing,

663
00:28:26.520 --> 00:28:28.890
let me show you how to turn this web application

664
00:28:28.890 --> 00:28:31.380
into a PWA as well.

665
00:28:31.380 --> 00:28:34.020
We’re gonna create a link reference here

666
00:28:34.020 --> 00:28:37.950
to a manifest, that manifest just exists here

667
00:28:37.950 --> 00:28:39.570
as a comment that you can reference.

668
00:28:39.570 --> 00:28:43.740
We’re gonna turn the manifest on in our route file as well.

669
00:28:43.740 --> 00:28:45.750
There are basically two lines here,

670
00:28:45.750 --> 00:28:47.040
as you can see, there’s a manifest,

671
00:28:47.040 --> 00:28:50.610
and there’s a service worker that you can use for your PWA.

672
00:28:50.610 --> 00:28:53.820
We’ll turn those on and I’ll show you the manifest first.

673
00:28:53.820 --> 00:28:55.650
The manifest is just really basic.

674
00:28:55.650 --> 00:28:58.290
It’s gonna show the name of the PWA you’re gonna using!

675
00:28:58.290 --> 00:29:00.420
And it’s gonna refer to an icon,

676
00:29:00.420 --> 00:29:02.820
by default, we just have a nice red dot.

677
00:29:02.820 --> 00:29:04.440
But you should obviously replace that

678
00:29:04.440 --> 00:29:07.230
with your application icon.

679
00:29:07.230 --> 00:29:08.280
And if I hop in

680
00:29:08.280 --> 00:29:10.020
and have a look at the service worker,

681
00:29:10.020 --> 00:29:13.290
it is sort of already set up for doing web push,

682
00:29:13.290 --> 00:29:15.840
just as an example here, having some listeners,

683
00:29:15.840 --> 00:29:18.360
you can tweak that as you see fit.

684
00:29:18.360 --> 00:29:20.490
We’re not gonna change that for this little example,

685
00:29:20.490 --> 00:29:24.360
but now let’s check in that PWA files,

686
00:29:24.360 --> 00:29:26.850
and then let’s deploy to production one more time.

687
00:29:26.850 --> 00:29:28.050
And as you can see,

688
00:29:28.050 --> 00:29:30.810
look in the top right corner, when I reload it,

689
00:29:30.810 --> 00:29:34.890
we now have that little install icon in Chrome.

690
00:29:34.890 --> 00:29:37.590
And if I click that little install icon,

691
00:29:37.590 --> 00:29:39.690
I’m gonna get this prompt, and boom!

692
00:29:39.690 --> 00:29:41.620
I have a PWA

693
00:29:42.600 --> 00:29:46.050
running in production for my Rails application.

694
00:29:46.050 --> 00:29:50.160
So that is a very quick tour of Rails,

695
00:29:50.160 --> 00:29:53.610
this is a wonderful way of getting started,

696
00:29:53.610 --> 00:29:57.030
just to use those scaffold generators

697
00:29:57.030 --> 00:30:00.284
and the authentication generators to get something going,

698
00:30:00.284 --> 00:30:01.380
get a Hello world out there,

699
00:30:01.380 --> 00:30:03.420
start working on your application,

700
00:30:03.420 --> 00:30:05.040
and before you know it,

701
00:30:05.040 --> 00:30:07.080
you might just be taking your application

702
00:30:07.080 --> 00:30:09.813
all the way from Hello World to IPO.
