WEBVTT

1
00:00:00.120 --> 00:00:03.200
<v Speaker 1>Have you ever paused, you know, to really think about

2
00:00:03.200 --> 00:00:05.839
<v Speaker 1>what it takes to build the software as a service

3
00:00:06.639 --> 00:00:09.439
<v Speaker 1>a sauce app from the ground up.

4
00:00:09.560 --> 00:00:11.599
<v Speaker 2>Yeah, it's It's definitely more than just.

5
00:00:11.599 --> 00:00:14.800
<v Speaker 1>Coding, right exactly, It's about architecting something wow.

6
00:00:14.919 --> 00:00:18.160
<v Speaker 2>Robust, scalable, user friendly, the whole package.

7
00:00:18.519 --> 00:00:20.800
<v Speaker 1>So today we're doing a deep dive. We've got this

8
00:00:20.920 --> 00:00:25.519
<v Speaker 1>fantastic source, a really comprehensive guide on building sauce with

9
00:00:25.679 --> 00:00:27.359
<v Speaker 1>Ruby on Rails seven.

10
00:00:27.359 --> 00:00:30.839
<v Speaker 2>And our mission really is to cut through all the complexity.

11
00:00:31.120 --> 00:00:33.399
<v Speaker 2>We want to pull out those key nuggets of knowledge,

12
00:00:33.600 --> 00:00:36.359
<v Speaker 2>look at the modern tools, the best practices, you know,

13
00:00:36.399 --> 00:00:39.799
<v Speaker 2>what makes Rails such a powerhouse for this kind of development.

14
00:00:39.399 --> 00:00:41.359
<v Speaker 1>Right, and show you how to navigate it all without

15
00:00:41.399 --> 00:00:43.359
<v Speaker 1>feeling well completely overwhelmed.

16
00:00:43.399 --> 00:00:45.960
<v Speaker 2>Get ready for some aha moments, because we're going to

17
00:00:46.039 --> 00:00:48.799
<v Speaker 2>demystify what goes into a production ready sauce app.

18
00:00:49.039 --> 00:00:51.719
<v Speaker 1>Okay, let's start right at the beginning. Then laying the foundation.

19
00:00:52.039 --> 00:00:57.560
<v Speaker 1>Rails has this famous philosophy convention over configuration. For folks

20
00:00:57.560 --> 00:01:00.240
<v Speaker 1>listening who may be no development, what's the real like

21
00:01:00.359 --> 00:01:02.799
<v Speaker 1>strategic edge you get from that when you're kicking off a.

22
00:01:02.759 --> 00:01:07.280
<v Speaker 2>Sauce It's all about speed initial velocity. Rails is well,

23
00:01:07.319 --> 00:01:10.480
<v Speaker 2>it's opinionated about speed. It hands you this pre defined

24
00:01:10.599 --> 00:01:14.640
<v Speaker 2>logical structure right away. Your app canfig dB test folders,

25
00:01:14.840 --> 00:01:16.599
<v Speaker 2>so you get productive almost instantly.

26
00:01:16.680 --> 00:01:20.239
<v Speaker 1>Ah, so you're not stuck debating file structures for days exactly.

27
00:01:20.680 --> 00:01:23.879
<v Speaker 2>You run Rails new and you've basically got a working

28
00:01:23.959 --> 00:01:27.799
<v Speaker 2>app skeleton ready for a Hello World pretty much out

29
00:01:27.799 --> 00:01:30.560
<v Speaker 2>of the box. It lets you focus on your business problem,

30
00:01:30.640 --> 00:01:31.280
<v Speaker 2>not the framework.

31
00:01:31.319 --> 00:01:33.840
<v Speaker 1>Setup that makes sense moves a lot of that initial churn.

32
00:01:34.359 --> 00:01:36.519
<v Speaker 1>And when you are spinning up that new app, what

33
00:01:36.599 --> 00:01:39.280
<v Speaker 1>are some of those first big setup choices, the ones

34
00:01:39.319 --> 00:01:42.079
<v Speaker 1>that really mark the difference between a quick demo and

35
00:01:42.319 --> 00:01:43.480
<v Speaker 1>something you'd actually deploy.

36
00:01:43.640 --> 00:01:47.840
<v Speaker 2>Okay, first up database, This trips people up. Sometimes Rails

37
00:01:48.000 --> 00:01:50.840
<v Speaker 2>defaults to skoy three, which is fine, super simple for

38
00:01:50.879 --> 00:01:51.879
<v Speaker 2>getting started.

39
00:01:51.560 --> 00:01:52.359
<v Speaker 1>But not for production.

40
00:01:53.040 --> 00:01:56.599
<v Speaker 2>Generally, No, for real sauce, you'll almost certainly want Postgres School.

41
00:01:56.599 --> 00:02:00.959
<v Speaker 2>It's just more robust handles, concurrent users, better advanced features

42
00:02:00.959 --> 00:02:02.280
<v Speaker 2>like Jason in b stuff.

43
00:02:02.040 --> 00:02:04.280
<v Speaker 1>You'll need later, so you'd specify that right at the start.

44
00:02:04.519 --> 00:02:09.439
<v Speaker 1>YEP Rails New year app database postcrescool tells Rails what

45
00:02:09.479 --> 00:02:10.759
<v Speaker 1>you intend to use from day one.

46
00:02:10.840 --> 00:02:14.800
<v Speaker 2>Okay, database sorted. What about managing the code itself, especially

47
00:02:14.800 --> 00:02:15.479
<v Speaker 2>if you have a team.

48
00:02:15.719 --> 00:02:19.000
<v Speaker 1>Well, get is absolutely fundamental. That's probably obvious to most devs,

49
00:02:19.319 --> 00:02:23.680
<v Speaker 1>but for Sauce. Its role in smooth team workflows, feature branching,

50
00:02:23.800 --> 00:02:27.919
<v Speaker 1>quick rollbacks when things go wrong. It's crucial for maintaining speed.

51
00:02:27.639 --> 00:02:30.319
<v Speaker 2>Insanity, and you'd host that somewhere like GitHub right.

52
00:02:30.439 --> 00:02:34.800
<v Speaker 1>GitHub, bitbucket. Essential for collaboration and especially for keeping your

53
00:02:34.800 --> 00:02:35.400
<v Speaker 1>code private.

54
00:02:35.599 --> 00:02:38.439
<v Speaker 2>Got it? Now? Inside that new Reils app, there's the

55
00:02:38.520 --> 00:02:41.759
<v Speaker 2>gem file. What are the sort of must have gems

56
00:02:41.800 --> 00:02:43.879
<v Speaker 2>included right away? What problems are they solving?

57
00:02:44.080 --> 00:02:46.639
<v Speaker 1>The gem file is like your recipe. You'll see pg

58
00:02:46.919 --> 00:02:49.479
<v Speaker 1>in there if you chose postcres school. That's the connector.

59
00:02:49.919 --> 00:02:53.080
<v Speaker 1>Puma is your web server handles the actual requests. It's fast,

60
00:02:53.199 --> 00:02:56.080
<v Speaker 1>concurrent and a really important one now is import mafrails.

61
00:02:56.439 --> 00:02:57.280
<v Speaker 2>What's the deal with that?

62
00:02:57.319 --> 00:02:57.439
<v Speaker 1>One?

63
00:02:57.560 --> 00:02:58.360
<v Speaker 2>Sounds modern?

64
00:02:58.719 --> 00:03:01.879
<v Speaker 1>It is? It lets you use modern JavaScript yes modules

65
00:03:01.919 --> 00:03:04.840
<v Speaker 1>directly in the browser without needing a complex build step

66
00:03:04.879 --> 00:03:08.120
<v Speaker 1>like webpack or as build. It really simplifies front end

67
00:03:08.120 --> 00:03:12.240
<v Speaker 1>asset management. Big win for developer experience and styling. That's

68
00:03:12.280 --> 00:03:13.639
<v Speaker 1>gotten simpler too, hasn't it.

69
00:03:13.719 --> 00:03:16.680
<v Speaker 2>Oh yeah, tailwind CSS is basically built in now with

70
00:03:16.800 --> 00:03:21.000
<v Speaker 2>Rail seven. It's a utility first CSS framework makes styling

71
00:03:21.039 --> 00:03:24.560
<v Speaker 2>fast and consistent without writing tons of custom CSS. You

72
00:03:24.599 --> 00:03:26.280
<v Speaker 2>build styles writing your HTML.

