1 00:00:16,910 --> 00:00:18,960 DAVID PADILLA: All right. Let's get started. 2 00:00:18,960 --> 00:00:21,800 Hello everyone. My name is David Padilla. 3 00:00:21,800 --> 00:00:25,910 You can find me at dabit. That's my user name 4 00:00:25,910 --> 00:00:27,880 on Twitter, on GitHub, and basically 5 00:00:27,880 --> 00:00:32,090 everything that matters. Hold on. 6 00:00:32,090 --> 00:00:34,110 I work for a company called Crowd Interactive, which 7 00:00:34,110 --> 00:00:37,500 is a Ruby on Rails consultancy based in Mexico. 8 00:00:37,500 --> 00:00:42,640 We also organize the only conference down there that 9 00:00:42,640 --> 00:00:45,710 takes topics like Ruby, JavaScript and all that. You 10 00:00:45,710 --> 00:00:48,589 can go to that website if you want more 11 00:00:48,589 --> 00:00:49,420 info. 12 00:00:49,420 --> 00:00:51,640 And I'm here to talk to you, or more 13 00:00:51,640 --> 00:00:54,600 like to, sort of, how to write web applications 14 00:00:54,600 --> 00:00:58,390 with Ruby but not with Rails, nor Sinatra nor 15 00:00:58,390 --> 00:01:01,239 Padrino nor any kind of frameworks. 16 00:01:01,239 --> 00:01:03,539 First, I want to give you a little bit 17 00:01:03,539 --> 00:01:07,280 of background of, of, of why I'm here or 18 00:01:07,280 --> 00:01:11,890 where this, where this talk came from. So, I 19 00:01:11,890 --> 00:01:18,890 basically invented MVC on ASP Classic. I don't know 20 00:01:19,030 --> 00:01:21,819 if you guys are old enough to hear about 21 00:01:21,819 --> 00:01:26,229 ASP Classic. Those were the good days. 22 00:01:26,229 --> 00:01:29,610 So I invented MVC on ASP. Although not really. 23 00:01:29,610 --> 00:01:33,429 Not formally. But, when I was working back then, 24 00:01:33,429 --> 00:01:35,099 my first job, it was ASP, and I was 25 00:01:35,099 --> 00:01:38,250 doing things like this. I remember, they threw me 26 00:01:38,250 --> 00:01:40,390 into a project that had code like this, that 27 00:01:40,390 --> 00:01:43,270 was like a page. They want that ASP. And 28 00:01:43,270 --> 00:01:44,830 we had all that code at the beginning where 29 00:01:44,830 --> 00:01:48,170 you set up your connection and, and everything relevant, 30 00:01:48,170 --> 00:01:50,750 and then on the, on the body of the, 31 00:01:50,750 --> 00:01:53,470 of the, of the page, you have, like, the 32 00:01:53,470 --> 00:01:56,950 dynamic stuff and, and, and you ran SQL queries 33 00:01:56,950 --> 00:02:00,300 and all that. And then whenever we needed to 34 00:02:00,300 --> 00:02:04,130 do another page like this, we would just copy 35 00:02:04,130 --> 00:02:07,660 all the code into page two, dot asp, and 36 00:02:07,660 --> 00:02:10,590 just change what's relevant. Right? But everything was copied 37 00:02:10,590 --> 00:02:13,310 and pasted into page and page and page, which 38 00:02:13,310 --> 00:02:15,599 was kind of odd. 39 00:02:15,599 --> 00:02:17,209 So when I, when I, when I began working 40 00:02:17,209 --> 00:02:19,090 with this, I was wondering like, how, how can 41 00:02:19,090 --> 00:02:22,650 this be possible. What happens, like, it was, it 42 00:02:22,650 --> 00:02:24,980 was painful to change something on the layout, for 43 00:02:24,980 --> 00:02:27,110 example. Just the page title, because you had to 44 00:02:27,110 --> 00:02:32,120 go page one, one by one to change whatever 45 00:02:32,120 --> 00:02:33,950 needed to be changed, and it made no sense 46 00:02:33,950 --> 00:02:34,980 to me. 47 00:02:34,980 --> 00:02:37,660 So I came up with some sort of hack. 48 00:02:37,660 --> 00:02:40,420 I changed the code to do something like this. 49 00:02:40,420 --> 00:02:42,670 I discovered there was some sort of include, so 50 00:02:42,670 --> 00:02:46,600 I said, I, I put all my database stuff 51 00:02:46,600 --> 00:02:49,480 in a single file. And then I decided to 52 00:02:49,480 --> 00:02:52,650 use the query string to drive to the application 53 00:02:52,650 --> 00:02:55,310 and do something like this. So I only had 54 00:02:55,310 --> 00:02:57,940 index dot asp, and then through query string I 55 00:02:57,940 --> 00:03:01,800 said page, product list. And then it, with a, 56 00:03:01,800 --> 00:03:03,840 with a fancy case, I will say, OK, if 57 00:03:03,840 --> 00:03:06,650 it says products then you have to call products 58 00:03:06,650 --> 00:03:09,180 dot asp. If it's another page, call this one 59 00:03:09,180 --> 00:03:11,220 and so on. And this made things easier. If 60 00:03:11,220 --> 00:03:13,340 I needed to change something on the layout, you 61 00:03:13,340 --> 00:03:15,960 will just switch it in index dot asp and 62 00:03:15,960 --> 00:03:17,069 not the whole application. 63 00:03:17,069 --> 00:03:19,600 Now, before you judge me for this code, let 64 00:03:19,600 --> 00:03:22,160 me remind you that it was the year 2000, 65 00:03:22,160 --> 00:03:24,750 right. That is Nickelback back there. I was listening 66 00:03:24,750 --> 00:03:27,290 to a lot of Nickelback back then. So you 67 00:03:27,290 --> 00:03:29,880 can think where I, where I was, right. So, 68 00:03:29,880 --> 00:03:33,400 it's 2000. I moved on from ASP. I went 69 00:03:33,400 --> 00:03:35,900 into the world of Java. I learned about Spring, 70 00:03:35,900 --> 00:03:38,550 about Struts. And that was when someone introduced me 71 00:03:38,550 --> 00:03:40,569 to the concept of MVC, and I was like 72 00:03:40,569 --> 00:03:44,790 oh. Yeah. This is what I needed back there, 73 00:03:44,790 --> 00:03:46,209 but it didn't exist there. 74 00:03:46,209 --> 00:03:47,650 And, and if you think about it, it was 75 00:03:47,650 --> 00:03:49,709 sort of the same concept, right. Like, separate your 76 00:03:49,709 --> 00:03:56,400 concerns wherever it matters, and, and stop reusing code, 77 00:03:56,400 --> 00:03:59,410 basically. And after a couple of years of doing 78 00:03:59,410 --> 00:04:02,270 Java, I was introduced, then, to Rails. I was 79 00:04:02,270 --> 00:04:05,580 lucky enough to get a job doing Rails programming, 80 00:04:05,580 --> 00:04:06,709 and that's what I've been doing for the last 81 00:04:06,709 --> 00:04:10,569 seven years. And I've been very happy about it. 82 00:04:10,569 --> 00:04:14,490 So, if there's someone that has recently moved from 83 00:04:14,490 --> 00:04:17,940 Java to Rails understand this feeling. So I've been 84 00:04:17,940 --> 00:04:23,289 happy for the last seven years. Until I hit 85 00:04:23,289 --> 00:04:29,060 what I guess I'd call my mid-programmer life crisis. 86 00:04:29,060 --> 00:04:32,470 This, what happened to me is that I was 87 00:04:32,470 --> 00:04:35,860 thinking, that was, that was, those days were cool, 88 00:04:35,860 --> 00:04:37,380 where you had all these problems that you needed 89 00:04:37,380 --> 00:04:40,440 to solve with programming and all that stuff. And 90 00:04:40,440 --> 00:04:42,310 right now I think that everything is just there. 91 00:04:42,310 --> 00:04:44,290 You just need to bundle install and the, and 92 00:04:44,290 --> 00:04:45,600 the world is solved. 93 00:04:45,600 --> 00:04:49,169 So I began thinking, programming web applications with Rails 94 00:04:49,169 --> 00:04:52,580 it's, it's kind of boring. That's, that's, that's like, 95 00:04:52,580 --> 00:04:56,480 I, I, I hit my mid-programmer life crisis, and 96 00:04:56,480 --> 00:04:58,780 it's because I began thinking, like, building websites with 97 00:04:58,780 --> 00:05:01,290 Rails is not enough programming. There's, there's a lot 98 00:05:01,290 --> 00:05:03,630 of magic like, like Akira just said. Just a 99 00:05:03,630 --> 00:05:05,930 lot of magic going on. It's, it's not enough 100 00:05:05,930 --> 00:05:09,370 programming for me. It feels like, if you called 101 00:05:09,370 --> 00:05:12,110 yourself a great programmer because you do Rails, it's 102 00:05:12,110 --> 00:05:14,460 the same thing as calling yourself a carpenter because 103 00:05:14,460 --> 00:05:17,590 you bought your carpenter at Ikea, right? Like. Yeah. 104 00:05:17,590 --> 00:05:19,930 I built that, that, that table. Oh, oh you 105 00:05:19,930 --> 00:05:22,840 have skills, right? You know what I mean? 106 00:05:22,840 --> 00:05:26,270 And, on top of that, on top of that, 107 00:05:26,270 --> 00:05:28,510 things like this happened. If you know Konstantin Haase, 108 00:05:28,510 --> 00:05:30,660 he was ranting the other day because Rails is 109 00:05:30,660 --> 00:05:33,310 like the worst Rack citizen there is. And he 110 00:05:33,310 --> 00:05:35,300 was telling, he was telling us that it was 111 00:05:35,300 --> 00:05:39,130 because they never contribute features back, implemented encrypted sessions 112 00:05:39,130 --> 00:05:41,520 in Rails, while it should be on the layer 113 00:05:41,520 --> 00:05:43,860 of Rack. You know, things like that. 114 00:05:43,860 --> 00:05:46,330 And the problem is that, that we, as Rails 115 00:05:46,330 --> 00:05:49,180 programmers, don't want to contribute back. It, it occurred 116 00:05:49,180 --> 00:05:51,340 to me that it's maybe because most of us 117 00:05:51,340 --> 00:05:54,260 don't know what's going on outside of Rails, right? 118 00:05:54,260 --> 00:05:56,800 Like, if, if you were at that last talk, 119 00:05:56,800 --> 00:05:58,710 there's all these concepts that we probably don't know 120 00:05:58,710 --> 00:06:02,070 where, do, that they belong to Railties or to 121 00:06:02,070 --> 00:06:04,600 Rack or whatever. We just think that everything is 122 00:06:04,600 --> 00:06:05,800 Rails, and it's not. 123 00:06:05,800 --> 00:06:07,120 And also, well, we used to have all these 124 00:06:07,120 --> 00:06:10,290 problems. We used to actually write SQL, you know, 125 00:06:10,290 --> 00:06:12,160 and now we don't do any of that. So 126 00:06:12,160 --> 00:06:15,190 maybe, maybe our mind is not challenged enough. So 127 00:06:15,190 --> 00:06:17,990 we need to, we need to start thinking about 128 00:06:17,990 --> 00:06:21,310 everything that's outside there. We need to bring programming 129 00:06:21,310 --> 00:06:24,860 back basically, and so that's why I'm here. I'm 130 00:06:24,860 --> 00:06:27,650 gonna try to show you how to write a 131 00:06:27,650 --> 00:06:31,760 web application with Ruby, but not Rails. And maybe 132 00:06:31,760 --> 00:06:33,169 just a little bit of Rack. 133 00:06:33,169 --> 00:06:36,070 You, I'm gonna explain to you a little bit 134 00:06:36,070 --> 00:06:39,639 what Rack is. And it's basically just a super 135 00:06:39,639 --> 00:06:44,520 cool interface that acts as, yes, an interface between 136 00:06:44,520 --> 00:06:47,760 web servers and applications. So basically what happens is 137 00:06:47,760 --> 00:06:51,860 that the web server, whether it is Unicorn, Puma, 138 00:06:51,860 --> 00:06:55,070 whatever, has to a hash with requests headers, right. 139 00:06:55,070 --> 00:06:57,290 And that hash is sent over to the web 140 00:06:57,290 --> 00:07:01,490 application that, by convention, needs to be any object 141 00:07:01,490 --> 00:07:03,490 that responds to the call method and receive that 142 00:07:03,490 --> 00:07:04,729 hash. 143 00:07:04,729 --> 00:07:07,070 And then the web application does its thing, you 144 00:07:07,070 --> 00:07:09,210 know, and the only thing that it needs to 145 00:07:09,210 --> 00:07:12,050 do is return back an array with three elements. 146 00:07:12,050 --> 00:07:14,699 One should be the http_code of the response, that's 147 00:07:14,699 --> 00:07:18,850 an integer. The, a hash with all the headers 148 00:07:18,850 --> 00:07:21,889 of the response, and a body, which will be 149 00:07:21,889 --> 00:07:25,610 any object that can respond to the method each. 150 00:07:25,610 --> 00:07:28,360 And that array travels back through the web server, 151 00:07:28,360 --> 00:07:30,360 and then the web server just turns it into 152 00:07:30,360 --> 00:07:36,100 something that the browser can understand. So, like I 153 00:07:36,100 --> 00:07:39,180 said, like you've heard, all you need to run 154 00:07:39,180 --> 00:07:42,470 a Rack application is the file config dot ru. 155 00:07:42,470 --> 00:07:47,050 And define on that file, using the run directive, 156 00:07:47,050 --> 00:07:50,630 the object that will respond to call, and that 157 00:07:50,630 --> 00:07:54,250 will receive that hash of, of headers. 158 00:07:54,250 --> 00:07:57,910 So, what you're seeing right here is basically the 159 00:07:57,910 --> 00:08:02,720 smallest but most useless web application ever. But it's 160 00:08:02,720 --> 00:08:06,710 just those three lines and that works. So, this 161 00:08:06,710 --> 00:08:08,350 is the dangerous part. This is where I do 162 00:08:08,350 --> 00:08:11,600 some live coding. Call me a rebel if you'd 163 00:08:11,600 --> 00:08:12,330 like. 164 00:08:12,330 --> 00:08:16,120 So, let's, let's do some live coding. I'm gonna 165 00:08:16,120 --> 00:08:22,960 get out this here. And let's begin with that, 166 00:08:22,960 --> 00:08:25,380 you can see that, right? Yeah. That's good. Let's 167 00:08:25,380 --> 00:08:28,389 begin with that config dot ru thing that we 168 00:08:28,389 --> 00:08:31,590 mentioned there. We need the run directive - we'll 169 00:08:31,590 --> 00:08:38,590 create a proc, because a proc can respond to, 170 00:08:39,269 --> 00:08:44,320 to call. We'll ask it to print that hash, 171 00:08:44,320 --> 00:08:45,850 you know, that we get, that we'll get from 172 00:08:45,850 --> 00:08:50,420 the server, and then just answer 200, a hash, 173 00:08:50,420 --> 00:08:54,629 and just some empty array, which is an object 174 00:08:54,629 --> 00:08:57,170 that responds to each, right. An array can do 175 00:08:57,170 --> 00:08:58,230 that. 176 00:08:58,230 --> 00:09:01,990 So, let's see what happens. To start any Rack 177 00:09:01,990 --> 00:09:03,790 application, all you need to do is run the 178 00:09:03,790 --> 00:09:06,339 rackup command, whatever, to reset that config dot ru 179 00:09:06,339 --> 00:09:09,649 file. And then it just boots up basically. So 180 00:09:09,649 --> 00:09:12,860 it's telling me that it's booting up on port 181 00:09:12,860 --> 00:09:16,269 9292. So if you go to a browser and 182 00:09:16,269 --> 00:09:18,410 we reload, there's nothing here because we're not doing 183 00:09:18,410 --> 00:09:22,339 anything. But you can see here that we get 184 00:09:22,339 --> 00:09:23,629 that hash, right. 185 00:09:23,629 --> 00:09:25,050 This is, this is what the browser sent over 186 00:09:25,050 --> 00:09:28,779 to the, to the Rack application, and it got, 187 00:09:28,779 --> 00:09:31,089 well, all that information that the browser is sending. 188 00:09:31,089 --> 00:09:35,829 So, that is great. 189 00:09:35,829 --> 00:09:40,529 Next thing, let's actually do something with this. So, 190 00:09:40,529 --> 00:09:45,649 we're gonna create a body like, like all web 191 00:09:45,649 --> 00:09:50,850 application have, and some, well. It will be body. 192 00:09:50,850 --> 00:09:52,629 I'm not very good at html so please forgive 193 00:09:52,629 --> 00:09:58,399 me. Let's do Hello World. We'll be, close the 194 00:09:58,399 --> 00:10:04,399 body tag, close the html one. And well. Let's 195 00:10:04,399 --> 00:10:10,999 just send that body back. See what happens. We 196 00:10:10,999 --> 00:10:15,279 restart our web server. And boom. We have a 197 00:10:15,279 --> 00:10:18,319 working web application that serves us a single page, 198 00:10:18,319 --> 00:10:18,929 basically. 199 00:10:18,929 --> 00:10:22,839 All right. Things are working. The problem right now 200 00:10:22,839 --> 00:10:25,269 with our web application is that it's only serving 201 00:10:25,269 --> 00:10:27,569 one page, no matter what the path is. So 202 00:10:27,569 --> 00:10:31,139 if you go, like, to, slash, like the root 203 00:10:31,139 --> 00:10:33,249 path, it's Hello World. If you go to slash 204 00:10:33,249 --> 00:10:37,779 admin, Hello World. it doesn't matter where you go. 205 00:10:37,779 --> 00:10:39,879 It's always, you know, the same thing. Because we 206 00:10:39,879 --> 00:10:44,329 need something to actually grab the request path and 207 00:10:44,329 --> 00:10:46,429 send it over to whatever it needs to be, 208 00:10:46,429 --> 00:10:48,119 wherever it needs to go. 209 00:10:48,119 --> 00:10:51,779 So, we're gonna use. That's, that's what's called a 210 00:10:51,779 --> 00:10:54,420 router, usually in the MVC pattern. And the router 211 00:10:54,420 --> 00:10:57,899 just does, does that. It basically just takes the, 212 00:10:57,899 --> 00:11:00,730 the request path, and then send it over to 213 00:11:00,730 --> 00:11:04,920 whoever needs to handle that request. Specifically, this is 214 00:11:04,920 --> 00:11:10,179 very complicated logic, in general. It's way beyond just 215 00:11:10,179 --> 00:11:13,300 doing a case structure. But we'll do that for 216 00:11:13,300 --> 00:11:14,389 now. 217 00:11:14,389 --> 00:11:16,199 If you want to learn more about the router 218 00:11:16,199 --> 00:11:19,980 in Rails, it's a gem called Journey. And as 219 00:11:19,980 --> 00:11:22,119 you can see, it has features and problems, which 220 00:11:22,119 --> 00:11:25,269 is basically just designed for Rails and that it's 221 00:11:25,269 --> 00:11:28,420 too complex right now. And you can imagine why. 222 00:11:28,420 --> 00:11:30,730 Like, if you, if you define routes, there's all 223 00:11:30,730 --> 00:11:33,829 these cases that need to be handled. Whatever you 224 00:11:33,829 --> 00:11:38,290 have. If it, the method, and if you have 225 00:11:38,290 --> 00:11:41,029 variables and all that, so it's, it's complex logic, 226 00:11:41,029 --> 00:11:43,929 right. So we're not getting into that. We're just 227 00:11:43,929 --> 00:11:47,540 gonna use the same technology that I used ten 228 00:11:47,540 --> 00:11:54,239 years ago, which is define our case, yay. 229 00:11:54,239 --> 00:11:58,100 So, first thing we want to do is say 230 00:11:58,100 --> 00:12:05,100 something like path equals env. We're gonna get it 231 00:12:06,369 --> 00:12:09,629 from those setters. And then say case path, and 232 00:12:09,629 --> 00:12:14,069 you know, when that path is the root path, 233 00:12:14,069 --> 00:12:18,160 just serve this. And if it's something else, just 234 00:12:18,160 --> 00:12:24,279 say hey, not found. And return a 404, the 235 00:12:24,279 --> 00:12:29,410 headers and return that body. And that's it. Yes. 236 00:12:29,410 --> 00:12:31,329 That's our router. Sweet. 237 00:12:31,329 --> 00:12:37,699 So. We restart our application and see what happens. 238 00:12:37,699 --> 00:12:42,999 So, now product not found. And if you go 239 00:12:42,999 --> 00:12:46,290 to root path, Hello World. Great. So, as you 240 00:12:46,290 --> 00:12:47,989 can see, the server is getting the same. You 241 00:12:47,989 --> 00:12:51,360 know, it's sending the right codes. 404. 200. And, 242 00:12:51,360 --> 00:12:54,989 and so on. So, we now have some sort 243 00:12:54,989 --> 00:12:57,360 of router, right. 244 00:12:57,360 --> 00:13:01,029 So, what's next? If we, we probably don't want 245 00:13:01,029 --> 00:13:05,199 to have this code, you know, just pasted in, 246 00:13:05,199 --> 00:13:07,139 in our whole, in a single file and do 247 00:13:07,139 --> 00:13:10,499 our whole web application here. So let's move this 248 00:13:10,499 --> 00:13:14,069 to a class. To, to make it a little 249 00:13:14,069 --> 00:13:18,929 bit more understandable. So I'm gonna steal this, and 250 00:13:18,929 --> 00:13:23,350 I'm gonna put it into a app.rb file. OK. 251 00:13:23,350 --> 00:13:30,040 Instead of this, I'm gonna say, like, class App. 252 00:13:30,040 --> 00:13:33,439 It has to be, it has to respond to, 253 00:13:33,439 --> 00:13:39,470 to call method and receive env, or that hash. 254 00:13:39,470 --> 00:13:41,449 And I'm gonna end the method. I'm gonna end 255 00:13:41,449 --> 00:13:45,839 that. And ident it. And that's it. Now we 256 00:13:45,839 --> 00:13:49,809 have to include that to config dot ru. 257 00:13:49,809 --> 00:13:56,809 I'm gonna require that file. And then I'm gonna 258 00:13:58,639 --> 00:14:02,869 tell Rack instead of, of doing stuff here, just, 259 00:14:02,869 --> 00:14:06,019 you know, send the hash to that, to that 260 00:14:06,019 --> 00:14:08,509 class, right. Because now it's an object that can 261 00:14:08,509 --> 00:14:12,160 respond to each. Sorry. To call. 262 00:14:12,160 --> 00:14:14,329 So this. Let's just make sure that this is 263 00:14:14,329 --> 00:14:15,899 working well. I don't want to write a test 264 00:14:15,899 --> 00:14:20,009 for this because, you saw the keynote. So, there 265 00:14:20,009 --> 00:14:23,660 you go. It's still working. We have now abstracted 266 00:14:23,660 --> 00:14:27,799 our code to, to, to a class. So that's 267 00:14:27,799 --> 00:14:31,779 great. What's next? So, I guess what's next is 268 00:14:31,779 --> 00:14:38,609 to go to our, here, and create controllers, right. 269 00:14:38,609 --> 00:14:42,559 Instead of having this laying around. We probably want 270 00:14:42,559 --> 00:14:46,399 a class that says, that does this. 271 00:14:46,399 --> 00:14:51,309 So let's create a folder real quick that's controllers. 272 00:14:51,309 --> 00:14:58,309 We'll put them there. And I'll say, let's say 273 00:15:00,259 --> 00:15:07,259 root_controller.rb. What? I know what's gonna. Hold on. Yeah. 274 00:15:09,109 --> 00:15:15,779 root_controller.rb. We say OK. RootController. And have, I don't 275 00:15:15,779 --> 00:15:18,749 know, the action show. This is where code will 276 00:15:18,749 --> 00:15:23,929 be. 277 00:15:23,929 --> 00:15:28,689 We probably want to have this controller class receive 278 00:15:28,689 --> 00:15:35,689 that env through the initializer. And then say, self.env 279 00:15:38,089 --> 00:15:45,089 equals env. We added , let's see. And there 280 00:15:48,189 --> 00:15:48,489 you go. 281 00:15:48,489 --> 00:15:50,290 And here, instead of doing this, we'll just say 282 00:15:50,290 --> 00:15:57,290 RootControll.new, get env and show. We want to require 283 00:16:00,799 --> 00:16:07,799 that controller here. And let's make sure this works. 284 00:16:09,350 --> 00:16:16,350 It doesn't. Perks of live coding. I know what 285 00:16:16,749 --> 00:16:23,419 it is. Don't worry. OK. K. So. We start 286 00:16:23,419 --> 00:16:26,319 our web application and it's still working, which is 287 00:16:26,319 --> 00:16:27,999 perfect. 288 00:16:27,999 --> 00:16:30,279 So what else, what else does a web application 289 00:16:30,279 --> 00:16:36,100 need? It needs views, right. We need views. We 290 00:16:36,100 --> 00:16:38,910 need to set our html logic. We need to 291 00:16:38,910 --> 00:16:40,579 set it apart and put it in a different 292 00:16:40,579 --> 00:16:45,579 component. And, that's like the controller html pasted into 293 00:16:45,579 --> 00:16:49,919 a controller. So let's create views. Hope you guys 294 00:16:49,919 --> 00:16:54,059 like haml. I do. So, we're gonna use that 295 00:16:54,059 --> 00:16:57,049 to create our views. First of all, we're gonna, 296 00:16:57,049 --> 00:17:00,989 we, we need to create a folder. Views for 297 00:17:00,989 --> 00:17:04,919 this controller in specific. All right. 298 00:17:04,919 --> 00:17:11,919 So, let's create our views. Show.html.haml. We need, like, 299 00:17:13,059 --> 00:17:20,059 head. Title, Railsconf. We'll create a body. And h1. 300 00:17:24,349 --> 00:17:27,750 Something like that. 301 00:17:27,750 --> 00:17:33,930 Controllers, root_controller, and then here. Let's create a method 302 00:17:33,930 --> 00:17:38,020 that will be render. And that method, I want 303 00:17:38,020 --> 00:17:41,300 it to receive like the, the, the template path. 304 00:17:41,300 --> 00:17:43,830 And what you need to do to, to render 305 00:17:43,830 --> 00:17:46,310 like a template with haml and stuff, you need 306 00:17:46,310 --> 00:17:51,760 to open the file first and read it. You 307 00:17:51,760 --> 00:17:55,610 need to add some sort of variable, which we 308 00:17:55,610 --> 00:18:02,610 call template, and then just say, Dear Haml::Engine, can 309 00:18:03,860 --> 00:18:05,650 you please render this? 310 00:18:05,650 --> 00:18:10,660 See, it's easy. That's why I chose haml. So 311 00:18:10,660 --> 00:18:13,250 we don't need this anymore, because our superview's gonna 312 00:18:13,250 --> 00:18:20,250 do it, and we're gonna say render('views/root/show.html.haml'). And I 313 00:18:24,860 --> 00:18:29,120 think that's it. We probably just need to require 314 00:18:29,120 --> 00:18:35,660 haml. We don't want it to blow up. There 315 00:18:35,660 --> 00:18:37,460 you go. 316 00:18:37,460 --> 00:18:42,580 And, let's see what happens. Yay. We're still there. 317 00:18:42,580 --> 00:18:45,520 So now we have views. The title changed because 318 00:18:45,520 --> 00:18:47,180 on that other version, we didn't have. But now 319 00:18:47,180 --> 00:18:48,790 we do. 320 00:18:48,790 --> 00:18:51,890 And, the whole point of what we're doing right 321 00:18:51,890 --> 00:18:54,610 now, it's because we didn't want to sort of 322 00:18:54,610 --> 00:18:57,290 duplicate code and copy and paste, and so we 323 00:18:57,290 --> 00:18:59,970 probably need layouts, right? Like, like, like with Rails. 324 00:18:59,970 --> 00:19:06,030 So, let's create a layout. First thing we do, 325 00:19:06,030 --> 00:19:13,030 views/layouts. Yeah. That'll work. And let's open what we 326 00:19:13,400 --> 00:19:17,060 have right now. And just steal the first four 327 00:19:17,060 --> 00:19:20,990 lines. No, actually, we need everything, all the way 328 00:19:20,990 --> 00:19:22,050 here. Yeah. 329 00:19:22,050 --> 00:19:26,630 And we indent it. Let's open views/layouts, let's call 330 00:19:26,630 --> 00:19:33,630 it app.html.haml. Views/layouts/app.html.haml. And here's where we paste it. 331 00:19:37,990 --> 00:19:40,470 And, like good old Rails, we're gonna do a 332 00:19:40,470 --> 00:19:43,000 yield, and there's where we want the view code 333 00:19:43,000 --> 00:19:48,510 to show up. I'm on time. That's good. 334 00:19:48,510 --> 00:19:53,400 We go back to our RootController, and now we 335 00:19:53,400 --> 00:19:59,570 define a method that will be render_with_layout. Same thing. 336 00:19:59,570 --> 00:20:03,700 We need to know the template path. And let's 337 00:20:03,700 --> 00:20:08,200 see, first we open our layout file. We're gonna 338 00:20:08,200 --> 00:20:13,900 hard code it because that's how we do. Layouts. 339 00:20:13,900 --> 00:20:20,900 No magic here. Read. 340 00:20:24,920 --> 00:20:28,190 And do the same thing. Dear Haml::Engine, can you 341 00:20:28,190 --> 00:20:33,880 please render that layout? The trick here is that 342 00:20:33,880 --> 00:20:36,310 you can pass a block to render, and then 343 00:20:36,310 --> 00:20:39,640 whatever you render inside of the block, that's what 344 00:20:39,640 --> 00:20:42,830 gets rendered to yield. So we simply call render 345 00:20:42,830 --> 00:20:45,720 again with that template path that we were looking 346 00:20:45,720 --> 00:20:47,620 for up there. 347 00:20:47,620 --> 00:20:54,620 So, now we change this code to render_with_layout. We 348 00:20:57,660 --> 00:21:02,990 restart our application. And it's still working. So. Now, 349 00:21:02,990 --> 00:21:09,990 if I go and change the title, for example, 350 00:21:11,130 --> 00:21:15,080 to 2014, then it should, should change. Yay! So, 351 00:21:15,080 --> 00:21:19,140 now we have a layout. That's great. And so, 352 00:21:19,140 --> 00:21:22,630 what else do we need from web applications? 353 00:21:22,630 --> 00:21:28,420 So, we usually need to have dynamic information on, 354 00:21:28,420 --> 00:21:31,390 on our web application. Something like this. Like, maybe 355 00:21:31,390 --> 00:21:34,390 the name comes from the database, or comes from 356 00:21:34,390 --> 00:21:37,060 a query param or whatever. So we need to 357 00:21:37,060 --> 00:21:40,800 be able to change data on the views, right. 358 00:21:40,800 --> 00:21:43,580 So, let's see if, first of all, we just 359 00:21:43,580 --> 00:21:47,910 add that variable there, like, like Rails, as if 360 00:21:47,910 --> 00:21:50,290 Rails will do it. But we can see that 361 00:21:50,290 --> 00:21:53,360 it's not that easy. It, it doesn't happen magically. 362 00:21:53,360 --> 00:21:56,030 So, what we need to do for this to 363 00:21:56,030 --> 00:21:59,780 work is we go back to our controller and, 364 00:21:59,780 --> 00:22:03,440 well, first of all, we need to define it, 365 00:22:03,440 --> 00:22:04,480 right. 366 00:22:04,480 --> 00:22:07,600 Let's say, world. 367 00:22:07,600 --> 00:22:11,770 And second of all, the render method can receive, 368 00:22:11,770 --> 00:22:16,110 as parameter to context of where the layout is 369 00:22:16,110 --> 00:22:19,610 going to be sort of processed. So basically we 370 00:22:19,610 --> 00:22:21,500 just need to tell it the context should be 371 00:22:21,500 --> 00:22:25,740 the same object. And, and that way this instance 372 00:22:25,740 --> 00:22:29,750 variable will be part of the package. So what 373 00:22:29,750 --> 00:22:34,730 we do here is we are going to as- 374 00:22:34,730 --> 00:22:37,690 to add the context to our render method. But 375 00:22:37,690 --> 00:22:40,480 as default we'll just say hey, just graft self 376 00:22:40,480 --> 00:22:46,510 if there's nothing there. Same here. And we need 377 00:22:46,510 --> 00:22:53,510 to pass that context to this render method. Over 378 00:22:57,980 --> 00:23:01,910 here and over here. So it's all the same. 379 00:23:01,910 --> 00:23:04,620 And this is gonna happen sort of magically because 380 00:23:04,620 --> 00:23:07,950 of that default, where we set it to self. 381 00:23:07,950 --> 00:23:10,280 And yay. It's working. 382 00:23:10,280 --> 00:23:14,320 So now we can populate that variable or, couple 383 00:23:14,320 --> 00:23:17,270 of variables with whatever we want basically. The most 384 00:23:17,270 --> 00:23:21,030 typical thing that we could do would be to 385 00:23:21,030 --> 00:23:24,070 send it over in a, in, in, in, like 386 00:23:24,070 --> 00:23:28,020 params. Like something like this. If it comes as 387 00:23:28,020 --> 00:23:33,810 a parameter, do something, or else just do world, 388 00:23:33,810 --> 00:23:37,400 right. But params is a method that we need 389 00:23:37,400 --> 00:23:44,400 to basically define. So let's define that. Params. I'm 390 00:23:45,210 --> 00:23:48,080 not going to write code to like go to 391 00:23:48,080 --> 00:23:53,410 a query string. We're just gonna use a method 392 00:23:53,410 --> 00:23:56,990 that already exists in Rack::Utils which basically does that 393 00:23:56,990 --> 00:24:01,570 - parse_nested_query. What it's gonna do, it's gonna take 394 00:24:01,570 --> 00:24:06,930 the query string and it's gonna turn it into 395 00:24:06,930 --> 00:24:09,050 a nice hash that we can access. So we're 396 00:24:09,050 --> 00:24:13,280 gonna add that here in params name and it 397 00:24:13,280 --> 00:24:17,260 should work at, at the first attempt. Let's try 398 00:24:17,260 --> 00:24:17,680 it. 399 00:24:17,680 --> 00:24:22,090 So, default is Hello, World. It will say name, 400 00:24:22,090 --> 00:24:28,830 I don't know, RailsConf, and it works. Hello Jane 401 00:24:28,830 --> 00:24:32,130 or whatever it is, you know. It just works. 402 00:24:32,130 --> 00:24:34,880 And, well, I guess the last thing that we 403 00:24:34,880 --> 00:24:37,430 could do for a web application will be to 404 00:24:37,430 --> 00:24:42,830 properly abstract it. And we probably want to grab 405 00:24:42,830 --> 00:24:45,100 all this code and set it on a controller 406 00:24:45,100 --> 00:24:52,100 class, right. Because. Over there. And, OK. Now, let's 407 00:24:53,750 --> 00:24:58,390 go back to our root_controller and just say hey, 408 00:24:58,390 --> 00:25:01,960 just inherit from controller. And that's it. That way 409 00:25:01,960 --> 00:25:05,110 we can, in the end, we can add more, 410 00:25:05,110 --> 00:25:09,150 more and more controllers to our super web application. 411 00:25:09,150 --> 00:25:11,470 The only thing we need to do is require 412 00:25:11,470 --> 00:25:17,880 controller. Here, and. Let's make sure that it still 413 00:25:17,880 --> 00:25:18,380 works. 414 00:25:18,380 --> 00:25:22,790 It still does. That's good. That's always good. Yup. 415 00:25:22,790 --> 00:25:27,110 There you go. So that's it on the coding 416 00:25:27,110 --> 00:25:29,360 side. As you can see, you have a working, 417 00:25:29,360 --> 00:25:33,850 perfectly working web application right there from using no 418 00:25:33,850 --> 00:25:40,850 frameworks at all, only your Ruby code. Now, I 419 00:25:41,330 --> 00:25:44,130 probably don't have the time to add models and 420 00:25:44,130 --> 00:25:48,360 all that because that's different logic, but. You could 421 00:25:48,360 --> 00:25:51,200 just, you know, inherit ActiveRecord::Base, they, they, you know, 422 00:25:51,200 --> 00:25:53,680 they've already done it. And it's, it's hard logic 423 00:25:53,680 --> 00:25:54,670 you don't need to redo. All you need to 424 00:25:54,670 --> 00:25:57,960 do is just, you know, define classes and say, 425 00:25:57,960 --> 00:26:00,440 inherit from ActiveRecord::Base, and you will get, like, all 426 00:26:00,440 --> 00:26:02,130 the magic that you get on Rails. 427 00:26:02,130 --> 00:26:03,720 If you're a little bit more hardcore, then you 428 00:26:03,720 --> 00:26:06,900 can use sequel, and just write your methods like 429 00:26:06,900 --> 00:26:09,190 so, and you can get access to the database 430 00:26:09,190 --> 00:26:11,600 that's, as if it was a hash, and just 431 00:26:11,600 --> 00:26:13,680 write your dot all, your dot find, all that 432 00:26:13,680 --> 00:26:17,150 logic. And if you're even more hardcore, you can 433 00:26:17,150 --> 00:26:20,600 directly use the pg gem or the mysql gem, 434 00:26:20,600 --> 00:26:24,030 and just, you know, do this sort of crazy 435 00:26:24,030 --> 00:26:27,510 stuff where you actually write SQL. Yay SQL. And 436 00:26:27,510 --> 00:26:30,740 then just, you know, iterate through the results and 437 00:26:30,740 --> 00:26:32,670 put them in the hash and all that. This 438 00:26:32,670 --> 00:26:35,430 is, this is fun. Like, this is programming, right. 439 00:26:35,430 --> 00:26:39,770 And one last piece of advice I have for 440 00:26:39,770 --> 00:26:46,450 you is don't ever actually do this. Don't ever 441 00:26:46,450 --> 00:26:49,080 actually do this unless you're some sort of speed 442 00:26:49,080 --> 00:26:52,270 freak or performance freak. When I run my tests, 443 00:26:52,270 --> 00:26:55,670 my super web application was able to handle 700 444 00:26:55,670 --> 00:26:59,360 requests per second, and every request will take one 445 00:26:59,360 --> 00:27:03,350 millisecond, which is pretty fast, right. But when I 446 00:27:03,350 --> 00:27:06,400 created the same application using Rails, I had like 447 00:27:06,400 --> 00:27:11,550 2x slowness, right, right. It will take two milliseconds 448 00:27:11,550 --> 00:27:14,150 to, to run, which is unacceptable. I want one 449 00:27:14,150 --> 00:27:18,470 milliseconds. But this is unfair because Rails solves all 450 00:27:18,470 --> 00:27:21,530 these problems, right. We have logging, caching, database pooling, 451 00:27:21,530 --> 00:27:24,120 sessions, cookies, security, all of that, that we're not 452 00:27:24,120 --> 00:27:27,850 considering on our own application. 453 00:27:27,850 --> 00:27:28,830 But even if you don't want to do this 454 00:27:28,830 --> 00:27:31,200 in real life, you do want to read code, 455 00:27:31,200 --> 00:27:33,290 and you do want to go and, and, and 456 00:27:33,290 --> 00:27:36,830 try and see how Rails is doing things. You 457 00:27:36,830 --> 00:27:40,030 want to try to understand, how is it doing 458 00:27:40,030 --> 00:27:43,510 it? Like, right, you want to do find that 459 00:27:43,510 --> 00:27:46,100 code that connects to the database, that code that 460 00:27:46,100 --> 00:27:50,140 turns dot find into select star from that table, 461 00:27:50,140 --> 00:27:52,020 you know, all that, you want to go and 462 00:27:52,020 --> 00:27:54,410 read and try to understand how things work. And 463 00:27:54,410 --> 00:27:57,570 then once you understand, try to write your own 464 00:27:57,570 --> 00:28:02,020 framework. Well, why not? There's, there's space for, for 465 00:28:02,020 --> 00:28:04,170 a new framework. Maybe, maybe you'll be the next 466 00:28:04,170 --> 00:28:08,590 DHH and will, and will be able to afford 467 00:28:08,590 --> 00:28:11,430 and race car and all that. 468 00:28:11,430 --> 00:28:12,850 But the most important thing is that you will 469 00:28:12,850 --> 00:28:17,250 understand, like, master this topic. You will know, you, 470 00:28:17,250 --> 00:28:19,460 you will have that feeling of saying, hey, I 471 00:28:19,460 --> 00:28:20,990 know how this works. This is great, now I 472 00:28:20,990 --> 00:28:27,180 can go back to doing my Ikea software. But 473 00:28:27,180 --> 00:28:30,780 I at least I know how it works, right. 474 00:28:30,780 --> 00:28:32,970 And then if you see the Rails core team, 475 00:28:32,970 --> 00:28:35,280 give them a hug. Because you will understand also, 476 00:28:35,280 --> 00:28:37,180 like, the pain that they had to go through 477 00:28:37,180 --> 00:28:40,540 to get Rails to where it is right now, 478 00:28:40,540 --> 00:28:42,440 because it's not easy, right. We just, we just 479 00:28:42,440 --> 00:28:45,360 wrote like thirty minutes of code, but it does 480 00:28:45,360 --> 00:28:47,480 basically nothing. It needs to take care of routing, 481 00:28:47,480 --> 00:28:51,090 like I said, caching, security, and all that. And 482 00:28:51,090 --> 00:28:52,970 that's, you know, a lot of lines of code 483 00:28:52,970 --> 00:28:55,620 that need to, that need to happen. So, so 484 00:28:55,620 --> 00:28:57,870 you see a Rails core guy, you say, hey, 485 00:28:57,870 --> 00:29:00,920 thanks for that. Give him a hug. And my 486 00:29:00,920 --> 00:29:03,050 last disclaimer is that I do not actually think 487 00:29:03,050 --> 00:29:05,500 that writing web applications with Rails is boring. That 488 00:29:05,500 --> 00:29:07,740 was just added for drama. 489 00:29:07,740 --> 00:29:12,250 And I hope you understand that. That's it. I 490 00:29:12,250 --> 00:29:15,090 will Tweet or, whenever you see the slides you 491 00:29:15,090 --> 00:29:17,330 will see like the code example on, on my 492 00:29:17,330 --> 00:29:20,020 talk on that, on that url. And thank you.