WEBVTT 00:00:16.655 --> 00:00:18.387 Brandon:Oh, hi. 00:00:18.387 --> 00:00:20.877 A hush falls over the room because I'm not paying attention. 00:00:21.434 --> 00:00:22.767 My slides came up. Hi. 00:00:25.551 --> 00:00:27.090 Really quick first, 00:00:27.512 --> 00:00:30.517 there are seats in the middle if people can squish together, 00:00:31.873 --> 00:00:33.990 otherwise people are going to be sitting in the 00:00:33.990 --> 00:00:37.349 aisles and the fire marshal is going to get angry. 00:00:38.651 --> 00:00:41.849 I don't know that, I'm not a building guy. 00:00:42.947 --> 00:00:44.764 Hi everybody, sorry to make you move around 00:00:44.764 --> 00:00:46.354 but also maybe that will wake you up a little bit. 00:00:46.354 --> 00:00:47.593 This is going to be a shot of espresso, 00:00:47.593 --> 00:00:48.960 we've got to go, go, go, go. 00:00:49.067 --> 00:00:51.890 I have a very serious talk about the heart of architecture. 00:00:53.828 --> 00:00:57.526 As you know, as DHH said at the first talk, we are engineers. 00:00:57.526 --> 00:00:59.503 What we do is build bridges with code. 00:01:01.698 --> 00:01:04.741 We are architects, we build centuries old castles. 00:01:05.772 --> 00:01:09.038 We are craftspeople, we are old-timey metal workers. 00:01:09.388 --> 00:01:10.853 And we live in the cloud. 00:01:10.853 --> 00:01:12.959 I think Javascript is ready for all of these things. 00:01:13.631 --> 00:01:16.809 I feel like Javascript is ready for Cloudgineering. 00:01:20.574 --> 00:01:22.165 If anybody knows what any of the things 00:01:22.165 --> 00:01:23.943 I said with the pretty pictures are, 00:01:23.943 --> 00:01:26.221 please grab me after the talk and explain them to me. 00:01:26.682 --> 00:01:29.154 I just say them to sound smart and serious 00:01:29.154 --> 00:01:31.116 about programming, it is serious business. 00:01:31.116 --> 00:01:32.225 Hi I'm Brandon Hayes, 00:01:32.225 --> 00:01:34.935 I work with Charles actually at The Frontside. 00:01:35.308 --> 00:01:41.748 I'm a dedicated Cloudgineer and no one ever asks which of 00:01:41.748 --> 00:01:44.087 us is the smart one when we converse together, 00:01:44.087 --> 00:01:45.549 which is a little weird. 00:01:45.778 --> 00:01:46.975 These are my credentials. 00:01:46.975 --> 00:01:49.352 As you can see I'm highly credentialed and 00:01:49.352 --> 00:01:51.349 ready to tell you all about programming. 00:01:52.369 --> 00:01:54.024 My wife gave me a few of these, 00:01:54.024 --> 00:01:55.850 most of them are actually true. 00:02:00.271 --> 00:02:02.350 I'm not here to talk about some 00:02:02.350 --> 00:02:06.897 core ideal or some big fancy thing. 00:02:07.334 --> 00:02:08.132 I live in the real world. 00:02:08.725 --> 00:02:12.972 I have to write programs that people want written fast and 00:02:12.972 --> 00:02:16.693 want them yesterday and it's very challenging some times. 00:02:17.389 --> 00:02:21.122 I understand that architecture is great but 00:02:21.122 --> 00:02:22.978 I don't have a lot of use for ivory tower people, 00:02:22.978 --> 00:02:25.284 I think the universe has plenty of uncles in it. 00:02:26.587 --> 00:02:28.695 We live in a place, 00:02:29.148 --> 00:02:31.070 and I'm going to tell you a tale about a couple of places. 00:02:31.557 --> 00:02:33.521 It's actually a meta talk about the 00:02:33.521 --> 00:02:35.099 ball of mud architecture pattern, 00:02:35.099 --> 00:02:36.710 that's one I can really get behind. 00:02:36.929 --> 00:02:39.563 If you're not familiar with this, Brian Foote, 00:02:39.563 --> 00:02:43.288 I believe in the late 1970s, described an architecture 00:02:43.288 --> 00:02:46.149 pattern that everyone here has seen called the ball of mud. 00:02:47.349 --> 00:02:48.693 To do that I need to talk about city planning. 00:02:50.006 --> 00:02:51.743 Most cities are not designed for growth. 00:02:52.320 --> 00:02:53.976 Salt Lake City would be a rare exception. 00:02:54.683 --> 00:02:57.350 You'll see it handled its eventual growth pretty well. 00:02:58.413 --> 00:03:00.839 From layout to infrastructure it seems to have avoided 00:03:00.839 --> 00:03:03.515 many of the problems that plague large cities. 00:03:04.163 --> 00:03:06.122 Our code does not live in Salt Lake City, 00:03:06.122 --> 00:03:07.376 they don't work like that. 00:03:08.288 --> 00:03:11.272 My current home town of Austin is a lot more typical. 00:03:13.048 --> 00:03:15.510 I look at that every day on my drive home while 00:03:15.510 --> 00:03:17.852 Charles rides his bike home, which is great. 00:03:18.223 --> 00:03:19.678 I get to sit in that every day for 00:03:19.678 --> 00:03:21.330 about 45 minutes on the way home. 00:03:21.772 --> 00:03:23.664 The city layout and infrastructure was not prepared 00:03:23.664 --> 00:03:25.819 for the kind of growth that they've experienced. 00:03:26.165 --> 00:03:28.489 That results in the dreaded urban sprawl. 00:03:29.458 --> 00:03:31.612 But we don't actually even live here. 00:03:31.637 --> 00:03:33.445 Let's be honest about our code for a minute people. 00:03:34.054 --> 00:03:35.127 We live here. 00:03:37.761 --> 00:03:39.531 It's not a sprawling metroplex 00:03:39.531 --> 00:03:40.934 or a beautifully planned city. 00:03:40.934 --> 00:03:42.562 We live in a favela. 00:03:42.631 --> 00:03:45.307 A favela is a Brazilian slum, basically. 00:03:45.307 --> 00:03:46.902 It looks like cool though, right? 00:03:47.041 --> 00:03:51.116 It's the definition of a walkable city -- well, hikeable. 00:03:51.869 --> 00:03:53.494 Let's zoom in. 00:03:54.617 --> 00:03:57.835 A favela is a Brazilian shanty town made permanent. 00:03:58.382 --> 00:04:02.384 The structures require little skill to create and they 00:04:02.384 --> 00:04:05.830 pop up everywhere out of whatever materials can be found. 00:04:06.214 --> 00:04:08.102 The problem is these structures are 00:04:08.102 --> 00:04:10.350 difficult to grow, to maintain or protect. 00:04:10.898 --> 00:04:13.319 There's little police presence or fire presence, 00:04:13.465 --> 00:04:15.929 and safety and crime issues are pretty rampant. 00:04:17.244 --> 00:04:19.351 Forget architecture stuff, 00:04:19.353 --> 00:04:21.414 we're going to go in to a code favela, 00:04:21.866 --> 00:04:23.354 it will look familiar to you. 00:04:23.354 --> 00:04:24.929 You've probably had some that made you 00:04:24.929 --> 00:04:26.897 nearly go crazy trying to maintain it. 00:04:27.320 --> 00:04:29.244 I apologize in advance for making you look at 00:04:29.244 --> 00:04:31.773 this but I really need you to feel my pain. 00:04:34.020 --> 00:04:36.913 That favela is a manifestation of the ball of 00:04:36.913 --> 00:04:39.147 mud pattern, which is really easy to create. 00:04:39.229 --> 00:04:42.137 You just need to build something temporary, 00:04:42.137 --> 00:04:44.972 add to it, and then rely on it for your business. 00:04:45.241 --> 00:04:47.319 They're so easy to create that it's the dominant 00:04:47.319 --> 00:04:50.565 architecture pattern, I would contest, in software today. 00:04:51.680 --> 00:04:53.164 Let's talk about how this happens. 00:04:53.867 --> 00:04:55.213 Should be pretty easy right, 00:04:55.213 --> 00:04:56.679 you can probably make this happen this week. 00:04:58.765 --> 00:05:02.437 I need a show of hands. How many of you hate being 00:05:02.437 --> 00:05:04.494 asked to raise your hands in a talk? 00:05:05.684 --> 00:05:08.477 I should see no hands, that is insane. 00:05:09.523 --> 00:05:11.419 How many of the rest of you have a 00:05:11.419 --> 00:05:13.504 prototype that is shipped to production? 00:05:14.666 --> 00:05:16.351 Pretty good balance there. 00:05:20.445 --> 00:05:21.773 They say, "This is a two week feature, 00:05:21.773 --> 00:05:23.102 "let's ship this thing in two weeks." 00:05:23.373 --> 00:05:24.483 I don't believe in two week features, 00:05:24.483 --> 00:05:25.872 I don't think that's actually a thing. 00:05:26.337 --> 00:05:28.540 We do try to cram features in to two weeks and then make 00:05:28.540 --> 00:05:31.307 sacrifices to get them out the door, or we inherit code from 00:05:31.307 --> 00:05:34.118 less experienced developers and it has to ship. 00:05:34.809 --> 00:05:37.678 But mostly these shanty towns start as a quick prototype. 00:05:38.915 --> 00:05:40.790 Let's go ahead and build a shanty town. 00:05:41.417 --> 00:05:43.009 It starts off like pretty much any other. 00:05:44.492 --> 00:05:46.417 Let's say we're all working on Giffindor. 00:05:46.774 --> 00:05:48.727 It's a social network for animated gifs. 00:05:49.888 --> 00:05:52.138 The founder is a huge Harry Potter fan, cosplayer, 00:05:52.152 --> 00:05:54.618 the whole thing. Has the glasses, it's adorable. 00:05:54.667 --> 00:05:55.945 Personally I'm more a Hufflepuff, 00:05:55.945 --> 00:05:57.259 this is not my website though. 00:05:57.887 --> 00:06:00.399 It's a vanilla server-side app in Rails. 00:06:01.290 --> 00:06:04.680 One note on pronunciation. I'm going to stake a stand. 00:06:04.680 --> 00:06:07.227 I'm going to say that gif is pronounced like GitHub Gist. 00:06:09.178 --> 00:06:11.461 I do the same thing with JSON and [JAY-sin]. 00:06:11.961 --> 00:06:12.867 I like to make everybody mad. 00:06:12.867 --> 00:06:14.977 Mix tabs and spaces, people love me. 00:06:15.932 --> 00:06:16.617 Back to work. 00:06:17.510 --> 00:06:19.946 Let's just sprinkle in a little interactivity. 00:06:21.013 --> 00:06:22.392 Let's start with sprinkles, they're fun, 00:06:22.392 --> 00:06:23.713 sprinkles are fun, yay! 00:06:25.523 --> 00:06:28.445 Your boss calls. She says, "We want a better experience 00:06:28.445 --> 00:06:30.193 "on the site. Our users demand it. They should not 00:06:30.193 --> 00:06:32.445 "have to go through a page refresh all the way 00:06:32.445 --> 00:06:34.696 "to the new page to submit a new animated gif." 00:06:36.148 --> 00:06:37.320 You look at your Javascript file. 00:06:38.950 --> 00:06:41.511 Nothing there, undaunted you march forward. 00:06:42.117 --> 00:06:44.665 Easy right? Just make a little HTML form 00:06:44.665 --> 00:06:46.941 on the page with show hide, all done. 00:06:48.196 --> 00:06:51.037 That worked, except it submits and 00:06:51.037 --> 00:06:52.871 does a full page refresh on submit. 00:06:52.871 --> 00:06:54.070 "Can you do that by AJAX, 00:06:54.070 --> 00:06:55.754 "it's kind of irritating to our users?" 00:06:56.195 --> 00:06:57.896 All right, that's what AJAX is for, right? 00:06:57.946 --> 00:06:59.973 We submit this thing via AJAX. 00:07:00.867 --> 00:07:03.103 That seems to work, all right. 00:07:03.510 --> 00:07:05.792 But now you actually have to add that new POST 00:07:05.792 --> 00:07:08.292 to the list of POSTs that are on that page. 00:07:08.946 --> 00:07:09.853 All right, no problem. 00:07:10.445 --> 00:07:12.274 Okay, a little bit of a problem. 00:07:13.087 --> 00:07:16.139 We're starting to duplicate some DOM code here in your 00:07:16.139 --> 00:07:18.877 Javascript so you get to edit stuff in two places. 00:07:19.304 --> 00:07:23.623 A little duplication. We know, we don't de-duplicate first. 00:07:24.837 --> 00:07:26.620 You're agile so you agile that code right 00:07:26.620 --> 00:07:29.277 in there until this whole thing is agile! (laughter and applause) 00:07:29.861 --> 00:07:32.649 By the way that's a trademark of Cloudgineering Inc. 00:07:32.663 --> 00:07:35.616 so do not use that without written permission. 00:07:37.200 --> 00:07:39.792 So this sprinkle is starting to turn in to a little more 00:07:39.792 --> 00:07:42.633 of a rain shower, a little bit of a steady rain. 00:07:42.633 --> 00:07:45.128 But cheer up Keanu, we shipped some software, right? 00:07:46.382 --> 00:07:49.415 Okay, sport. The product manager, who tends to look 00:07:49.415 --> 00:07:52.133 like Fred MacMurray for some reason, is really happy. 00:07:52.648 --> 00:07:55.416 He has more ideas. He wants users to be able to click 00:07:55.416 --> 00:07:57.492 a cancel button so that they zero out the form, 00:07:57.492 --> 00:07:59.399 because if you open it it's just stuck there. 00:08:00.648 --> 00:08:02.798 Dutifully you implement the cancel button 00:08:02.798 --> 00:08:04.706 and zero out the form with jQuery. 00:08:04.933 --> 00:08:07.852 Awesome, except now users are hitting submit on 00:08:07.852 --> 00:08:10.134 empty and invalid forms, so we need some sort of 00:08:10.134 --> 00:08:12.542 client-side validation to prevent that from happening. 00:08:12.696 --> 00:08:14.292 It shouldn't be too hard to tell if 00:08:14.292 --> 00:08:17.091 somebody has attached an animated gif link. 00:08:19.030 --> 00:08:21.956 It wasn't super, super easy but it was relatively 00:08:21.956 --> 00:08:24.294 straight forward. We disable the submit button unless 00:08:24.294 --> 00:08:26.726 it's valid and show messages with jQuery. 00:08:27.292 --> 00:08:29.008 This is starting to look a little weird, right? 00:08:29.031 --> 00:08:30.772 It's starting to really come down. 00:08:32.306 --> 00:08:33.580 Poor Al Roker. 00:08:34.789 --> 00:08:36.697 Your CEO comes in to congratulate you 00:08:36.697 --> 00:08:38.260 on all the great work you've done. 00:08:38.260 --> 00:08:40.712 You've really shipped a lot of code and agiled everything 00:08:40.712 --> 00:08:43.821 and you just need a couple more enhancements. 00:08:44.058 --> 00:08:46.933 Let's add an inline preview for that image so users know 00:08:46.933 --> 00:08:49.254 what they're about to post before they post it, 00:08:49.297 --> 00:08:51.765 and a little character count that doesn't ding them 00:08:51.765 --> 00:08:53.977 for long urls. We want a smart character count. 00:08:55.602 --> 00:08:57.292 That's working but actually broke a couple of 00:08:57.292 --> 00:08:59.807 other things about the state of this form. 00:09:00.011 --> 00:09:03.483 We do some double checking and enable or disable submit. 00:09:04.697 --> 00:09:06.730 Now you're caught between these two worlds. 00:09:06.730 --> 00:09:09.523 You want to craft code that you can be proud of and that 00:09:09.635 --> 00:09:12.525 lets you feel good about the things that you do, 00:09:12.624 --> 00:09:14.481 but you also want to be able to ship stuff. 00:09:14.481 --> 00:09:16.692 Your business needs you to move fast and break things. 00:09:16.702 --> 00:09:20.399 You need to get stuff done, GSD. Craftsmanship, ship it. 00:09:20.516 --> 00:09:22.300 I say craftmanship it. 00:09:22.377 --> 00:09:24.777 (laughter) 00:09:24.777 --> 00:09:28.392 (hesitant applause) 00:09:29.484 --> 00:09:31.256 It's a good thing you're a cloudgineer and you 00:09:31.256 --> 00:09:33.370 can straddle these two worlds just perfectly. 00:09:34.181 --> 00:09:36.820 Look at all this code that we've craftsmanshipped. 00:09:38.245 --> 00:09:40.945 Sandy Metz talked yesterday about code shape 00:09:40.945 --> 00:09:42.787 and the squint test as an indicator. 00:09:42.787 --> 00:09:45.630 When I squint this code has a shape and 00:09:45.630 --> 00:09:47.656 that shape is a sack of hot garbage. 00:09:47.656 --> 00:09:50.102 (laughter) 00:09:50.102 --> 00:09:51.849 I don't know if Chicago has this but in Manhattan 00:09:51.849 --> 00:09:54.119 in the summer time you get this nice smell 00:09:54.119 --> 00:09:56.115 wafting off of the hot garbage, it's great. 00:09:56.381 --> 00:09:57.843 That's kind of how it feels. 00:09:58.277 --> 00:10:03.035 Here we are, a total tsunami of entangled jQuery code. 00:10:03.035 --> 00:10:05.675 (laughter) 00:10:05.675 --> 00:10:07.775 Let's ship a feature against that. 00:10:10.476 --> 00:10:13.256 Please, it's really important! 00:10:14.204 --> 00:10:16.411 Your CEO is now putty in your hands, 00:10:16.411 --> 00:10:18.819 you are a superstar developer and the expectation 00:10:18.819 --> 00:10:21.374 is now that you just shipped so fast. 00:10:21.374 --> 00:10:23.809 And a light button, let's do it. 00:10:23.901 --> 00:10:27.005 Here's the thing. I was going to implement this in jQuery, 00:10:27.323 --> 00:10:28.958 I was going to do it but there was already so 00:10:28.958 --> 00:10:31.071 much double checking and interwoven states that 00:10:31.071 --> 00:10:34.146 I physically couldn't without getting really ill. 00:10:34.680 --> 00:10:36.583 The thought of touching this code made me want 00:10:36.583 --> 00:10:38.275 to quit writing the talk and just be like, 00:10:38.275 --> 00:10:40.147 "You know what RailsConf, thanks anyway." 00:10:41.283 --> 00:10:43.107 Now what, what do we do? 00:10:43.380 --> 00:10:46.054 Actually Brian Foote has prescriptions for 00:10:46.054 --> 00:10:47.286 dealing with the ball of mud pattern, 00:10:47.286 --> 00:10:48.916 and it's not always what you think. 00:10:48.916 --> 00:10:51.190 You don't necessarily dive right into a refactor. 00:10:51.450 --> 00:10:53.470 Addressing a ball of mud is pretty difficult. 00:10:53.685 --> 00:10:55.386 We can sweep it all under the rug, 00:10:55.386 --> 00:10:57.033 or put it inside of a black box. 00:10:57.586 --> 00:10:58.978 You can reconstruct it, 00:10:58.978 --> 00:11:02.672 tear the whole thing down and raze it and rebuild it. 00:11:02.786 --> 00:11:04.036 You can renovate block-by-block, 00:11:04.036 --> 00:11:05.768 which he calls keeping it working, 00:11:05.914 --> 00:11:08.517 or you can quit you job, which in some cases, 00:11:08.517 --> 00:11:10.797 sometimes it's the thing to do. 00:11:11.637 --> 00:11:13.459 Black box is fine if you know you're never 00:11:13.459 --> 00:11:15.150 going to have to touch that code again. 00:11:15.150 --> 00:11:16.686 If it's some complicated math equation or 00:11:16.686 --> 00:11:18.156 something I've seen that done, where you 00:11:18.156 --> 00:11:20.668 just hide it in the closet and that's fine. 00:11:21.252 --> 00:11:23.976 A rewrite is a great way to learn really amazingly 00:11:23.976 --> 00:11:27.007 hidden lessons about your business logic. 00:11:27.133 --> 00:11:29.240 Things that are encoded in very strange places. 00:11:29.416 --> 00:11:31.009 It's a really great way to make something that 00:11:31.009 --> 00:11:33.253 sounds like it takes two weeks take six months. 00:11:35.589 --> 00:11:38.408 I feel like you always discover that hidden 00:11:38.408 --> 00:11:40.970 business logic so let's talk about a refactor. 00:11:41.511 --> 00:11:42.972 Why would we do that? 00:11:43.697 --> 00:11:45.358 We decided that refactor is probably the right 00:11:45.358 --> 00:11:46.761 thing to do because the feature has to be 00:11:46.761 --> 00:11:49.193 maintained but it's now too expensive to manage. 00:11:49.331 --> 00:11:51.240 Users are starting to actually have a bad time with 00:11:51.240 --> 00:11:53.216 it because the longer they stay on the page the 00:11:53.216 --> 00:11:55.457 more likely they are to have problems with it. 00:11:56.417 --> 00:11:58.958 And more importantly to me personally is 00:11:58.958 --> 00:12:00.807 that you are tossing and turning all night. 00:12:00.807 --> 00:12:02.662 You cannot sleep because you're dreaming about the JIRA 00:12:02.662 --> 00:12:04.552 tickets that are waiting for you in the morning. 00:12:04.552 --> 00:12:06.396 Why are we still using JIRA, why is that a thing?! 00:12:06.396 --> 00:12:08.085 Okay, anyway, separate deal. 00:12:09.922 --> 00:12:12.584 You think about your frustrated users, your gut is 00:12:12.584 --> 00:12:15.111 telling you to fix it and your gut is totally right. 00:12:16.446 --> 00:12:17.977 You have two paths out of here. 00:12:17.977 --> 00:12:21.038 I think the person in this room, super smart guy, is like, 00:12:21.038 --> 00:12:24.769 "Why don't you refactor this to smart Javascript objects?" 00:12:25.353 --> 00:12:29.486 He's largely right. That's an ideomatic way to dig out of this. 00:12:29.634 --> 00:12:32.111 He also asked me if I did that as a strawman 00:12:32.111 --> 00:12:34.663 of how to build really terrible jQuery code. 00:12:34.949 --> 00:12:39.256 I was like, "Yeees. I was not doing my best." 00:12:40.675 --> 00:12:42.241 The other option is to use a framework 00:12:42.241 --> 00:12:44.697 to abstract away the DOM and handle data. 00:12:46.059 --> 00:12:47.684 Our goal is to get the heck out of 00:12:47.684 --> 00:12:49.308 the DOM as fast as humanly possible. 00:12:50.162 --> 00:12:52.063 That's our biggest pain point right now. 00:12:52.388 --> 00:12:54.203 For me I'll choose a framework. 00:12:54.209 --> 00:12:55.478 The framework will manage the DOM and 00:12:55.478 --> 00:12:57.101 we'll just manage the underlying data. 00:12:58.401 --> 00:13:01.366 All we need to do now is five steps to get out. 00:13:02.634 --> 00:13:04.983 These steps will probably apply for people that 00:13:04.983 --> 00:13:08.399 use plain Javascript and don't use a framework, 00:13:08.399 --> 00:13:10.306 or any framework that you choose. 00:13:10.306 --> 00:13:12.162 It's just nice to build up against one, 00:13:12.202 --> 00:13:13.662 personally I certainly prefer it. 00:13:14.679 --> 00:13:16.834 On our blog we'll talk more about why 00:13:16.834 --> 00:13:18.788 we choose Ember and why we like it, 00:13:18.788 --> 00:13:21.197 and you heard Charles mention earlier if you were here, 00:13:21.197 --> 00:13:23.303 about why we like Ember's model layer. 00:13:23.431 --> 00:13:25.912 I feel like it's a really strong model layer for 00:13:25.912 --> 00:13:28.038 the case that we're trying to accomplish now. 00:13:28.038 --> 00:13:29.588 It has really great bindings and managed state, 00:13:29.588 --> 00:13:31.099 and it's got a great drop in component 00:13:31.099 --> 00:13:32.770 library to tie it all together. 00:13:33.371 --> 00:13:36.955 Step one, let's rap it. Rap it, rap it, rap it, wrap it. 00:13:40.313 --> 00:13:42.289 A little sidetrack, a lot of people don't realize 00:13:42.289 --> 00:13:44.381 that you can sprinkle Ember into an app. 00:13:44.556 --> 00:13:47.116 A lot of people think that Ember only works if you want to 00:13:47.116 --> 00:13:49.684 start an app from scratch and build up from the ground up, 00:13:49.684 --> 00:13:52.617 from floor zero all the way to the top, but you can actually 00:13:52.617 --> 00:13:54.479 apply it to a lot of codebases and it's really 00:13:54.479 --> 00:13:57.431 great for refactoring existing codebases toward it. 00:13:58.051 --> 00:14:01.626 That's just these three steps right here. 00:14:01.825 --> 00:14:04.312 At The Frontside we do that pretty often where 00:14:04.312 --> 00:14:07.668 we take an existing Rails application and move 00:14:07.668 --> 00:14:11.161 it towards Ember, but it's actually not that hard. 00:14:11.201 --> 00:14:13.199 First things first it's time for some justice. 00:14:13.199 --> 00:14:15.619 We're going to put that terrible code in code jail. 00:14:15.619 --> 00:14:18.508 That code jail is this initLegacyCode function. 00:14:18.508 --> 00:14:21.778 We're going to create an Ember component, we're going to 00:14:21.778 --> 00:14:25.179 put the stuff in initLegacyCode, which is not a special name, 00:14:25.179 --> 00:14:28.635 I just chose it to tell me that this is the jail. 00:14:28.635 --> 00:14:31.542 It bootstraps the old code inside the component. 00:14:31.542 --> 00:14:33.675 We do not alter that code at all. 00:14:33.977 --> 00:14:37.288 Also we move the HTML in to a handlebars 00:14:37.288 --> 00:14:39.461 template associated with this component. 00:14:39.743 --> 00:14:42.028 No structure of that HTML actually changes, 00:14:42.384 --> 00:14:44.038 we're just isolating. 00:14:44.918 --> 00:14:48.366 Then we can sprinkle. Now we use jQuery to stuff all of 00:14:48.366 --> 00:14:51.677 this old stuff that we had before back in to the DOM. 00:14:53.822 --> 00:14:56.525 Another thing Sandy said yesterday that I hope 00:14:56.525 --> 00:14:59.163 it's self evident, it's certainly made itself self evident 00:14:59.163 --> 00:15:02.529 to me over the course of the last year or two doing this, 00:15:02.529 --> 00:15:04.425 that you have to test it. 00:15:04.713 --> 00:15:08.575 If you do not test your code a refactor is 00:15:08.575 --> 00:15:11.648 essentially impossible, I cannot imagine trying to do it. 00:15:11.648 --> 00:15:13.820 I was not a big testing advocate earlier. 00:15:13.820 --> 00:15:16.930 I was very skeptical, let's say, about testing. 00:15:16.930 --> 00:15:19.641 I was raised by cowboy coders in my first 00:15:19.641 --> 00:15:22.065 place when I was learning to program. 00:15:22.390 --> 00:15:24.821 But we're going to do it and we're going to see that it's 00:15:24.821 --> 00:15:27.492 actually not that hard to actually test the thing itself. 00:15:27.835 --> 00:15:30.257 We're going to test that it shows up and it passes. 00:15:33.684 --> 00:15:35.418 I'm doing a little bit of a hand wave 00:15:35.418 --> 00:15:38.148 here over Javascript testing setup. 00:15:39.181 --> 00:15:43.435 Javascript test setup story for getting Ember applications 00:15:43.435 --> 00:15:47.016 bootstrapped in Rails can be a little challenging. 00:15:47.016 --> 00:15:48.985 There's a growing body of knowledge about it. 00:15:48.985 --> 00:15:50.991 I want to give you guys a quick note on that. 00:15:51.011 --> 00:15:52.835 On its own, Javascript testing is pretty easy 00:15:52.835 --> 00:15:55.005 but when you add in frameworks and tie it to Rails, 00:15:55.021 --> 00:15:56.478 add in the asset pipeline, 00:15:56.478 --> 00:15:58.010 things can get a little complicated. 00:15:58.167 --> 00:15:59.617 It's a little bit of a wild west, 00:15:59.913 --> 00:16:01.085 there's a lot of choices out there. 00:16:01.335 --> 00:16:02.790 There's a little bit of paralysis of choice I think. 00:16:03.211 --> 00:16:05.400 It's really wide open, but not like home on the 00:16:05.400 --> 00:16:09.332 range wide open, more like this kind of wild west. 00:16:10.362 --> 00:16:13.930 It can lead to that, you look at the thing of, 00:16:13.930 --> 00:16:15.663 "I don't know what brand of toothpaste I want, 00:16:15.663 --> 00:16:17.206 "I just want some toothpaste." 00:16:17.538 --> 00:16:19.431 There's not really a truly accepted happy 00:16:19.431 --> 00:16:21.355 path just yet but it is getting better. 00:16:21.992 --> 00:16:23.433 Things are maturing, we're building schools, 00:16:23.433 --> 00:16:25.004 we're building hospitals still. 00:16:25.773 --> 00:16:27.897 There's a lot of a need for libraries and blog 00:16:27.897 --> 00:16:30.811 posts and people finding these happy paths. 00:16:30.811 --> 00:16:33.080 Taking aside for 15 minutes, there are screen casts 00:16:33.080 --> 00:16:34.836 being released right now, there's a thing called 00:16:34.836 --> 00:16:37.806 Ember Sparks where he's teaching people how to 00:16:37.806 --> 00:16:40.414 set up and bootstrap your application environment. 00:16:40.414 --> 00:16:43.414 We're all still figuring this out there, so be prepared 00:16:43.414 --> 00:16:47.006 for a little bit of rough take off on this still. 00:16:48.322 --> 00:16:50.682 Another thing is testing AJAX can feel a little 00:16:50.682 --> 00:16:52.214 intimidating when you're trying to test Javascript 00:16:52.214 --> 00:16:53.491 but it's actually pretty simple. 00:16:53.491 --> 00:16:55.308 There are multiple libraries to do this kind of thing 00:16:55.308 --> 00:16:56.914 I like ic-ajax. 00:16:59.995 --> 00:17:03.663 It intercepts AJAX calls and allows you to inject fixtures in. 00:17:04.760 --> 00:17:09.314 Here we're going to test each path through the experience. 00:17:09.444 --> 00:17:11.085 In this one we're testing that clicking 00:17:11.085 --> 00:17:13.009 submit shows a success message. 00:17:13.461 --> 00:17:15.396 We just want to go through and verify that all the 00:17:15.396 --> 00:17:18.242 things that the code says it does it's actually doing. 00:17:19.237 --> 00:17:21.056 We're not changing any code, 00:17:21.056 --> 00:17:23.423 we're just wrapping it in test existing. 00:17:24.528 --> 00:17:25.744 And that passes. 00:17:26.325 --> 00:17:28.855 Okay. At this point we repeat for each path 00:17:28.855 --> 00:17:31.066 to create an integration test for the entire 00:17:31.066 --> 00:17:33.676 application stubbed at the API level. 00:17:33.965 --> 00:17:37.164 This took several hours but it's really important. 00:17:37.164 --> 00:17:38.514 As I said if you don't have a test harness 00:17:38.514 --> 00:17:40.148 I do not know how you can refactor. 00:17:40.464 --> 00:17:42.946 Maybe if somebody has another answer we can discuss it, 00:17:42.946 --> 00:17:45.481 because testing is not my favorite thing in the world. 00:17:46.867 --> 00:17:48.867 We can now move forward with some confidence. 00:17:48.867 --> 00:17:51.118 Go ahead and take yourself a victory lap, you earned it. 00:17:51.118 --> 00:17:53.051 This is, however, just the start. 00:17:54.483 --> 00:17:56.711 Step three is to identify models. 00:17:56.711 --> 00:17:59.743 You have this blob of code, how do you find models in here? 00:17:59.743 --> 00:18:02.167 Your server MVC might give you some hints. 00:18:02.712 --> 00:18:05.609 I don't believe that your models will map one to one, 00:18:05.609 --> 00:18:07.885 but it's a really great place to start. 00:18:08.986 --> 00:18:12.290 In this one we actually get to start driving with the tests. 00:18:12.635 --> 00:18:14.961 Sometimes I test drive, sometimes I don't, 00:18:14.961 --> 00:18:19.033 I'm not an expert at either style, but I do think that 00:18:19.033 --> 00:18:21.979 in this case it was pretty good to say, "I know that I 00:18:21.979 --> 00:18:23.648 "have a model and I know part of what a model is 00:18:23.648 --> 00:18:26.949 "going to parse out an animated gif url 00:18:26.949 --> 00:18:29.164 "and tell me whether it is one or is not one." 00:18:30.605 --> 00:18:33.640 With no code that thing should fail, and it does. 00:18:34.652 --> 00:18:36.748 Now let's extract it. 00:18:36.748 --> 00:18:39.461 We can actually extract some of that logic to a model. 00:18:40.308 --> 00:18:43.230 And we can extract the animated gif link from 00:18:43.230 --> 00:18:45.648 the POST body and give it a property here. 00:18:45.648 --> 00:18:47.991 This is called a computed property where you see parsedUrl. 00:18:48.297 --> 00:18:50.118 It does some functiony stuff and then it has a little 00:18:50.118 --> 00:18:52.165 declaration at the end that says property body. 00:18:52.298 --> 00:18:54.686 It means that we're going to depend on the body, 00:18:54.686 --> 00:18:57.727 which is the blob of data that somebody just types in, 00:18:57.727 --> 00:18:59.921 the text that they type in. 00:19:00.874 --> 00:19:02.387 At any time a person changes that, 00:19:02.387 --> 00:19:03.729 any time that changes it's going to observe and 00:19:03.729 --> 00:19:06.400 update this parsedUrl property on this object. 00:19:08.540 --> 00:19:13.183 Now those unit tests will pass and we can start turning that 00:19:13.183 --> 00:19:17.521 static content into the dynamic content using handlebars. 00:19:18.597 --> 00:19:21.246 This lets us kill some code, that's pretty awesome. 00:19:21.579 --> 00:19:24.888 This should get the older acceptance test passing again. 00:19:24.888 --> 00:19:28.820 It is the coolest feeling in the world to write some tests, 00:19:28.820 --> 00:19:31.479 take some code, scrub some garbage out of it, 00:19:31.479 --> 00:19:33.586 do something really dangerous feeling, 00:19:33.586 --> 00:19:35.337 like jump off the cliff and know, when you rerun 00:19:35.337 --> 00:19:37.586 those tests and they start passing again, 00:19:37.586 --> 00:19:39.236 and you start getting green again after a refactor, 00:19:39.236 --> 00:19:40.700 it's really fun. 00:19:41.311 --> 00:19:42.842 In this case we didn't do that much, 00:19:42.842 --> 00:19:44.227 we didn't have to write that much code because 00:19:44.227 --> 00:19:46.058 we let the framework carry our matched luggage 00:19:46.058 --> 00:19:48.428 for it which we cannot live without. 00:19:49.112 --> 00:19:50.815 The models hold onto your data, 00:19:50.815 --> 00:19:53.826 they keep it up to date and the changes in the DOM are 00:19:53.826 --> 00:19:56.790 just going to automatically propagate out of that. 00:19:58.231 --> 00:20:00.415 Now we're going to lean even harder into the framework. 00:20:01.029 --> 00:20:03.482 It actually is sort of the fun part, identifying the 00:20:03.482 --> 00:20:05.431 states is more fun than identifying models, I think, 00:20:05.431 --> 00:20:06.696 because we get to go back through the 00:20:06.696 --> 00:20:08.337 app and pick out what these states are. 00:20:09.164 --> 00:20:11.197 In this little widget the first state is 00:20:11.197 --> 00:20:12.949 a blank state, a initial state where the 00:20:12.949 --> 00:20:14.962 button is just visible and nothing else is. 00:20:15.561 --> 00:20:17.149 When we click it the button goes away and 00:20:17.149 --> 00:20:19.086 the thing is in a ready-to-save state. 00:20:20.169 --> 00:20:21.916 While data is in flight we're going to disable 00:20:21.916 --> 00:20:24.087 the post button, leave everything else the same. 00:20:25.061 --> 00:20:26.462 On an error state we're going to leave 00:20:26.462 --> 00:20:28.915 the text intact but display a message. 00:20:30.747 --> 00:20:32.547 On success we're going to display a 00:20:32.547 --> 00:20:34.319 success message and hide the form. 00:20:34.513 --> 00:20:37.162 After five seconds we want it to reset to that initial state. 00:20:37.262 --> 00:20:38.854 That's kind of the business logic that we wanted 00:20:38.854 --> 00:20:41.884 in the first place but we incrementally built it. 00:20:41.884 --> 00:20:44.700 That's an okay way to find out what you want but 00:20:44.700 --> 00:20:47.081 not a great way to ship to production, as we found. 00:20:47.994 --> 00:20:49.713 The component starts in this initial state. 00:20:49.793 --> 00:20:52.408 We bind that state to a class on the component's DOM, 00:20:53.154 --> 00:20:55.574 and then we'll use that later to let CSS 00:20:55.574 --> 00:20:57.693 manage what is shown and what is hidden. 00:20:58.309 --> 00:21:00.517 We want the DOM to just be a representation of the 00:21:00.517 --> 00:21:03.338 state of the app. The DOM is just there to represent 00:21:03.338 --> 00:21:05.269 the app's state at any given time. 00:21:05.374 --> 00:21:07.687 It's kind of almost read-only. 00:21:08.106 --> 00:21:10.186 Now instead of managing the DOM with jQuery 00:21:10.186 --> 00:21:11.416 we're going to have buttons fire off 00:21:11.416 --> 00:21:13.087 actions that just push the state around. 00:21:13.479 --> 00:21:14.764 "You go here, you go here," 00:21:14.764 --> 00:21:18.574 they're like the train conductors in a Japanese train station. 00:21:19.306 --> 00:21:21.087 It's kind of a lazy developer's state 00:21:21.087 --> 00:21:22.510 machine but it's going to do for now. 00:21:23.894 --> 00:21:25.328 Step four, that's done. 00:21:25.328 --> 00:21:26.763 That was all the code we needed for state. 00:21:27.009 --> 00:21:29.634 Step four is to break up the remaining code left in code jail. 00:21:29.810 --> 00:21:31.868 The states and model are in place and are tested, 00:21:31.868 --> 00:21:33.598 but there's a couple of ugly things left. 00:21:33.731 --> 00:21:36.774 Let's look at it. Code jail is not empty. 00:21:36.774 --> 00:21:38.790 The legacy code still reaches outside the 00:21:38.790 --> 00:21:41.756 component to delete things in a wonky way. 00:21:42.795 --> 00:21:45.603 And, heh heh, hi, how are you. 00:21:46.809 --> 00:21:48.759 I want to rub your nose in this code, 00:21:48.825 --> 00:21:50.087 even though I'm the one that wrote it. 00:21:51.510 --> 00:21:53.412 What could possibly go wrong here, right? 00:21:54.753 --> 00:21:58.951 This POST is pretty scary. It's painful to modify, 00:21:58.951 --> 00:22:01.732 it invites pain for the user but listing POST 00:22:01.732 --> 00:22:03.827 is outside the responsibility of this component 00:22:03.827 --> 00:22:05.969 we've created so what can we do about it? 00:22:07.757 --> 00:22:09.213 Actually we have a pattern that we've already laid out. 00:22:09.213 --> 00:22:10.369 Let's create another component and 00:22:10.369 --> 00:22:12.041 sprinkle it in for listing those POSTs. 00:22:13.141 --> 00:22:15.119 Another quick detour in to Ember Data. 00:22:15.311 --> 00:22:16.778 At this point I have a choice to make. 00:22:16.778 --> 00:22:20.462 Do I want to make sharing this information with you more 00:22:20.462 --> 00:22:22.900 complicated by talking about Ember Data and I think I do, 00:22:22.900 --> 00:22:24.792 it actually made the next steps much easier, 00:22:25.064 --> 00:22:27.672 and this detour actually took me about 20 minutes to 00:22:27.672 --> 00:22:30.073 replace the model with an Ember Data model. 00:22:30.281 --> 00:22:33.260 Ember data is basically a wrapper that talks to AJAX 00:22:33.260 --> 00:22:36.510 for you and converts to an Ember model for you. 00:22:38.077 --> 00:22:39.857 It buys us lots of good things. 00:22:39.964 --> 00:22:41.791 Basically took just a few minutes to do. 00:22:41.904 --> 00:22:46.369 That's it, we just declare it as a model on Ember Data. 00:22:47.685 --> 00:22:51.119 I like to wire in an ic-ajax, just like we did before, 00:22:51.119 --> 00:22:53.901 to Ember Data and this is all the work that it takes to do. 00:22:54.166 --> 00:22:56.198 Fixtures will still work as written. 00:22:56.252 --> 00:22:58.887 This was all it took to get the tests passing again. 00:23:00.264 --> 00:23:02.041 That's pretty much it for the list component. 00:23:02.041 --> 00:23:03.666 As you can see I have a delete function, 00:23:03.666 --> 00:23:05.574 a place to reference the list, that's it. 00:23:05.574 --> 00:23:08.901 It has a list of those posts and a way to delete one of them. 00:23:09.308 --> 00:23:11.885 All I'm doing is destroying a model record. 00:23:13.505 --> 00:23:15.282 The second set of tests here is pretty 00:23:15.282 --> 00:23:17.684 much going to follow the first. This test shows 00:23:17.684 --> 00:23:20.808 that the animated gifs show up as expected, 00:23:21.041 --> 00:23:23.495 and from here we can drive out the delete functionality. 00:23:24.245 --> 00:23:27.308 We have a second template to replace the server-side markup 00:23:28.310 --> 00:23:30.527 and then we sprinkle it in just like the first one. 00:23:30.605 --> 00:23:32.972 We say, "Hey, jQuery, take this component and stuff it in to 00:23:32.972 --> 00:23:35.432 "the DOM for me where that list of posts used to be," 00:23:35.688 --> 00:23:37.494 and Ember is going to show that for us now. 00:23:37.513 --> 00:23:39.113 That's interesting, we have two components. 00:23:39.113 --> 00:23:40.808 How are they talking to each other? 00:23:41.063 --> 00:23:43.309 Well they both react to changes to the underlying data. 00:23:43.309 --> 00:23:46.059 There's a pool underneath that is the 00:23:46.059 --> 00:23:47.885 same shared data set but the components 00:23:47.885 --> 00:23:49.766 are completely isolated from one another. 00:23:49.766 --> 00:23:51.728 They can only communicate by altering 00:23:51.728 --> 00:23:53.497 that pool of underlying data. 00:23:54.532 --> 00:23:56.588 Changes in one place can affect the other. 00:23:57.542 --> 00:23:59.870 There's a lot of boilerplate code we did not write here. 00:23:59.870 --> 00:24:01.261 We just trust that the data layer is going to do 00:24:01.261 --> 00:24:03.552 its job and the DOM will represent it properly. 00:24:05.177 --> 00:24:07.779 One thing that happened though is because 00:24:07.779 --> 00:24:11.214 we're not doing stuff with jQuery UI animation 00:24:11.214 --> 00:24:13.264 stuff any more we lost show hide functionality, 00:24:13.264 --> 00:24:14.555 so let's put that back. 00:24:15.091 --> 00:24:16.636 We're going to use CSS transitions 00:24:16.636 --> 00:24:17.854 which buys a lot of benefits, 00:24:17.854 --> 00:24:21.198 including hardware acceleration on more modern browsers. 00:24:22.245 --> 00:24:25.366 Remember how we bound class name to form state earlier? 00:24:25.563 --> 00:24:28.016 We said there was a thing there that says form 00:24:28.016 --> 00:24:31.291 state is bound to the class name for this component. 00:24:31.373 --> 00:24:33.589 Now we get these classes for free automatically, 00:24:33.716 --> 00:24:35.015 Ember is going to stuff that in to our 00:24:35.015 --> 00:24:37.312 component every time the state changes. 00:24:37.312 --> 00:24:39.774 It pushes the state, it changes the name of the class. 00:24:40.199 --> 00:24:41.930 I like to start by creating placeholders 00:24:41.930 --> 00:24:46.340 for the various states in a given component, 00:24:47.436 --> 00:24:49.964 and then put different behaviors under those states. 00:24:50.171 --> 00:24:52.356 In this you can see it almost tells a story. 00:24:52.453 --> 00:24:54.327 We start an initial state with a height of 00:24:54.327 --> 00:24:56.464 zero px and an opacity of zero. 00:25:02.961 --> 00:25:06.063 Then once it's in another state it actually expands. 00:25:06.434 --> 00:25:09.027 Everything except initial it will transition to that state. 00:25:09.671 --> 00:25:11.174 We transition open to visible 00:25:11.174 --> 00:25:14.542 with a 200 millisecond delay and a ... 00:25:16.140 --> 00:25:18.504 You know what, I'm just going to show it to you. 00:25:18.504 --> 00:25:21.167 It's not great to try to explain how CSS animations work. 00:25:22.172 --> 00:25:23.120 Let's do that. 00:25:31.465 --> 00:25:33.044 I think I need to make that window smaller. 00:25:35.939 --> 00:25:37.652 That's great. Thanks Obama. 00:25:41.882 --> 00:25:44.737 We're going to submit and now it expands. 00:25:44.737 --> 00:25:47.859 Here we're in a validation error state. 00:25:50.809 --> 00:25:52.507 We have the gif preview. 00:25:52.530 --> 00:25:54.373 We have zero characters because that smart preview is 00:25:54.373 --> 00:25:57.188 telling us that we're not using up any characters. 00:26:00.791 --> 00:26:02.766 And we'll post it. 00:26:03.747 --> 00:26:05.676 Oh, I just got trolled by chrome caching. 00:26:08.970 --> 00:26:13.800 This one is just great. Julie Andrews is so awesome. 00:26:18.030 --> 00:26:20.402 I have many of these that I really love very much. 00:26:21.844 --> 00:26:23.547 Instead of doing that all day maybe 00:26:23.547 --> 00:26:25.404 we should go back to the talk. 00:26:26.877 --> 00:26:28.152 What we're not doing is we're not 00:26:28.152 --> 00:26:29.878 manipulating the DOM directly. 00:26:29.892 --> 00:26:32.120 If we want our tests can actually relax about the DOM 00:26:32.120 --> 00:26:35.224 a little bit, we don't need to necessarily test the framework. 00:26:35.835 --> 00:26:38.460 What we can focus on is application logic. 00:26:38.574 --> 00:26:40.894 We can still integration test if we want 00:26:42.173 --> 00:26:44.292 but let's look back and see what we've done so far. 00:26:45.076 --> 00:26:48.554 There's some old code right here. 00:26:48.554 --> 00:26:50.631 Let's see if you can locate the business logic in here. 00:26:52.786 --> 00:26:54.373 Right? You can't. 00:26:54.373 --> 00:26:56.261 That's why I'm introducing a powerful 00:26:56.261 --> 00:26:59.145 encryption algorithm called jQCS, 512-bit. 00:26:59.597 --> 00:27:01.185 It scatters your business logic across 00:27:01.185 --> 00:27:03.043 hundreds of lines of jQuery code. 00:27:04.506 --> 00:27:06.214 You can stop worrying about whether hackers 00:27:06.214 --> 00:27:07.918 are going to access your business logic in your 00:27:07.918 --> 00:27:10.637 front end because even your programmers can't. 00:27:10.637 --> 00:27:11.976 (laughter) 00:27:11.976 --> 00:27:13.523 That's cloudgineering folks. 00:27:14.814 --> 00:27:16.175 Also a trademark. 00:27:17.262 --> 00:27:19.464 That turns out not to be such a super hot idea. 00:27:20.556 --> 00:27:22.919 We've now refactored this into a place where 00:27:22.919 --> 00:27:25.141 we've moved that encrypted logic and exposed 00:27:25.141 --> 00:27:27.509 it via computed properties, states and models. 00:27:27.739 --> 00:27:29.701 The business logic is actually front and center now. 00:27:30.120 --> 00:27:32.294 We've got from this sack of hot garbage to a 00:27:32.294 --> 00:27:34.832 tested and documented reliable implementation. 00:27:34.832 --> 00:27:37.996 It's not perfect but now it begs to be extended and reused. 00:27:39.798 --> 00:27:41.917 From here what happens next is really up to you. 00:27:43.273 --> 00:27:45.747 From here, most of the rendering that's 00:27:45.747 --> 00:27:47.635 happening on the page is being done by Ember. 00:27:47.715 --> 00:27:49.606 If you want to replace it and get all the benefits of 00:27:49.606 --> 00:27:52.027 having a router underneath your app, great, go nuts. 00:27:52.331 --> 00:27:56.279 You can actually now take application handlebars and 00:27:56.279 --> 00:27:58.715 have it render those to components for you, and you're maybe 00:27:58.715 --> 00:28:01.058 a few hours from having a full single page application. 00:28:01.386 --> 00:28:03.657 Or you can continue to sprinkle in more components 00:28:03.657 --> 00:28:05.765 and let your Rails app do all the driving and let your 00:28:05.765 --> 00:28:08.376 components do the more dynamic pieces of your application 00:28:08.376 --> 00:28:10.820 for you with that pool of shared data underneath it. 00:28:12.665 --> 00:28:14.459 Now my brain is tired. 00:28:14.668 --> 00:28:16.902 Why did we do all this stuff, what even is my life. 00:28:18.407 --> 00:28:22.322 We had one job to do, a job that we were just about to quit, 00:28:23.940 --> 00:28:26.777 but right before you became millionaires in the IPO. 00:28:26.777 --> 00:28:28.465 I found out a couple years ago I quit 00:28:28.465 --> 00:28:33.515 a job that just recently IPO'd. I would be on some yacht. 00:28:35.349 --> 00:28:37.543 But we didn't quit, because we love our users, 00:28:37.543 --> 00:28:40.992 we love our coworkers, and we want to love our job. 00:28:41.766 --> 00:28:43.652 Software development, it really is fun. 00:28:43.827 --> 00:28:46.947 It can be frustrating but it shouldn't give you night sweats. 00:28:48.450 --> 00:28:50.230 Let's try this one more time against 00:28:50.230 --> 00:28:51.748 our new and improved code base. 00:28:51.748 --> 00:28:53.763 Once we know the API it's a small test to just 00:28:53.763 --> 00:28:55.711 verify that this thing does what we want. 00:28:55.711 --> 00:28:57.790 We can add a little favorite or like feature. 00:28:58.795 --> 00:29:02.122 We stub out the data, test that a favorite makes it favorite 00:29:02.122 --> 00:29:03.840 and an unfavorite makes it unfavorite. 00:29:04.391 --> 00:29:06.234 Build a little favorite model that talks to 00:29:06.234 --> 00:29:08.946 the server and it has many relationship here. 00:29:09.202 --> 00:29:11.004 You can see DS belongs to gifPost 00:29:11.004 --> 00:29:12.778 and it has many on the other side. 00:29:13.463 --> 00:29:14.876 And add some dynamic content 00:29:14.876 --> 00:29:17.170 to the handlebars template. 00:29:18.317 --> 00:29:20.481 Then we write a toggle action to create or 00:29:20.481 --> 00:29:23.154 destroy the favorite and that's pretty much it. 00:29:23.793 --> 00:29:26.736 If chrome caching will smile upon me 00:29:26.774 --> 00:29:29.655 We'll demo that as well, I'm going to switch my branch. 00:29:47.257 --> 00:29:49.397 Everybody knows this trick, right? 00:29:50.557 --> 00:29:53.086 Also everybody knows the trick of typing rails s. 00:29:55.614 --> 00:29:58.614 It's a little known thing, most people don't know. 00:29:59.048 --> 00:30:01.653 It's how you load a Rails server up. 00:30:02.391 --> 00:30:04.357 (laughter) 00:30:06.911 --> 00:30:09.139 You can see my responsive design is so badass. 00:30:09.408 --> 00:30:12.306 Woah, star just flies all around. 00:30:13.119 --> 00:30:16.038 Now we can favorite this thing. 00:30:16.093 --> 00:30:18.622 It's actually talking to the server on the back end but 00:30:18.622 --> 00:30:20.758 it was so easy to do this that we actually were like, 00:30:20.851 --> 00:30:23.115 Well, do you want me to filter these favorites for you? 00:30:23.115 --> 00:30:26.424 I can do that and just show you my favorite ones. 00:30:26.424 --> 00:30:29.061 This one, this is legendary. 00:30:32.967 --> 00:30:34.799 (laughter) 00:30:36.029 --> 00:30:38.322 (laughter) 00:30:42.967 --> 00:30:45.505 (laughter) 00:30:46.766 --> 00:30:49.720 Now we have favorites. If I unfavorite something 00:30:49.720 --> 00:30:51.579 it will automatically pop out of the list. 00:30:51.579 --> 00:30:54.083 I'm not managing any of this stuff. I just built a 00:30:54.083 --> 00:30:56.557 little tiny filter that took like five minutes to do. 00:30:57.091 --> 00:30:59.734 This stuff buys you so much and extending 00:30:59.734 --> 00:31:01.546 this actually becomes very fun. 00:31:06.944 --> 00:31:09.808 We've changed our relationship now to this code base, 00:31:09.808 --> 00:31:11.838 where we actually like working on it. 00:31:11.919 --> 00:31:13.216 We wake up in the morning instead of feeling 00:31:13.216 --> 00:31:15.581 sick about what's going to be in our inbox we're 00:31:15.581 --> 00:31:17.931 actually really excited about what we get to do next. 00:31:20.074 --> 00:31:22.812 I just want to tell you as an addendum to this that my 00:31:22.812 --> 00:31:26.080 personal story about, my first conference was about 00:31:26.080 --> 00:31:31.017 four years ago and I think a lot of people, can I get a 00:31:31.017 --> 00:31:35.185 show of hands of who's hear that's their first conference? 00:31:37.454 --> 00:31:39.488 That's a really great portion of the room. 00:31:39.488 --> 00:31:40.744 My first conference, 00:31:40.744 --> 00:31:43.275 I went to a hack night the night after the conference. 00:31:43.367 --> 00:31:45.420 It was put on by some really great people 00:31:45.420 --> 00:31:48.277 but I walked in, I looked around and I didn't know anybody. 00:31:49.419 --> 00:31:51.537 I listened to some people talk. 00:31:51.537 --> 00:31:53.607 I was just learning to program. 00:31:53.607 --> 00:31:56.118 I was listening to people talk and they were so smart 00:31:56.118 --> 00:31:57.804 and they were people that were so well known in the 00:31:57.804 --> 00:32:01.348 community and I was so nobody that I immediately 00:32:01.348 --> 00:32:03.180 turned around, left, ran out of the room as fast 00:32:03.180 --> 00:32:05.523 as I could, got in my car and cried and drove home. 00:32:06.078 --> 00:32:08.198 Which is pretty awesome, I'm like super cool guy. 00:32:08.198 --> 00:32:10.154 (laughter) 00:32:10.154 --> 00:32:12.858 After that point the community picked me up and 00:32:12.858 --> 00:32:15.089 dusted me off and said, "Get back in there kiddo." 00:32:15.647 --> 00:32:17.828 Many people in that community that I didn't know in the 00:32:17.828 --> 00:32:19.861 room at the time became some of my closest friends. 00:32:21.373 --> 00:32:23.795 These people in this room, if you'll look around, are some 00:32:23.795 --> 00:32:27.372 of your future closest friends and colleagues and mentors. 00:32:28.045 --> 00:32:30.841 The community is the reason that 00:32:30.841 --> 00:32:32.602 I get to do this for a living, 00:32:32.602 --> 00:32:35.112 when before I was doing just horrifying things. 00:32:35.112 --> 00:32:36.717 If you can imagine what it would be like to do 00:32:36.717 --> 00:32:38.761 marketing for a multi-level marketing corporation. 00:32:39.644 --> 00:32:42.934 Just imagine the existential hell and imagine programming. 00:32:42.934 --> 00:32:44.859 We're pretty lucky to get to do this and I want 00:32:44.859 --> 00:32:47.078 everybody to have as good a time writing software 00:32:47.078 --> 00:32:49.966 as I get to have when I'm doing stuff like this. 00:32:52.241 --> 00:32:53.765 The other thing I want to say, the last note 00:32:53.765 --> 00:32:57.532 I want to say on community is we have a tendency 00:32:57.532 --> 00:32:59.439 to do this tent pole thing where we raise some 00:32:59.439 --> 00:33:02.016 people up and then gather around those people. 00:33:02.032 --> 00:33:03.748 That's not really what a community is about, 00:33:03.748 --> 00:33:06.124 a community is a mesh, it's not like hub and spoke. 00:33:06.748 --> 00:33:08.266 Every person in here has something to 00:33:08.266 --> 00:33:09.795 contribute and something amazing to do 00:33:09.795 --> 00:33:11.434 and I can't wait to go to your talks later. 00:33:11.452 --> 00:33:13.872 I'm told I'm pretty good at hugs ... 00:33:13.872 --> 00:33:18.092 (applause) 00:33:28.217 --> 00:33:29.894 I'm told I'm pretty good at hugs so come 00:33:29.894 --> 00:33:34.454 say hi to me and thank you so much. (applause) 00:33:38.593 --> 00:33:42.999 (energetic big band music)