73
00:03:26.439 --> 00:03:29.520
<v Speaker 1>Okay, so you've run Rails new, configured a few things.

74
00:03:29.800 --> 00:03:32.599
<v Speaker 1>The source really stresses how fast you get something working.

75
00:03:32.599 --> 00:03:33.400
<v Speaker 1>Can you walk us through that?

76
00:03:33.479 --> 00:03:36.120
<v Speaker 2>Yeah, it's pretty neat. You run Rails new, then Rail Server,

77
00:03:36.560 --> 00:03:39.960
<v Speaker 2>and boom you've got a default Rails welcome page in

78
00:03:40.000 --> 00:03:44.159
<v Speaker 2>your browser. Minutes tops just like that. Then the guide

79
00:03:44.240 --> 00:03:47.199
<v Speaker 2>usually shows you making a tiny change at a route,

80
00:03:47.280 --> 00:03:50.240
<v Speaker 2>a super simple controller action to display your own custom

81
00:03:50.280 --> 00:03:53.759
<v Speaker 2>Hello World. It just hammers home how quick that feedback

82
00:03:53.759 --> 00:03:56.439
<v Speaker 2>loop is with rails rapid iteration.

83
00:03:56.599 --> 00:03:59.800
<v Speaker 1>Okay, let's talk. Testing often feels like a chore, But

84
00:04:00.000 --> 00:04:02.759
<v Speaker 1>why is it so critical, especially for size right from

85
00:04:02.759 --> 00:04:04.000
<v Speaker 1>the get go right.

86
00:04:03.879 --> 00:04:07.560
<v Speaker 2>It's not just about finding bugs today, it's about building confidence.

87
00:04:07.599 --> 00:04:11.479
<v Speaker 2>It's a safety net so when you refactor later or

88
00:04:11.560 --> 00:04:15.120
<v Speaker 2>add new features, you can deploy without constantly worrying you

89
00:04:15.159 --> 00:04:18.519
<v Speaker 2>broke something else. It actually speeds up long term development

90
00:04:18.560 --> 00:04:21.519
<v Speaker 2>because you move faster when you're not afraid to change things.

91
00:04:21.720 --> 00:04:22.879
<v Speaker 1>That's a great way to put it in. There are

92
00:04:22.879 --> 00:04:24.279
<v Speaker 1>different kinds of tests.

93
00:04:24.000 --> 00:04:26.759
<v Speaker 2>Right, Absolutely, you've got your model tests or unit tests,

94
00:04:26.800 --> 00:04:29.480
<v Speaker 2>so they check small pieces in isolation, make sure a

95
00:04:29.519 --> 00:04:33.680
<v Speaker 2>specific calculation is right for example. Then view tests and

96
00:04:33.800 --> 00:04:35.800
<v Speaker 2>the big ones system tests.

97
00:04:36.000 --> 00:04:37.199
<v Speaker 1>What does system tests do?

98
00:04:37.439 --> 00:04:41.040
<v Speaker 2>They use tools like Capybara to actually simulate a user

99
00:04:41.079 --> 00:04:44.560
<v Speaker 2>interacting with your app in a browser, clicking buttons, filling forms,

100
00:04:44.639 --> 00:04:45.319
<v Speaker 2>the whole flow.

101
00:04:45.639 --> 00:04:47.959
<v Speaker 1>Ah, so they test the whole stack together exactly.

102
00:04:48.120 --> 00:04:50.680
<v Speaker 2>They're powerful, but they're also slow.

103
00:04:50.439 --> 00:04:51.959
<v Speaker 1>To run, okay, so there's a trade off.

104
00:04:52.040 --> 00:04:55.959
<v Speaker 2>Definitely, you use system tests for your most critical user paths,

105
00:04:55.959 --> 00:04:59.959
<v Speaker 2>sign up, core feature usage, for edge cases or specific

106
00:05:00.079 --> 00:05:03.480
<v Speaker 2>controller logic, you rely on faster controller or unit tests

107
00:05:03.480 --> 00:05:05.199
<v Speaker 2>to get quick feedback makes sense.

108
00:05:05.439 --> 00:05:08.399
<v Speaker 1>Any specific testing tools that are really indispensable here.

109
00:05:08.680 --> 00:05:11.920
<v Speaker 2>I definitely mentioned simple cough. It shows your test coverage

110
00:05:12.040 --> 00:05:14.920
<v Speaker 2>literally highlights which lines of code your tests are.

111
00:05:14.839 --> 00:05:17.680
<v Speaker 1>Hitting, so you know what's not being tested precisely.

112
00:05:18.000 --> 00:05:20.160
<v Speaker 2>And the other big one is VCR.

113
00:05:19.920 --> 00:05:22.360
<v Speaker 1>VCR like the old video takes hah.

114
00:05:22.439 --> 00:05:25.480
<v Speaker 2>Yeah, the name's a bit retro, but it records external

115
00:05:25.480 --> 00:05:28.839
<v Speaker 2>API calls like to stripe or get hub the first

116
00:05:28.879 --> 00:05:32.160
<v Speaker 2>time your test runs them. Then on subsequent runs, it

117
00:05:32.319 --> 00:05:34.319
<v Speaker 2>just plays back that recorded response.

118
00:05:34.639 --> 00:05:37.399
<v Speaker 1>Ah, so your tests don't actually hit the live API.

119
00:05:37.079 --> 00:05:40.480
<v Speaker 2>Every time exactly makes tests way faster, more reliable, and

120
00:05:40.480 --> 00:05:43.279
<v Speaker 2>you can even run them offline. Huge time saver, especially

121
00:05:43.279 --> 00:05:45.879
<v Speaker 2>for APIs that change or have right limits brilliant.

122
00:05:45.879 --> 00:05:49.240
<v Speaker 1>And to run all these tests automatically, that's continuous integration,

123
00:05:49.360 --> 00:05:49.879
<v Speaker 1>right yeap.

124
00:05:50.079 --> 00:05:53.959
<v Speaker 2>CI services think Circle Ci, Travis CI, Semaphore, GitHub actions.

125
00:05:54.160 --> 00:05:56.519
<v Speaker 2>They run your full test suite automatically. Every time you

126
00:05:56.560 --> 00:05:59.680
<v Speaker 2>push code, you get immediate feedback did your change break anything?

127
00:06:00.120 --> 00:06:02.920
<v Speaker 2>Crucial for team velocity and keeping the codebase healthy.

128
00:06:03.040 --> 00:06:06.279
<v Speaker 1>Okay, shifting gears a bit. Users can't have a songs

129
00:06:06.319 --> 00:06:08.839
<v Speaker 1>without them. How do you start setting up a solid

130
00:06:08.959 --> 00:06:10.079
<v Speaker 1>user system in rails?

131
00:06:10.399 --> 00:06:13.120
<v Speaker 2>Users are everything? Yeah, it starts with a user model.

132
00:06:13.120 --> 00:06:16.560
<v Speaker 2>You add attributes you need, name, time zone, maybe rules later.

133
00:06:17.079 --> 00:06:20.480
<v Speaker 2>A really important detail, often overlooked early on, is adding

134
00:06:20.519 --> 00:06:22.199
<v Speaker 2>a hasheet or UUID.

135
00:06:22.519 --> 00:06:23.480
<v Speaker 1>Why is that important?

136
00:06:23.680 --> 00:06:27.240
<v Speaker 2>It's mainly for security and cleaner URLs. Instead of seeing

137
00:06:27.399 --> 00:06:30.759
<v Speaker 2>users one users two in the URL, which someone could

138
00:06:30.759 --> 00:06:32.199
<v Speaker 2>guess or iterate.

139
00:06:31.959 --> 00:06:34.959
<v Speaker 1>Through trying to find other users data.

140
00:06:34.720 --> 00:06:37.759
<v Speaker 2>Right, a UID gives you something like user say three

141
00:06:37.839 --> 00:06:42.800
<v Speaker 2>B seven C it's nonsequential, unpredictable, much safer, and Rail's

142
00:06:42.839 --> 00:06:46.040
<v Speaker 2>database migrations handle adding these columns and changing your database

143
00:06:46.040 --> 00:06:48.240
<v Speaker 2>schema really smoothly. That's a core strength.

144
00:06:48.399 --> 00:06:52.199
<v Speaker 1>Okay, And for actually logging users in authentication is building

145
00:06:52.240 --> 00:06:54.240
<v Speaker 1>your own login system still a thing people do.

146
00:06:54.279 --> 00:06:57.600
<v Speaker 2>Please please don't. Rolling your own off is notoriously hard

147
00:06:57.600 --> 00:07:00.480
<v Speaker 2>to get right. Security is complex, So what's the standard approach?

148
00:07:00.720 --> 00:07:03.720
<v Speaker 2>Devise It's a gem, It's been around forever, it's battle tested.

149
00:07:04.000 --> 00:07:08.439
<v Speaker 2>It handles sessions, cookies, password resets, confirmations, the works, and

150
00:07:08.480 --> 00:07:11.199
<v Speaker 2>it gives you basic views you can customize using device,

151
00:07:11.279 --> 00:07:13.639
<v Speaker 2>saves you a massive amount of time and prevents countless

152
00:07:13.639 --> 00:07:14.480
<v Speaker 2>security headaches.

153
00:07:14.759 --> 00:07:18.160
<v Speaker 1>Good advice. So users can log in. Yeah, but then

154
00:07:18.199 --> 00:07:22.240
<v Speaker 1>you often need roles right, like admins versus regular users.

155
00:07:22.240 --> 00:07:23.360
<v Speaker 1>How's that handled right?

156
00:07:23.600 --> 00:07:26.399
<v Speaker 2>So first you need the basic flows sign in, sign out,

157
00:07:26.439 --> 00:07:29.000
<v Speaker 2>sign up, make sure you have clear feedback using rails

158
00:07:29.040 --> 00:07:32.879
<v Speaker 2>flash messages. User invites are also common, especially for team

159
00:07:32.920 --> 00:07:37.639
<v Speaker 2>based apps. For roles themselves, a gem called rollifies really popular.

160
00:07:37.639 --> 00:07:40.600
<v Speaker 2>It lets you associate roles you define them like dot

161
00:07:40.639 --> 00:07:42.959
<v Speaker 2>admin or dot member with your users.

162
00:07:42.959 --> 00:07:44.399
<v Speaker 1>Okay, so user has a role.

163
00:07:44.360 --> 00:07:46.800
<v Speaker 2>Yep, and then you need to connect that role to

164
00:07:46.879 --> 00:07:47.800
<v Speaker 2>what they're allowed to do.

165
00:07:47.839 --> 00:07:50.040
<v Speaker 1>That's authorization and how do you manage that? Is there

166
00:07:50.160 --> 00:07:50.879
<v Speaker 1>standard way?

167
00:07:51.079 --> 00:07:54.199
<v Speaker 2>Can can can is the go to gem here. It's

168
00:07:54.279 --> 00:07:57.839
<v Speaker 2>incredibly powerful because it lets you define all your authorization

169
00:07:58.000 --> 00:08:01.759
<v Speaker 2>roles in one central place, usually a file called ability dot.

170
00:08:01.639 --> 00:08:03.560
<v Speaker 1>RB one file for all permissions.

171
00:08:03.720 --> 00:08:05.800
<v Speaker 2>Yeah, pretty much. It keeps things really organized.

172
00:08:05.879 --> 00:08:07.800
<v Speaker 1>How fine grained can you get with those rules?

173
00:08:08.120 --> 00:08:11.800
<v Speaker 2>Very you define can or cannot rules, you combine actions

174
00:08:11.920 --> 00:08:14.959
<v Speaker 2>like read dot create, dot update, dot manage, which is

175
00:08:15.000 --> 00:08:17.839
<v Speaker 2>like a wild card with specific models. So you could

176
00:08:17.839 --> 00:08:20.839
<v Speaker 2>say a user can manage their own projects, but they

177
00:08:20.879 --> 00:08:22.920
<v Speaker 2>can read projects belonging to their team.

178
00:08:23.040 --> 00:08:25.959
<v Speaker 1>Ah okay, very specific exactly.

179
00:08:26.399 --> 00:08:28.519
<v Speaker 2>And if someone tries to do something they're not allowed

180
00:08:28.560 --> 00:08:31.600
<v Speaker 2>to can can can helps you catch that and redirect them,

181
00:08:31.959 --> 00:08:34.519
<v Speaker 2>maybe show an access denied message.

182
00:08:34.759 --> 00:08:37.480
<v Speaker 1>And obviously you need to test all of this thoroughly.

183
00:08:37.639 --> 00:08:40.720
<v Speaker 1>The log ins, the roles, the permissions absolutely critical.

184
00:08:40.919 --> 00:08:43.480
<v Speaker 2>You'd use a mix of tests here. Controller specs are

185
00:08:43.519 --> 00:08:46.759
<v Speaker 2>good for checking the logic does this role get redirected correctly?

186
00:08:47.320 --> 00:08:50.639
<v Speaker 2>And system specs are essential for testing the full user experience.

187
00:08:50.679 --> 00:08:53.320
<v Speaker 2>Can a user actually sign up, log in and access

188
00:08:53.320 --> 00:08:54.840
<v Speaker 2>the things they should be able to access.

189
00:08:54.960 --> 00:08:58.080
<v Speaker 1>Right makes sense. Okay, let's dive into the core business logic,

190
00:08:58.320 --> 00:09:01.480
<v Speaker 1>the real meat of the application. The source mentioned scaffold

191
00:09:01.559 --> 00:09:05.080
<v Speaker 1>quite a bit. Rails G scaffold. What is that and

192
00:09:05.120 --> 00:09:08.519
<v Speaker 1>why is it highlighted? Ugh scaffolding. This is where rails

193
00:09:08.559 --> 00:09:11.799
<v Speaker 1>can feel like magic sometimes, especially when you're starting. It's

194
00:09:11.799 --> 00:09:15.039
<v Speaker 1>a generator command. You run rails G scaffold stand up,

195
00:09:15.080 --> 00:09:19.159
<v Speaker 1>for example, and it instantly creates the model, the database, migration,

196
00:09:19.600 --> 00:09:25.519
<v Speaker 1>the controller with all the basic actions index, show, new, create, edit, update,

197
00:09:25.559 --> 00:09:29.080
<v Speaker 1>destroy the views for each action and basic tests.

198
00:09:29.240 --> 00:09:32.360
<v Speaker 2>Wow. Okay, the whole cru setup in one command.

199
00:09:32.159 --> 00:09:36.440
<v Speaker 1>Exactly, crud, create, read, update, delete. It gives you a

200
00:09:36.440 --> 00:09:39.879
<v Speaker 1>fully working interface for managing that stand up object in minutes.

201
00:09:40.399 --> 00:09:42.440
<v Speaker 1>Huge shortcut for getting basic features up.

202
00:09:42.480 --> 00:09:44.320
<v Speaker 2>But it's not the final code, right. You don't just

203
00:09:44.360 --> 00:09:45.919
<v Speaker 2>deploy the scaffold output.

204
00:09:45.799 --> 00:09:47.799
<v Speaker 1>Oh definitely not. Think of it as a starting point,

205
00:09:47.879 --> 00:09:50.759
<v Speaker 1>a really, really good starting point. You almost always need

206
00:09:50.759 --> 00:09:53.840
<v Speaker 1>to customize the generator code, change the forms, tweak the

207
00:09:53.840 --> 00:09:56.759
<v Speaker 1>controller logic, adjust the views. But it saves you from

208
00:09:56.799 --> 00:10:00.200
<v Speaker 1>writing all that boilerplate yourself. It's you maybe eighty percent there.

209
00:10:00.080 --> 00:10:03.720
<v Speaker 2>Or fast okay, so you scaffold then customize using our

210
00:10:03.720 --> 00:10:06.480
<v Speaker 2>stand up tracker example. What are some key business models

211
00:10:06.519 --> 00:10:08.840
<v Speaker 2>or patterns you'd build on top of that. Well, one

212
00:10:08.879 --> 00:10:11.919
<v Speaker 2>neat concept the source mentions is tracking the current date

213
00:10:12.519 --> 00:10:15.960
<v Speaker 2>using RAILS sessions and maybe a dedicated controller. The app

214
00:10:16.000 --> 00:10:18.559
<v Speaker 2>can remember which date the user is looking at.

215
00:10:18.799 --> 00:10:21.720
<v Speaker 1>So if I navigate away and come back, I'm still

216
00:10:21.720 --> 00:10:23.840
<v Speaker 1>looking at yesterday's stand ups exactly.

217
00:10:23.879 --> 00:10:27.759
<v Speaker 2>It provides context across the application, very useful for something

218
00:10:27.799 --> 00:10:29.279
<v Speaker 2>like a daily stand up tracker.

219
00:10:29.399 --> 00:10:32.480
<v Speaker 1>And what about relationships like users belonging to teams?

220
00:10:32.600 --> 00:10:35.919
<v Speaker 2>That's a classic RAILS pattern has many through You'd have

221
00:10:36.080 --> 00:10:39.200
<v Speaker 2>user model, a team model, and a team membership model.

222
00:10:38.919 --> 00:10:41.320
<v Speaker 1>In between that links them the join table.

223
00:10:41.200 --> 00:10:43.759
<v Speaker 2>Right, it makes it easy to ask what teams does

224
00:10:43.799 --> 00:10:47.080
<v Speaker 2>this user belong to user dot teams? Or who are

225
00:10:47.080 --> 00:10:50.639
<v Speaker 2>the members of this team team dot users? Very clean.

226
00:10:51.120 --> 00:10:53.919
<v Speaker 2>You could also use similar patterns for things like static lookups,

227
00:10:53.960 --> 00:10:56.080
<v Speaker 2>maybe using enom for days of the week or something.

228
00:10:56.240 --> 00:10:59.440
<v Speaker 1>Got it and I saw something interesting about tasks single

229
00:10:59.480 --> 00:11:02.639
<v Speaker 1>table in Harrodan's STI. What's that about?

230
00:11:02.840 --> 00:11:07.159
<v Speaker 2>Ah STI? It's a clever database pattern. Imagine in our

231
00:11:07.240 --> 00:11:09.879
<v Speaker 2>stand up app you have different types of tasks, things

232
00:11:09.919 --> 00:11:13.080
<v Speaker 2>you did, things you plan, Toto, and maybe blockers.

233
00:11:13.159 --> 00:11:14.519
<v Speaker 1>Okay, three distinct types.

234
00:11:14.759 --> 00:11:18.960
<v Speaker 2>Instead of creating three separate database tables DIDs Toto's blockers,

235
00:11:19.000 --> 00:11:22.120
<v Speaker 2>you use one tasks table and you add a special

236
00:11:22.120 --> 00:11:24.960
<v Speaker 2>type column to that table. Rails uses this column to

237
00:11:25.000 --> 00:11:28.799
<v Speaker 2>know which class each row represents, did Toto or blocker?

238
00:11:29.120 --> 00:11:30.840
<v Speaker 1>So they all live in one table, but your code

239
00:11:30.840 --> 00:11:32.720
<v Speaker 1>treats them as different classes exactly.

240
00:11:33.240 --> 00:11:35.320
<v Speaker 2>It's great for models that share a lot of common

241
00:11:35.360 --> 00:11:39.120
<v Speaker 2>attributes but have some distinct behaviors. Keeps your schema simpler.

242
00:11:39.879 --> 00:11:43.600
<v Speaker 1>Very cool now, making all this feel dynamic and interactive.

243
00:11:43.840 --> 00:11:46.600
<v Speaker 1>Hot Wire seems to be a big deal in Rails seven.

244
00:11:46.759 --> 00:11:47.240
<v Speaker 1>What is it?

245
00:11:47.720 --> 00:11:51.000
<v Speaker 2>Hot Wire is huge. It's basically a collection of technologies

246
00:11:51.039 --> 00:11:54.919
<v Speaker 2>Turbo stimulus, JS and strata for mobile designed to give

247
00:11:54.919 --> 00:11:57.159
<v Speaker 2>you that fast interactive SPA.

248
00:11:56.960 --> 00:12:00.279
<v Speaker 1>Like field SBA being single page application. Right.

249
00:12:00.600 --> 00:12:03.120
<v Speaker 2>But here's the kicker. You get that feel without writing

250
00:12:03.159 --> 00:12:06.600
<v Speaker 2>much custom JavaScript. That's the revolutionary part for many Rails devs.

251
00:12:06.600 --> 00:12:09.879
<v Speaker 1>How does that work? No JavaScript framework needed largely. No.

252
00:12:10.240 --> 00:12:13.279
<v Speaker 2>Hot wire sends HTML over the wire, not Jason. It

253
00:12:13.399 --> 00:12:16.480
<v Speaker 2>leverages the server to render HTML fragments and then uses

254
00:12:16.519 --> 00:12:18.039
<v Speaker 2>clever techniques to update the page.

255
00:12:18.120 --> 00:12:19.759
<v Speaker 1>Okay, break that down. What does turbo do.

256
00:12:19.960 --> 00:12:23.919
<v Speaker 2>Turbo has a few parts. Turbo drive intercepts, link clicks

257
00:12:23.919 --> 00:12:27.480
<v Speaker 2>and form submissions. Instead of a full page reload, it

258
00:12:27.559 --> 00:12:30.639
<v Speaker 2>fetches the new page in the background and cleverly swaps

259
00:12:30.639 --> 00:12:34.600
<v Speaker 2>out just the body or specific parts. Makes navigation feel instant.

260
00:12:34.799 --> 00:12:38.840
<v Speaker 1>Okay, faster page changes. What about real time updates like

261
00:12:38.919 --> 00:12:41.600
<v Speaker 1>seeing a teammate stand up appear without refreshing.

262
00:12:41.720 --> 00:12:45.080
<v Speaker 2>That's turbo streams. It uses web sockets to push small

263
00:12:45.240 --> 00:12:48.440
<v Speaker 2>HTML changes directly from the server to all connected clients.

264
00:12:48.720 --> 00:12:51.360
<v Speaker 2>Someone saves the stand up, a turbostream message goes out

265
00:12:51.399 --> 00:12:53.720
<v Speaker 2>and bam, it appears on everyone else's screen.

266
00:12:53.879 --> 00:12:54.799
<v Speaker 1>And Turbo frames.

267
00:12:54.879 --> 00:12:57.960
<v Speaker 2>Turbo frames let you designate specific sections of your page.

268
00:12:58.120 --> 00:13:02.200
<v Speaker 2>Turbo frame tags as independent updatable Click a link inside

269
00:13:02.200 --> 00:13:05.679
<v Speaker 2>a frame and only that frame's content gets replaced. Great

270
00:13:05.759 --> 00:13:07.759
<v Speaker 2>for things like editing a single item in a list

271
00:13:07.799 --> 00:13:09.120
<v Speaker 2>without reloading the whole list.

272
00:13:09.200 --> 00:13:11.039
<v Speaker 1>And you can still use JavaScript if you need to

273
00:13:11.440 --> 00:13:12.720
<v Speaker 1>for things like date pickers.

274
00:13:13.000 --> 00:13:16.639
<v Speaker 2>Absolutely, that's where stimulus js comes in. It's a modest

275
00:13:16.679 --> 00:13:21.159
<v Speaker 2>JavaScript framework that connects JavaScript controllers to HTML elements using

276
00:13:21.240 --> 00:13:25.279
<v Speaker 2>data attributes the source shows integrating a JavaScript date picker

277
00:13:25.360 --> 00:13:29.279
<v Speaker 2>like flat picker stimulus handles the interaction and then maybe

278
00:13:29.320 --> 00:13:32.240
<v Speaker 2>triggers a turbo request to update the page content based

279
00:13:32.240 --> 00:13:35.000
<v Speaker 2>on the selected date. They work together beautifully.

280
00:13:35.440 --> 00:13:37.639
<v Speaker 1>So putting it all together, the stand up app can

281
00:13:37.679 --> 00:13:39.799
<v Speaker 1>show stand ups based on different filters.

282
00:13:39.919 --> 00:13:42.240
<v Speaker 2>Yeah, you can easily build views that show your stand

283
00:13:42.320 --> 00:13:45.159
<v Speaker 2>ups or all stand ups for a specific team, or

284
00:13:45.200 --> 00:13:49.279
<v Speaker 2>all stand ups from a particular user on their profile page. Rails,

285
00:13:49.360 --> 00:13:52.240
<v Speaker 2>routing and controllers handle the data fetching, and hot wire

286
00:13:52.279 --> 00:13:54.360
<v Speaker 2>makes the presentation dynamic and fast.

287
00:13:54.799 --> 00:13:57.840
<v Speaker 1>Okay, moving beyond the core UI in models, let's talk

288
00:13:57.960 --> 00:14:01.919
<v Speaker 1>robustness and integrations objects. You call them the secret sauce.

289
00:14:02.039 --> 00:14:03.279
<v Speaker 1>Why are they so important?

290
00:14:03.639 --> 00:14:05.679
<v Speaker 2>AI? Yeah, secret sauce might be a bit much, but

291
00:14:05.679 --> 00:14:07.960
<v Speaker 2>they are really helpful for keeping your code clean as

292
00:14:07.960 --> 00:14:10.960
<v Speaker 2>the app grows. The core idea is to prevent fat

293
00:14:11.000 --> 00:14:14.279
<v Speaker 2>controllers or fat models where you cram way too much

294
00:14:14.320 --> 00:14:16.879
<v Speaker 2>business logic into those default rails classes.

295
00:14:16.960 --> 00:14:19.039
<v Speaker 1>So you pull logic out exactly.

296
00:14:19.279 --> 00:14:23.159
<v Speaker 2>You create dedicated Ruby classes service objects that handle one

297
00:14:23.279 --> 00:14:27.960
<v Speaker 2>specific business process or action like create user process payment.

298
00:14:28.080 --> 00:14:30.840
<v Speaker 2>Since stand up reminder, it makes the code much easier

299
00:14:30.840 --> 00:14:34.559
<v Speaker 2>to understand, test and maintain. You know exactly where to

300
00:14:34.600 --> 00:14:37.039
<v Speaker 2>look for the logic related to creating a user.

301
00:14:37.440 --> 00:14:39.639
<v Speaker 1>Are their best practices for writing them? Yeah?

302
00:14:39.679 --> 00:14:43.080
<v Speaker 2>Definitely. A common one is to have just one public

303
00:14:43.159 --> 00:14:47.679
<v Speaker 2>method often called dot call, makes its purpose clear, keep

304
00:14:47.720 --> 00:14:52.440
<v Speaker 2>dependencies internal or pass them in, and crucially return something meaningful,

305
00:14:52.600 --> 00:14:53.759
<v Speaker 2>not just true or false.

306
00:14:53.799 --> 00:14:55.080
<v Speaker 1>What kind of meaningful object?

307
00:14:55.159 --> 00:14:58.159
<v Speaker 2>Maybe a simple struct or an immutable struck that indicates

308
00:14:58.200 --> 00:15:01.639
<v Speaker 2>success and carries the results object like the newly created

309
00:15:01.720 --> 00:15:04.720
<v Speaker 2>user or any errors that occurred. Gives you much more

310
00:15:04.720 --> 00:15:05.799
<v Speaker 2>context than a boolean.

311
00:15:05.879 --> 00:15:07.159
<v Speaker 1>Can you give a concrete example?

312
00:15:07.279 --> 00:15:10.360
<v Speaker 2>Sure, the source uses a new registration service. When the

313
00:15:10.399 --> 00:15:13.320
<v Speaker 2>user signs up, this one service might coordinate several steps.

314
00:15:13.519 --> 00:15:15.840
<v Speaker 2>Create the hat record, create a user, maybe create a

315
00:15:15.840 --> 00:15:18.919
<v Speaker 2>striped customer record, queue up a welcome email, send a

316
00:15:18.960 --> 00:15:19.879
<v Speaker 2>Slack notification.

317
00:15:20.159 --> 00:15:21.879
<v Speaker 1>Okay, lots of steps right.

318
00:15:22.120 --> 00:15:24.840
<v Speaker 2>Putting all that logic directly in your user's controller would

319
00:15:24.840 --> 00:15:28.519
<v Speaker 2>be a mess. The service object orchestrates it cleanly. You

320
00:15:28.519 --> 00:15:32.519
<v Speaker 2>can even use namespaces like notification services, dot, Slack, webooks,

321
00:15:32.519 --> 00:15:34.919
<v Speaker 2>dot new account to organize related services.

322
00:15:35.039 --> 00:15:38.000
<v Speaker 1>Okay, that makes sense. Now, Some of those steps like

323
00:15:38.080 --> 00:15:40.840
<v Speaker 1>sending emails or talking to stripe might take a second

324
00:15:40.879 --> 00:15:43.399
<v Speaker 1>or two. How do you prevent that from slowing down

325
00:15:43.440 --> 00:15:44.320
<v Speaker 1>the user's request?

326
00:15:44.679 --> 00:15:48.600
<v Speaker 2>Background jobs absolutely essential for a responsive web apps. You

327
00:15:48.679 --> 00:15:51.320
<v Speaker 2>identify tasks that don't need to happen immediately within the

328
00:15:51.320 --> 00:15:55.480
<v Speaker 2>web request cycle, sending emails, processing images, calling slow external APIs,

329
00:15:55.799 --> 00:15:58.120
<v Speaker 2>and you push them onto a background queue so.

330
00:15:58.080 --> 00:16:01.759
<v Speaker 1>The web request finishes quickly and the job runs later exactly.

331
00:16:02.240 --> 00:16:05.240
<v Speaker 2>The user gets a fast response and a separate process

332
00:16:05.279 --> 00:16:07.559
<v Speaker 2>picks up the job from the queue and executes it

333
00:16:07.600 --> 00:16:09.840
<v Speaker 2>in the background. Keeps your app feeling snappy.

334
00:16:09.960 --> 00:16:11.080
<v Speaker 1>How does Rails handle that?

335
00:16:11.759 --> 00:16:14.919
<v Speaker 2>Rails has a built in framework called active job. It

336
00:16:14.919 --> 00:16:17.559
<v Speaker 2>provides a standard way to define your jobs. Then you

337
00:16:17.679 --> 00:16:20.120
<v Speaker 2>choose a back end adapter to actually run the jobs.

338
00:16:20.360 --> 00:16:23.919
<v Speaker 2>Sidekick is probably the most popular for Rails. It uses rttus.

339
00:16:23.919 --> 00:16:25.320
<v Speaker 2>It's very fast and reliable.

340
00:16:25.559 --> 00:16:28.600
<v Speaker 1>Could use schedule jobs too, like send a daily email yep.

341
00:16:29.000 --> 00:16:31.960
<v Speaker 2>You can use extensions like Sidekick, dot cron or similar

342
00:16:32.000 --> 00:16:35.080
<v Speaker 2>tools to schedule jobs to run at specific times or intervals.

343
00:16:35.360 --> 00:16:39.039
<v Speaker 2>Perfect for daily reminders, weekly reports, nightly cleanups, et cetera.

344
00:16:39.320 --> 00:16:42.440
<v Speaker 1>Speaking of emails, how does Rails actually send.

345
00:16:42.279 --> 00:16:45.639
<v Speaker 2>Them through action mailer? It's another built in framework. You

346
00:16:45.720 --> 00:16:49.159
<v Speaker 2>define mailer classes similar to controllers, with methods for each

347
00:16:49.159 --> 00:16:51.360
<v Speaker 2>type of email you want to send. You can create

348
00:16:51.399 --> 00:16:53.960
<v Speaker 2>both HTML and plaintext versions easily.

349
00:16:54.399 --> 00:16:57.559
<v Speaker 1>And you mentioned deliver later for background jobs right.

350
00:16:57.919 --> 00:17:00.320
<v Speaker 2>You can call deliver now to send it immediate lee

351
00:17:00.440 --> 00:17:03.919
<v Speaker 2>usually only for testing or very specific cases, or deliver

352
00:17:04.039 --> 00:17:06.880
<v Speaker 2>later to queue it up via active job. Always use

353
00:17:06.920 --> 00:17:09.079
<v Speaker 2>deliver later for real world emails.

354
00:17:09.119 --> 00:17:11.079
<v Speaker 1>What else do you need for emails and production just

355
00:17:11.240 --> 00:17:11.960
<v Speaker 1>action mailer?

356
00:17:12.119 --> 00:17:15.720
<v Speaker 2>No, you'll need an actual email delivery service like send grid, Postmark,

357
00:17:15.799 --> 00:17:18.880
<v Speaker 2>or mail gun. Your server itself usually isn't configured for

358
00:17:18.960 --> 00:17:22.839
<v Speaker 2>reliable mass email delivery. You also need to configure DNS

359
00:17:22.960 --> 00:17:26.359
<v Speaker 2>records SBF, DKM for your domain to ensure your emails

360
00:17:26.400 --> 00:17:28.119
<v Speaker 2>don't end up in spam folders.

361
00:17:27.759 --> 00:17:30.599
<v Speaker 1>And apikeys for those services, How do you store those? Securely?

362
00:17:30.880 --> 00:17:33.960
<v Speaker 2>Rails credentials It's a built in way to manage secrets.

363
00:17:34.240 --> 00:17:37.559
<v Speaker 2>It creates an encrypted file canfig credentials, dot email, dot

364
00:17:37.559 --> 00:17:41.720
<v Speaker 2>enc where you store apikeys and other sensitive stuff. This

365
00:17:41.880 --> 00:17:44.400
<v Speaker 2>file can be checked in to get but you need

366
00:17:44.440 --> 00:17:46.880
<v Speaker 2>the master key canfig master dot key which you never

367
00:17:46.960 --> 00:17:50.359
<v Speaker 2>check in to decrypt it. Very secure way to handle secrets.

368
00:17:50.400 --> 00:17:53.559
<v Speaker 1>Okay, that's sending email. What about receiving email? Can rails

369
00:17:53.599 --> 00:17:55.920
<v Speaker 1>handle replies? Yes?

370
00:17:56.720 --> 00:17:59.599
<v Speaker 2>This is super powerful. Action Mailbox is the framework for this.

371
00:18:00.000 --> 00:18:03.519
<v Speaker 2>That's your Rails application receive incoming emails. You can figure

372
00:18:03.599 --> 00:18:06.559
<v Speaker 2>specific email addresses like replies at your wapp dot com

373
00:18:06.759 --> 00:18:08.799
<v Speaker 2>to route emails into your application.

374
00:18:09.000 --> 00:18:09.880
<v Speaker 1>What could you do with them?

375
00:18:09.920 --> 00:18:13.400
<v Speaker 2>Then you define mailboxes that process incoming emails. Based on

376
00:18:13.480 --> 00:18:16.519
<v Speaker 2>routing rules, you can parse the email content, extract data,

377
00:18:16.519 --> 00:18:19.279
<v Speaker 2>and trigger actions in your app. Imagine replying to a

378
00:18:19.279 --> 00:18:22.319
<v Speaker 2>stand up reminder email with your updates and action Mailbox

379
00:18:22.359 --> 00:18:25.720
<v Speaker 2>automatically parses it and saves your stand up Very cool stuff.

380
00:18:25.839 --> 00:18:29.559
<v Speaker 1>Wow, Okay, that opens up possibilities. Let's talk money. Stripe

381
00:18:29.559 --> 00:18:32.440
<v Speaker 1>integration for payments and subscriptions. How does that typically work?

382
00:18:32.440 --> 00:18:35.440
<v Speaker 2>In rail SaaS Stripe is pretty much the de facto standard.

383
00:18:35.599 --> 00:18:39.000
<v Speaker 2>It's very developer friendly. First, you define your products and

384
00:18:39.039 --> 00:18:44.000
<v Speaker 2>prices in the Stripe dashboard, your different subscription tiers, free, pro,

385
00:18:44.279 --> 00:18:45.839
<v Speaker 2>enterprise and how much they.

386
00:18:45.720 --> 00:18:47.400
<v Speaker 1>Cost, and link those to your app.

387
00:18:47.559 --> 00:18:51.079
<v Speaker 2>Yeah. You often map those Stripe product price IDs to

388
00:18:51.319 --> 00:18:54.799
<v Speaker 2>something in your application, maybe a configuration file, products dot

389
00:18:54.839 --> 00:18:58.880
<v Speaker 2>AML or a simple product model. This lets your app

390
00:18:58.960 --> 00:19:01.920
<v Speaker 2>know the limits associated with each plan like max users,

391
00:19:02.000 --> 00:19:03.279
<v Speaker 2>features available, etc.

392
00:19:03.720 --> 00:19:05.640
<v Speaker 1>How does the sign up flow work with Stripe?

393
00:19:05.960 --> 00:19:09.240
<v Speaker 2>Typically, when a user signs up or upgrades, your application

394
00:19:09.319 --> 00:19:13.119
<v Speaker 2>interacts with stripes API. You create a Stripe customer object

395
00:19:13.160 --> 00:19:16.079
<v Speaker 2>for the user count. Then you create a subscription linking

396
00:19:16.119 --> 00:19:19.200
<v Speaker 2>that customer to a specific price. Stripe handles the actual

397
00:19:19.240 --> 00:19:22.119
<v Speaker 2>payment processing. Your app just needs to store the Stripe

398
00:19:22.119 --> 00:19:25.839
<v Speaker 2>customer ID and subscription ID on your account or user model,

399
00:19:25.920 --> 00:19:26.240
<v Speaker 2>and then.

400
00:19:26.160 --> 00:19:29.359
<v Speaker 1>You check that subscription status to enforce limits exactly.

401
00:19:29.759 --> 00:19:32.720
<v Speaker 2>You'll have logic, maybe a before reaction in your controllers

402
00:19:32.839 --> 00:19:36.359
<v Speaker 2>or checks within specific features that looks at the account's

403
00:19:36.400 --> 00:19:39.920
<v Speaker 2>subscription status. Is the subscription active, what plan are they on?

404
00:19:40.279 --> 00:19:43.400
<v Speaker 2>Based on that, you allow or deny actions, or maybe

405
00:19:43.599 --> 00:19:45.839
<v Speaker 2>redirect them to a billing page if they hit a limit.

406
00:19:46.519 --> 00:19:49.720
<v Speaker 2>Stripe provides a pre built billing portal you can easily

407
00:19:49.799 --> 00:19:52.559
<v Speaker 2>link users to for managing their subscription.

408
00:19:52.319 --> 00:19:55.200
<v Speaker 1>And testing this. You don't want to actually charge credit

409
00:19:55.279 --> 00:19:56.039
<v Speaker 1>cards during.

410
00:19:55.839 --> 00:19:58.680
<v Speaker 2>Tests, absolutely not. This is where mocking comes in again.

411
00:19:59.160 --> 00:20:02.160
<v Speaker 2>You use libra is like webmoc or VCR again to

412
00:20:02.200 --> 00:20:05.119
<v Speaker 2>intercept any calls to the Stripe API during your tests,

413
00:20:05.559 --> 00:20:09.400
<v Speaker 2>you provide fake successful or failed responses. This ensures your

414
00:20:09.440 --> 00:20:12.640
<v Speaker 2>tests run quickly and reliably without hitting striped servers or

415
00:20:12.680 --> 00:20:14.839
<v Speaker 2>needing real card details. Crucial.

416
00:20:15.000 --> 00:20:19.039
<v Speaker 1>Okay, beyond payments, what about integrating with other APIs like GitHub?

417
00:20:19.680 --> 00:20:23.119
<v Speaker 2>The pattern is often similar, usually involving o off for authorization.

418
00:20:23.559 --> 00:20:26.720
<v Speaker 2>For GitHub, you'd register an oof app. When a user

419
00:20:26.720 --> 00:20:29.240
<v Speaker 2>wants to connect their account, you redirect them to Gethub

420
00:20:29.279 --> 00:20:30.440
<v Speaker 2>to authorize your application.

421
00:20:30.680 --> 00:20:32.000
<v Speaker 1>Big grant permission right.

422
00:20:32.359 --> 00:20:35.400
<v Speaker 2>GitHub redirects them back to your app with a temporary code.

423
00:20:35.799 --> 00:20:39.759
<v Speaker 2>Your app then exchanges that code securely with GitHub's API

424
00:20:39.880 --> 00:20:43.279
<v Speaker 2>to get an access token. You store that token securely,

425
00:20:43.599 --> 00:20:47.279
<v Speaker 2>maybe using Rails credentials or database encryption, and then you

426
00:20:47.319 --> 00:20:49.480
<v Speaker 2>can use it to make API calls on the user's

427
00:20:49.519 --> 00:20:52.359
<v Speaker 2>behalf like listing their repositories.

428
00:20:51.799 --> 00:20:55.799
<v Speaker 1>And getting real time updates from GitHub like new code pushes.

429
00:20:55.960 --> 00:20:59.559
<v Speaker 2>That's webhooks. You'd use the GitHub API using the user's

430
00:20:59.559 --> 00:21:02.720
<v Speaker 2>token to tell GitHub, Hey, whenever there's a push event

431
00:21:02.759 --> 00:21:05.440
<v Speaker 2>on this repo, send a notification to this URL on

432
00:21:05.519 --> 00:21:06.119
<v Speaker 2>my application.

433
00:21:06.319 --> 00:21:08.119
<v Speaker 1>So getthub calls your app exactly.

434
00:21:08.160 --> 00:21:10.960
<v Speaker 2>Your app needs an endpoint ready to receive that webhook data.

435
00:21:11.119 --> 00:21:14.000
<v Speaker 2>You'd probably store these incoming events in your database, maybe

436
00:21:14.000 --> 00:21:16.759
<v Speaker 2>in an event table. STI could be useful here too.

437
00:21:16.880 --> 00:21:19.440
<v Speaker 2>For different types of events push event, pull request event,

438
00:21:19.680 --> 00:21:22.160
<v Speaker 2>you might store the raw event, payload and adjson B

439
00:21:22.279 --> 00:21:24.079
<v Speaker 2>column for flexibility.

440
00:21:23.480 --> 00:21:25.880
<v Speaker 1>And finally, tracking what users are doing in the app.

441
00:21:26.079 --> 00:21:30.359
<v Speaker 2>Analytics Yeah, super important for understanding usage and making decisions.

442
00:21:30.799 --> 00:21:33.960
<v Speaker 2>Tools like mixed Panel or segment or common you integrate

443
00:21:34.000 --> 00:21:37.160
<v Speaker 2>their stks and send events from your rails app back

444
00:21:37.279 --> 00:21:41.519
<v Speaker 2>end or potentially the front end. JavaScript you identify users

445
00:21:41.559 --> 00:21:46.279
<v Speaker 2>and track key actions users sign up, page viewed, feature used,

446
00:21:46.559 --> 00:21:50.119
<v Speaker 2>stand up, created, plan, upgraded gives you valuable insights into

447
00:21:50.240 --> 00:21:50.920
<v Speaker 2>user behavior.

448
00:21:51.000 --> 00:21:53.920
<v Speaker 1>Okay, we've built a lot, now making it fast and

449
00:21:53.920 --> 00:21:57.640
<v Speaker 1>getting it deployed. Optimizations First, what are the low hanging fruit,

450
00:21:57.720 --> 00:22:00.400
<v Speaker 1>the real bang for your buck performance improvements?

451
00:22:00.559 --> 00:22:04.920
<v Speaker 2>Good question? First, know where the slownesses. Tools like Rackmini

452
00:22:05.000 --> 00:22:08.559
<v Speaker 2>Profiler show you database query times and rendering times right

453
00:22:08.599 --> 00:22:11.240
<v Speaker 2>in your browser during development. Essential first step.

454
00:22:11.240 --> 00:22:12.720
<v Speaker 1>Okay, diagnose first, Then what.

455
00:22:13.000 --> 00:22:16.119
<v Speaker 2>N plus one queries? Huge performance killer. This is when

456
00:22:16.160 --> 00:22:18.119
<v Speaker 2>you load a list of things like teams and then

457
00:22:18.160 --> 00:22:20.880
<v Speaker 2>loop through them, making a separate database query inside the

458
00:22:20.880 --> 00:22:23.640
<v Speaker 2>loop to get related data like the users for each team.

459
00:22:23.599 --> 00:22:26.720
<v Speaker 1>One query for the list, then end queries inside.

460
00:22:26.400 --> 00:22:30.559
<v Speaker 2>The loop exactly. You fix it with eager loading. In Rails,

461
00:22:30.799 --> 00:22:34.960
<v Speaker 2>you use dot includes or references on your initial query

462
00:22:35.559 --> 00:22:38.880
<v Speaker 2>team dot includes, dot users, dot all that tells Rails

463
00:22:38.880 --> 00:22:41.559
<v Speaker 2>to fetch all the teams and their associated users in

464
00:22:41.680 --> 00:22:43.319
<v Speaker 2>just one or two efficient queries.

465
00:22:43.359 --> 00:22:45.279
<v Speaker 1>Are there tools to fined N plus ones?

466
00:22:45.839 --> 00:22:48.640
<v Speaker 2>Yes? The bullet gem is fantastic for detecting N plus

467
00:22:48.680 --> 00:22:52.720
<v Speaker 2>one queries and other database issues automatically during development. It'll

468
00:22:52.759 --> 00:22:55.279
<v Speaker 2>pop up warnings telling you where to add eager loading.

469
00:22:55.599 --> 00:22:57.799
<v Speaker 1>What else slows down database access.

470
00:22:57.480 --> 00:23:01.359
<v Speaker 2>Missing database indices. If you're freequently looking up records by

471
00:23:01.400 --> 00:23:03.759
<v Speaker 2>a column that doesn't have an index, like finding a

472
00:23:03.839 --> 00:23:06.920
<v Speaker 2>user by email, the database has to scan the hotal

473
00:23:07.079 --> 00:23:08.640
<v Speaker 2>terribly slow on large tables.

474
00:23:08.799 --> 00:23:10.160
<v Speaker 1>How do you find missing indices?

475
00:23:10.240 --> 00:23:12.680
<v Speaker 2>Tools like luld blog can scan your models and usage

476
00:23:12.720 --> 00:23:15.519
<v Speaker 2>patterns and suggest indices you should add. Adding the right

477
00:23:15.519 --> 00:23:18.480
<v Speaker 2>indices can make lookups orders of magnitude faster.

478
00:23:18.759 --> 00:23:21.400
<v Speaker 1>What about just displaying lots of data like a huge

479
00:23:21.440 --> 00:23:23.160
<v Speaker 1>list of stand ups pagination.

480
00:23:24.279 --> 00:23:26.720
<v Speaker 2>Don't try to load and render thousands of records on

481
00:23:26.720 --> 00:23:30.640
<v Speaker 2>one page. It kills memory and browser performance. Use a

482
00:23:30.680 --> 00:23:33.799
<v Speaker 2>gem like pagy, which is very fast and memory efficient

483
00:23:34.119 --> 00:23:37.319
<v Speaker 2>to break results into pages, show twenty or fifty items

484
00:23:37.319 --> 00:23:40.559
<v Speaker 2>at a time. Huge improvement for user experience and serverload.

485
00:23:40.680 --> 00:23:43.599
<v Speaker 1>Any quick server side wins Gzip compression.

486
00:23:44.119 --> 00:23:48.039
<v Speaker 2>Rails has middleware called rack deflator that can automatically compress

487
00:23:48.079 --> 00:23:52.799
<v Speaker 2>responses htmail json before sending them to the browser. Smaller

488
00:23:52.839 --> 00:23:55.480
<v Speaker 2>response size means faster downloads. It's usually just a one

489
00:23:55.480 --> 00:23:56.720
<v Speaker 2>line configuration change.

490
00:23:57.000 --> 00:23:59.839
<v Speaker 1>Easy win, okay, and the big one casing How does that?

491
00:24:00.799 --> 00:24:04.480
<v Speaker 2>Cashing is probably the single most impactful performance technique. The

492
00:24:04.519 --> 00:24:07.799
<v Speaker 2>basic idea is don't recalculate or rerender something if it

493
00:24:07.799 --> 00:24:10.119
<v Speaker 2>hasn't changed, store the result and reuse it.

494
00:24:10.160 --> 00:24:11.480
<v Speaker 1>Where do you store the cash stuff?

495
00:24:11.599 --> 00:24:14.359
<v Speaker 2>You can figure a cash store. Rettis is very common

496
00:24:14.400 --> 00:24:17.880
<v Speaker 2>and versatile for cashing in Rails. Memcash is another option.

497
00:24:18.240 --> 00:24:20.920
<v Speaker 2>You can even use the filesystem or memory for development.

498
00:24:21.039 --> 00:24:22.480
<v Speaker 1>What kinds of things can you cash?

499
00:24:22.799 --> 00:24:26.039
<v Speaker 2>Several levels. There's low level caching, where you cash raw

500
00:24:26.160 --> 00:24:29.359
<v Speaker 2>data like the result of a complex query. Then there's

501
00:24:29.400 --> 00:24:32.720
<v Speaker 2>fragment caching, which is really powerful in RAILS views. You

502
00:24:32.759 --> 00:24:35.359
<v Speaker 2>wrap a piece of HTML, maybe a complex partial in

503
00:24:35.400 --> 00:24:39.240
<v Speaker 2>a cash block. Rails renders at once, stores the HPML fragment,

504
00:24:39.519 --> 00:24:43.279
<v Speaker 2>and reuses it on subsequent requests until the underlying data changes.

505
00:24:43.599 --> 00:24:45.559
<v Speaker 1>How does it know when the data changes?

506
00:24:45.799 --> 00:24:49.160
<v Speaker 2>Typically through cash keys based on the objects being rendered.

507
00:24:49.480 --> 00:24:52.359
<v Speaker 2>If you cash a block based on a at product object,

508
00:24:52.839 --> 00:24:55.839
<v Speaker 2>Rails uses the products it and update at timestamp and

509
00:24:55.880 --> 00:24:58.920
<v Speaker 2>the key. When the product updates, the key changes and

510
00:24:59.000 --> 00:25:00.000
<v Speaker 2>the cash is invalid.

511
00:25:00.640 --> 00:25:03.440
<v Speaker 1>In Russian doll caching sounds complex.

512
00:25:03.079 --> 00:25:05.640
<v Speaker 2>It builds on fragment caching. Imagine you cash a list

513
00:25:05.720 --> 00:25:08.039
<v Speaker 2>of products, and each product in the list is also

514
00:25:08.119 --> 00:25:12.119
<v Speaker 2>cashed individually, like nested Russian dolls. The magic is that

515
00:25:12.160 --> 00:25:16.039
<v Speaker 2>if you update one product, Rails can automatically invalidate just

516
00:25:16.119 --> 00:25:19.079
<v Speaker 2>that product's fragment and the outerless cash that contained it.

517
00:25:19.079 --> 00:25:22.519
<v Speaker 2>It often involves using touch true on model associations or

518
00:25:22.559 --> 00:25:26.480
<v Speaker 2>after commit hooks to ensure parent objects updated timestamps change

519
00:25:26.480 --> 00:25:30.319
<v Speaker 2>when children change, automatically busting the cash. Very efficient. How

520
00:25:30.359 --> 00:25:32.519
<v Speaker 2>you set up cashing, You can figure your cash store

521
00:25:32.519 --> 00:25:35.640
<v Speaker 2>in your environment files example fund environments, production, dot RP

522
00:25:36.079 --> 00:25:38.839
<v Speaker 2>tell Rails to use reddis You can easily toggle cashing

523
00:25:38.839 --> 00:25:41.440
<v Speaker 2>on off and development with binrailsdev dot cash.

524
00:25:41.359 --> 00:25:46.039
<v Speaker 1>Okay apps optimized time to deploy. Heroku is mentioned as popular.

525
00:25:46.200 --> 00:25:47.079
<v Speaker 1>How do you prep for that?

526
00:25:47.559 --> 00:25:50.720
<v Speaker 2>Heroku is great for getting started. Before deploying. You need

527
00:25:50.759 --> 00:25:54.960
<v Speaker 2>to configure production specific settings your domain name, mailer settings

528
00:25:55.039 --> 00:25:57.880
<v Speaker 2>using those SND grid keys, maybe forcing SSL.

529
00:25:57.680 --> 00:25:59.160
<v Speaker 1>And the deployment process itself.

530
00:25:59.200 --> 00:26:03.559
<v Speaker 2>It's pretty standard Heroku workflow. Install the Heroku Cli two belt,

531
00:26:04.079 --> 00:26:07.599
<v Speaker 2>run Heroku create to create your app. Add necessary add

532
00:26:07.599 --> 00:26:10.839
<v Speaker 2>ons like postgrass, Heroku add ons dot create, Heroku postgress

533
00:26:10.880 --> 00:26:13.960
<v Speaker 2>call and rettis Heroku add ons dot create, Heroku rettis.

534
00:26:14.240 --> 00:26:17.759
<v Speaker 2>Set your environment variables securely using Heroku configu do set,

535
00:26:17.880 --> 00:26:20.839
<v Speaker 2>especially the Rails master key needed to decrypt your credentials.

536
00:26:21.000 --> 00:26:22.960
<v Speaker 2>You might need to adjust your profile to specify how

537
00:26:23.000 --> 00:26:26.079
<v Speaker 2>many web workers and background job sidecack workers to run.

538
00:26:26.359 --> 00:26:29.000
<v Speaker 2>Then it's just get push Heroku Maine to deploy your code,

539
00:26:29.200 --> 00:26:32.319
<v Speaker 2>followed by Heroku run rails dB dot migrate to update

540
00:26:32.319 --> 00:26:33.279
<v Speaker 2>the production database.

541
00:26:33.279 --> 00:26:36.960
<v Speaker 1>STEMA seems straightforward enough for basic deployment. Any other cool

542
00:26:37.200 --> 00:26:39.519
<v Speaker 1>modern rails tools worth mentioning for sauce.

543
00:26:39.720 --> 00:26:43.960
<v Speaker 2>Oh yeah, Rail seven brought lotuing for active record queries.

544
00:26:44.480 --> 00:26:46.599
<v Speaker 2>If you have a page that needs to run say

545
00:26:46.920 --> 00:26:50.200
<v Speaker 2>three independent database queries to gather data for different sections

546
00:26:50.200 --> 00:26:53.880
<v Speaker 2>look at dashboard exactly. Instead of running them one after another,

547
00:26:53.920 --> 00:26:58.599
<v Speaker 2>lotusink lets them run concurrently, potentially speeding up data loading significantly.

548
00:26:59.359 --> 00:27:01.839
<v Speaker 2>And another big one is active record encryption.

549
00:27:02.240 --> 00:27:04.200
<v Speaker 1>Encrypting data in the database YEP.

550
00:27:04.519 --> 00:27:07.599
<v Speaker 2>Rail seven has built in support using the encrypts declaration

551
00:27:07.680 --> 00:27:10.799
<v Speaker 2>in your model. You can mark attributes like user dotcrypts

552
00:27:10.839 --> 00:27:15.039
<v Speaker 2>dot email or task dotcrypts dot title. Rails handles the

553
00:27:15.119 --> 00:27:19.240
<v Speaker 2>encryption and decryption automatically and transparently for your application. The

554
00:27:19.319 --> 00:27:21.680
<v Speaker 2>data is stored encrypted at rest in the database, but

555
00:27:21.720 --> 00:27:24.480
<v Speaker 2>your app code just reads and writes it normally. Adds

556
00:27:24.519 --> 00:27:26.480
<v Speaker 2>a great layer of security for sensitive data.

557
00:27:26.640 --> 00:27:29.799
<v Speaker 1>Wow, that's built right in. Very nice. Okay, so we've

558
00:27:29.799 --> 00:27:31.640
<v Speaker 1>covered a kind of ground here. What does this all

559
00:27:31.640 --> 00:27:34.200
<v Speaker 1>mean for someone listening trying to learn or build their

560
00:27:34.240 --> 00:27:34.799
<v Speaker 1>own saws.

561
00:27:35.119 --> 00:27:37.240
<v Speaker 2>I think the big takeaway is seeing the whole journey

562
00:27:37.240 --> 00:27:40.799
<v Speaker 2>mapped out from that initial Rails new and setting up

563
00:27:40.880 --> 00:27:45.279
<v Speaker 2>users with solid off through building core features, handling payments,

564
00:27:45.319 --> 00:27:49.039
<v Speaker 2>integrating APIs, using background jobs all the way to optimizing

565
00:27:49.039 --> 00:27:53.359
<v Speaker 2>and deploying. Rails provides tools and conventions for almost every step.

566
00:27:53.720 --> 00:27:57.599
<v Speaker 2>It's amazing how this one framework guides you through such complexity,

567
00:27:57.799 --> 00:27:58.880
<v Speaker 2>often quite elegantly.

568
00:27:59.240 --> 00:28:02.160
<v Speaker 1>It really paints picture of how all these pieces connect.

569
00:28:02.240 --> 00:28:05.799
<v Speaker 1>The database, the back end logic, the frontend reactivity with

570
00:28:05.920 --> 00:28:08.200
<v Speaker 1>hot wire, the external services.

571
00:28:08.319 --> 00:28:10.680
<v Speaker 2>Absolutely, building a sauce is a deep dive. It's not

572
00:28:10.720 --> 00:28:13.759
<v Speaker 2>just one thing, it's this whole ecosystem of interconnected parts

573
00:28:13.759 --> 00:28:14.400
<v Speaker 2>working together.

574
00:28:14.720 --> 00:28:17.519
<v Speaker 1>So as you, the listener, reflect on everything we've unpacked

575
00:28:17.519 --> 00:28:20.680
<v Speaker 1>from this guide, here's something to think about. How might

576
00:28:20.839 --> 00:28:25.160
<v Speaker 1>understanding this deep interplay between that server driven frontend reactivity

577
00:28:25.200 --> 00:28:27.839
<v Speaker 1>like hot wire and the back end efficiency techniques like

578
00:28:27.920 --> 00:28:32.039
<v Speaker 1>background jobs and sophisticated caching. How might that fundamentally change

579
00:28:32.039 --> 00:28:35.039
<v Speaker 1>the way you approach building your next major software project,

580
00:28:35.039 --> 00:28:36.240
<v Speaker 1>even if you're not using rails
