[Script Info] Title: [Events] Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text Dialogue: 0,0:00:17.06,0:00:18.18,Default,,0000,0000,0000,,ERNIE MILLER: Good afternoon everybody. Dialogue: 0,0:00:18.18,0:00:18.82,Default,,0000,0000,0000,,AUDIENCE: Good afternoon. Dialogue: 0,0:00:18.82,0:00:19.58,Default,,0000,0000,0000,,E.M.: How's it going? Dialogue: 0,0:00:19.58,0:00:21.36,Default,,0000,0000,0000,,AUDIENCE: It's going good! Hi Ernie! Dialogue: 0,0:00:21.36,0:00:23.42,Default,,0000,0000,0000,,E.M.: Hi. My name's Ernie Miller. I work for Dialogue: 0,0:00:23.43,0:00:26.25,Default,,0000,0000,0000,,a company called Appriss in Louisville, Kentucky.\NPlease ask Dialogue: 0,0:00:26.25,0:00:28.80,Default,,0000,0000,0000,,me about them later so that I can justify Dialogue: 0,0:00:28.80,0:00:30.29,Default,,0000,0000,0000,,expensing the trip. Dialogue: 0,0:00:30.29,0:00:31.75,Default,,0000,0000,0000,,AUDIENCE: Whoo! Dialogue: 0,0:00:31.75,0:00:32.48,Default,,0000,0000,0000,,[applause] Dialogue: 0,0:00:32.48,0:00:34.94,Default,,0000,0000,0000,,E.M.: If I could ask you all to do Dialogue: 0,0:00:34.94,0:00:38.37,Default,,0000,0000,0000,,me a favor, as it turns out, most of Dialogue: 0,0:00:38.37,0:00:41.37,Default,,0000,0000,0000,,my fellow co-workers that had come out to\NRailsConf Dialogue: 0,0:00:41.37,0:00:44.17,Default,,0000,0000,0000,,have had to catch a flight to go back Dialogue: 0,0:00:44.17,0:00:45.74,Default,,0000,0000,0000,,home, and so they're missing my talk. And\Nso Dialogue: 0,0:00:45.74,0:00:47.81,Default,,0000,0000,0000,,what I'd like you to do is to Tweet Dialogue: 0,0:00:47.81,0:00:50.74,Default,,0000,0000,0000,,very enthusiastically about the talk, regardless\Nof if it's Dialogue: 0,0:00:50.74,0:00:52.43,Default,,0000,0000,0000,,very good, so that, you know, for at least Dialogue: 0,0:00:52.43,0:00:53.91,Default,,0000,0000,0000,,until it goes on video, they're gonna think\Nthey Dialogue: 0,0:00:53.91,0:00:56.13,Default,,0000,0000,0000,,missed the talk of a lifetime. Dialogue: 0,0:00:56.13,0:00:59.73,Default,,0000,0000,0000,,So, RailsConf, huh? Have you guys had a good Dialogue: 0,0:00:59.73,0:01:00.23,Default,,0000,0000,0000,,times? Dialogue: 0,0:01:00.23,0:01:01.22,Default,,0000,0000,0000,,AUDIENCE: Whoo! Dialogue: 0,0:01:01.22,0:01:01.72,Default,,0000,0000,0000,,[applause] Dialogue: 0,0:01:01.72,0:01:03.21,Default,,0000,0000,0000,,E.M.: Yeah? Yeah. Dialogue: 0,0:01:03.21,0:01:07.69,Default,,0000,0000,0000,,I've had a ball, too. I've had a ball, Dialogue: 0,0:01:07.69,0:01:08.19,Default,,0000,0000,0000,,too. Dialogue: 0,0:01:08.19,0:01:08.68,Default,,0000,0000,0000,,So. Dialogue: 0,0:01:08.68,0:01:10.18,Default,,0000,0000,0000,,AUDIENCE: Ah, yeah! Dialogue: 0,0:01:10.18,0:01:11.36,Default,,0000,0000,0000,,E.M.: I am not. Dialogue: 0,0:01:11.36,0:01:12.53,Default,,0000,0000,0000,,AUDIENCE: [indecipherable - 00:01:10] Dialogue: 0,0:01:12.53,0:01:14.87,Default,,0000,0000,0000,,E.M.: Yes. Yes it was. Dialogue: 0,0:01:14.87,0:01:19.67,Default,,0000,0000,0000,,So, I am not a member of Ruby core. Dialogue: 0,0:01:19.67,0:01:25.26,Default,,0000,0000,0000,,I am not a member of Rails core. However, Dialogue: 0,0:01:25.26,0:01:27.85,Default,,0000,0000,0000,,last month, this game came out, and I'm an Dialogue: 0,0:01:27.85,0:01:31.71,Default,,0000,0000,0000,,avid gamer, and I'd like to happily report\Nthat Dialogue: 0,0:01:31.71,0:01:34.59,Default,,0000,0000,0000,,I am very frequently a member of Damage core, Dialogue: 0,0:01:34.59,0:01:36.78,Default,,0000,0000,0000,,at this point. Dialogue: 0,0:01:36.78,0:01:40.71,Default,,0000,0000,0000,,Unfortunately, membership only lasts for about\Nfifteen seconds at Dialogue: 0,0:01:40.71,0:01:42.94,Default,,0000,0000,0000,,a time. Then I get booted again. So, so Dialogue: 0,0:01:42.94,0:01:46.46,Default,,0000,0000,0000,,there is that. But, you know, I'm thinking,\Nyou Dialogue: 0,0:01:46.46,0:01:48.06,Default,,0000,0000,0000,,know, it's, it's moving up in the world. I'm Dialogue: 0,0:01:48.06,0:01:50.43,Default,,0000,0000,0000,,a member of something core. Dialogue: 0,0:01:50.43,0:01:54.83,Default,,0000,0000,0000,,So, so, it's come to my attention recently\Nthat Dialogue: 0,0:01:54.83,0:01:57.30,Default,,0000,0000,0000,,I have been giving a fair number of talks Dialogue: 0,0:01:57.30,0:01:59.71,Default,,0000,0000,0000,,that usually involve me ranting about something,\Nand I Dialogue: 0,0:01:59.71,0:02:01.77,Default,,0000,0000,0000,,think I'm becoming a bit of a curmudgeon. Dialogue: 0,0:02:01.77,0:02:02.35,Default,,0000,0000,0000,,[applause] Dialogue: 0,0:02:02.35,0:02:06.99,Default,,0000,0000,0000,,So, you're not supposed to clap for that. Dialogue: 0,0:02:06.99,0:02:07.57,Default,,0000,0000,0000,,[laughter] Dialogue: 0,0:02:07.57,0:02:09.74,Default,,0000,0000,0000,,OK. So, one of the things that I want Dialogue: 0,0:02:09.74,0:02:11.57,Default,,0000,0000,0000,,to start off by doing is saying that I Dialogue: 0,0:02:11.57,0:02:13.88,Default,,0000,0000,0000,,recognize that most of us would not be in Dialogue: 0,0:02:13.88,0:02:17.00,Default,,0000,0000,0000,,this room if it weren't for Rails, and that Dialogue: 0,0:02:17.00,0:02:20.09,Default,,0000,0000,0000,,we really owe a lot of our opportunity to Dialogue: 0,0:02:20.09,0:02:22.25,Default,,0000,0000,0000,,get paid for doing Ruby, I know I do Dialogue: 0,0:02:22.25,0:02:26.58,Default,,0000,0000,0000,,anyway, to Rails's existence. So, first off,\NI'd like Dialogue: 0,0:02:26.58,0:02:28.89,Default,,0000,0000,0000,,to get a hand for Rails and how awesome Dialogue: 0,0:02:28.89,0:02:30.24,Default,,0000,0000,0000,,it is and how it enables us to do Dialogue: 0,0:02:30.24,0:02:31.14,Default,,0000,0000,0000,,everything. Dialogue: 0,0:02:31.14,0:02:32.05,Default,,0000,0000,0000,,[applause] Dialogue: 0,0:02:32.05,0:02:36.45,Default,,0000,0000,0000,,OK. OK. Nope. Nope. That's enough. Nope. No\Nmore. Dialogue: 0,0:02:36.45,0:02:36.99,Default,,0000,0000,0000,,We're done celebrating. Dialogue: 0,0:02:36.99,0:02:37.18,Default,,0000,0000,0000,,[laughter] Dialogue: 0,0:02:37.18,0:02:39.53,Default,,0000,0000,0000,,Just that much celebration. Nothing more. Dialogue: 0,0:02:39.53,0:02:40.28,Default,,0000,0000,0000,,[laughter] Dialogue: 0,0:02:40.28,0:02:43.46,Default,,0000,0000,0000,,OK. All right. Stop the part. Dialogue: 0,0:02:43.46,0:02:47.80,Default,,0000,0000,0000,,So. That. That gets me every time. Dialogue: 0,0:02:47.80,0:02:50.44,Default,,0000,0000,0000,,So, that being the case, I, I have to Dialogue: 0,0:02:50.44,0:02:54.40,Default,,0000,0000,0000,,say, a lot of us have been hitting brick Dialogue: 0,0:02:54.40,0:02:57.18,Default,,0000,0000,0000,,walls. How many of you have been building\Nsomething Dialogue: 0,0:02:57.18,0:02:59.66,Default,,0000,0000,0000,,relatively complex with Rails, and you sort\Nof feel Dialogue: 0,0:02:59.66,0:03:02.27,Default,,0000,0000,0000,,like you've, you've gone up against a brick\Nwall. Dialogue: 0,0:03:02.27,0:03:04.58,Default,,0000,0000,0000,,You can't make anymore forward progress and\Nyou feel Dialogue: 0,0:03:04.58,0:03:07.09,Default,,0000,0000,0000,,like you've been kind of, you know, so- yeah, Dialogue: 0,0:03:07.09,0:03:08.97,Default,,0000,0000,0000,,OK. So some hands are going up right. Dialogue: 0,0:03:08.97,0:03:12.21,Default,,0000,0000,0000,,And, and, and so it seems to me, like, Dialogue: 0,0:03:12.21,0:03:14.93,Default,,0000,0000,0000,,if there is that much talk about it, you Dialogue: 0,0:03:14.93,0:03:16.93,Default,,0000,0000,0000,,know, it seems like we often get the response Dialogue: 0,0:03:16.93,0:03:18.77,Default,,0000,0000,0000,,that, you know, we just need to run with Dialogue: 0,0:03:18.77,0:03:22.99,Default,,0000,0000,0000,,more passion at the wall. Run faster. And,\Nand Dialogue: 0,0:03:22.99,0:03:26.54,Default,,0000,0000,0000,,if we just fully commit that we'll burst through Dialogue: 0,0:03:26.54,0:03:28.32,Default,,0000,0000,0000,,and we'll be in this sort of magical land Dialogue: 0,0:03:28.32,0:03:31.89,Default,,0000,0000,0000,,where everything works the way that it's supposed\Nto, Dialogue: 0,0:03:31.89,0:03:34.32,Default,,0000,0000,0000,,and just don't fight so much, right? Dialogue: 0,0:03:34.32,0:03:37.78,Default,,0000,0000,0000,,I have to think that if so many of Dialogue: 0,0:03:37.78,0:03:39.59,Default,,0000,0000,0000,,us have kind of run into these sort of Dialogue: 0,0:03:39.59,0:03:43.73,Default,,0000,0000,0000,,problems, that maybe there's something there.\NMaybe there's, there's Dialogue: 0,0:03:43.73,0:03:44.94,Default,,0000,0000,0000,,some kind of an issue there, and I wanted Dialogue: 0,0:03:44.94,0:03:47.94,Default,,0000,0000,0000,,to give a few opinions about, you know, why Dialogue: 0,0:03:47.94,0:03:49.29,Default,,0000,0000,0000,,that might be. Dialogue: 0,0:03:49.29,0:03:54.90,Default,,0000,0000,0000,,So, Rails is a convention over configuration\Nadvocate, right. Dialogue: 0,0:03:54.90,0:03:56.90,Default,,0000,0000,0000,,That's, that's the big thing that we always\Ntalk Dialogue: 0,0:03:56.90,0:03:59.30,Default,,0000,0000,0000,,about, that we would prefer to have convention\Nover Dialogue: 0,0:03:59.30,0:04:04.40,Default,,0000,0000,0000,,configuration. Now, conventions are really\Nwhat, what opinions want Dialogue: 0,0:04:04.40,0:04:07.23,Default,,0000,0000,0000,,to be when they grow up, right. So, most Dialogue: 0,0:04:07.23,0:04:09.67,Default,,0000,0000,0000,,conventions have stemmed from an opinion.\NWe hopefully share Dialogue: 0,0:04:09.67,0:04:13.82,Default,,0000,0000,0000,,the opinion, but I want to be clear that, Dialogue: 0,0:04:13.82,0:04:16.28,Default,,0000,0000,0000,,when I talk about the opinions that Rails\Nhas Dialogue: 0,0:04:16.28,0:04:19.41,Default,,0000,0000,0000,,today, I am not talking specifically about\Nany members Dialogue: 0,0:04:19.41,0:04:21.33,Default,,0000,0000,0000,,of the core team. I'm not talking about the Dialogue: 0,0:04:21.33,0:04:24.81,Default,,0000,0000,0000,,people, though the software may in fact reflect\Nopinions Dialogue: 0,0:04:24.81,0:04:26.64,Default,,0000,0000,0000,,of people, what I want to talk about is Dialogue: 0,0:04:26.64,0:04:28.78,Default,,0000,0000,0000,,what does the software tell us, right? Dialogue: 0,0:04:28.78,0:04:32.57,Default,,0000,0000,0000,,Because we know that Rails is opinionated\Nsoftware. So, Dialogue: 0,0:04:32.57,0:04:35.22,Default,,0000,0000,0000,,with that out of the way, let's go with Dialogue: 0,0:04:35.22,0:04:38.13,Default,,0000,0000,0000,,the first opinion that Rails, Rails has, that\NI Dialogue: 0,0:04:38.13,0:04:40.65,Default,,0000,0000,0000,,believe Rails has anyway, which is that code\Nshould Dialogue: 0,0:04:40.65,0:04:45.35,Default,,0000,0000,0000,,read like English. And we see this pretty\Nfrequently Dialogue: 0,0:04:45.35,0:04:49.87,Default,,0000,0000,0000,,in comparisons between straight-up Ruby versus\NRails kind of Dialogue: 0,0:04:49.87,0:04:50.84,Default,,0000,0000,0000,,code, right, so. Dialogue: 0,0:04:50.84,0:04:52.63,Default,,0000,0000,0000,,Here's something that a lot of us actually\Nlike. Dialogue: 0,0:04:52.63,0:04:53.68,Default,,0000,0000,0000,,Like, I know this is one of the things Dialogue: 0,0:04:53.68,0:04:55.57,Default,,0000,0000,0000,,that hooked me on Rails right off the bat, Dialogue: 0,0:04:55.57,0:04:57.28,Default,,0000,0000,0000,,was like, oh, I can say, like, five dot Dialogue: 0,0:04:57.28,0:05:00.70,Default,,0000,0000,0000,,days ago, or, you know, because I'm writing\Nsomething Dialogue: 0,0:05:00.70,0:05:03.43,Default,,0000,0000,0000,,in old English, I can say one dot fortnight.from_now. Dialogue: 0,0:05:03.43,0:05:09.14,Default,,0000,0000,0000,,That's very useful. Right. Dialogue: 0,0:05:09.14,0:05:11.55,Default,,0000,0000,0000,,So there's nothing particular, when we say\Nlike, one Dialogue: 0,0:05:11.55,0:05:14.39,Default,,0000,0000,0000,,dot megabyte, right, there's, there's nothing\Nmegabyte-y about the Dialogue: 0,0:05:14.39,0:05:17.74,Default,,0000,0000,0000,,number, right. It just does some multiplication. Dialogue: 0,0:05:17.74,0:05:23.03,Default,,0000,0000,0000,,Similarly, we have some, oh yeah. Fortnight.\NYeah. Similarly, Dialogue: 0,0:05:23.03,0:05:26.99,Default,,0000,0000,0000,,we have some differences where we have something\Nthat Dialogue: 0,0:05:26.99,0:05:29.80,Default,,0000,0000,0000,,array already has, for instance, on it, like\Nthe Dialogue: 0,0:05:29.80,0:05:31.45,Default,,0000,0000,0000,,sh- I just found out it's called the shovel Dialogue: 0,0:05:31.45,0:05:33.40,Default,,0000,0000,0000,,operator. I always just said less than less\Nthan, Dialogue: 0,0:05:33.40,0:05:35.45,Default,,0000,0000,0000,,but whatever it is, right. So we have, like, Dialogue: 0,0:05:35.45,0:05:38.09,Default,,0000,0000,0000,,array less than less than object, right, and\Nwe've, Dialogue: 0,0:05:38.09,0:05:40.08,Default,,0000,0000,0000,,we've got that alias to append, so that we Dialogue: 0,0:05:40.08,0:05:41.83,Default,,0000,0000,0000,,can say append. Dialogue: 0,0:05:41.83,0:05:44.12,Default,,0000,0000,0000,,We have object dot in, so we can ask Dialogue: 0,0:05:44.12,0:05:45.75,Default,,0000,0000,0000,,whether an object is in an array include of Dialogue: 0,0:05:45.75,0:05:47.77,Default,,0000,0000,0000,,ask an array whether it has an object. Things Dialogue: 0,0:05:47.77,0:05:49.55,Default,,0000,0000,0000,,like that. Dialogue: 0,0:05:49.55,0:05:53.79,Default,,0000,0000,0000,,We have string methods that have been, you\Nknow, Dialogue: 0,0:05:53.79,0:05:56.91,Default,,0000,0000,0000,,kind of patched in for, for instance, the\Nstring Dialogue: 0,0:05:56.91,0:05:58.39,Default,,0000,0000,0000,,inquirer. That's one of my, one of my favorite Dialogue: 0,0:05:58.39,0:06:00.52,Default,,0000,0000,0000,,ones. Right in the middle there, we have a Dialogue: 0,0:06:00.52,0:06:02.47,Default,,0000,0000,0000,,check on the left. In Ruby, you simply ask Dialogue: 0,0:06:02.47,0:06:06.12,Default,,0000,0000,0000,,if the environment string equals production.\NBut in Rails, Dialogue: 0,0:06:06.12,0:06:08.75,Default,,0000,0000,0000,,there's a thing called a string inquirer,\Nwhich simply Dialogue: 0,0:06:08.75,0:06:13.26,Default,,0000,0000,0000,,patches method_missing so that you can actually\Nsay, OK. Dialogue: 0,0:06:13.26,0:06:16.24,Default,,0000,0000,0000,,Is the string actually containing the method\Nthat you Dialogue: 0,0:06:16.24,0:06:18.92,Default,,0000,0000,0000,,just sent minus the question mark? And so,\Nthat's Dialogue: 0,0:06:18.92,0:06:21.37,Default,,0000,0000,0000,,really all its doing - the thing on the Dialogue: 0,0:06:21.37,0:06:22.67,Default,,0000,0000,0000,,left. Dialogue: 0,0:06:22.67,0:06:26.96,Default,,0000,0000,0000,,Here's another one. So, in time, we can say Dialogue: 0,0:06:26.96,0:06:30.42,Default,,0000,0000,0000,,beginning_of_day, we can say midnight, we\Ncan sat at_midnight, Dialogue: 0,0:06:30.42,0:06:33.93,Default,,0000,0000,0000,,we can say at_beginning_of_day. We can say\Nmidday, noon, Dialogue: 0,0:06:33.93,0:06:37.26,Default,,0000,0000,0000,,at_midday, at_noon, at_middle_of_day, right.\NThey're all the same thing, Dialogue: 0,0:06:37.26,0:06:41.98,Default,,0000,0000,0000,,and yet there's this really clean API that's\Nexposed Dialogue: 0,0:06:41.98,0:06:44.69,Default,,0000,0000,0000,,this whole change thing, right. It's fairly\Ndiscoverable. Like, Dialogue: 0,0:06:44.69,0:06:46.89,Default,,0000,0000,0000,,I could make a reasonable guess that if I Dialogue: 0,0:06:46.89,0:06:49.57,Default,,0000,0000,0000,,said change_minute to something, or if I said\Nchange Dialogue: 0,0:06:49.57,0:06:52.48,Default,,0000,0000,0000,,any piece of the time to something, it would Dialogue: 0,0:06:52.48,0:06:55.07,Default,,0000,0000,0000,,be able to do exactly what I ask it Dialogue: 0,0:06:55.07,0:06:57.37,Default,,0000,0000,0000,,to do just then. But instead we have these, Dialogue: 0,0:06:57.37,0:07:00.02,Default,,0000,0000,0000,,these aliases that allow us to write code\Nthat's Dialogue: 0,0:07:00.02,0:07:00.86,Default,,0000,0000,0000,,like English. Dialogue: 0,0:07:00.86,0:07:03.67,Default,,0000,0000,0000,,Now, when I go into a coffee shop and Dialogue: 0,0:07:03.67,0:07:05.20,Default,,0000,0000,0000,,I want something that's got a high caffeine\Ncontent, Dialogue: 0,0:07:05.20,0:07:07.40,Default,,0000,0000,0000,,I may order one of these. You all know Dialogue: 0,0:07:07.40,0:07:10.22,Default,,0000,0000,0000,,what this is, right. This is coffee brewed\Nby Dialogue: 0,0:07:10.22,0:07:12.07,Default,,0000,0000,0000,,forcing a small amount of nearly boiling water\Nunder Dialogue: 0,0:07:12.07,0:07:14.58,Default,,0000,0000,0000,,pressure through finely ground coffee beans.\NAnd that's what Dialogue: 0,0:07:14.58,0:07:16.07,Default,,0000,0000,0000,,I go up to the counter and ask for, Dialogue: 0,0:07:16.07,0:07:16.43,Default,,0000,0000,0000,,right. Dialogue: 0,0:07:16.43,0:07:18.95,Default,,0000,0000,0000,,Nope. You know. They'd probably go, you mean\Nan Dialogue: 0,0:07:18.95,0:07:24.04,Default,,0000,0000,0000,,espresso, right? Because espresso is what\Nwe call a Dialogue: 0,0:07:24.04,0:07:28.80,Default,,0000,0000,0000,,loan word. We borrowed that word from Italian\Nbecause Dialogue: 0,0:07:28.80,0:07:30.94,Default,,0000,0000,0000,,it was concise, it was a good way to Dialogue: 0,0:07:30.94,0:07:33.79,Default,,0000,0000,0000,,say what it was that, that we wanted to Dialogue: 0,0:07:33.79,0:07:36.07,Default,,0000,0000,0000,,say without all of those words, right. Dialogue: 0,0:07:36.07,0:07:40.13,Default,,0000,0000,0000,,Ruby is a language in-and-of-itself. It borrows\Nfrom English Dialogue: 0,0:07:40.13,0:07:42.92,Default,,0000,0000,0000,,where it makes sense. But it is my opinion, Dialogue: 0,0:07:42.92,0:07:44.69,Default,,0000,0000,0000,,anyway, that if there is a concise way to Dialogue: 0,0:07:44.69,0:07:47.19,Default,,0000,0000,0000,,say something in Ruby, we don't necessarily\Nneed to Dialogue: 0,0:07:47.19,0:07:49.50,Default,,0000,0000,0000,,borrow a loan word in English. You know how Dialogue: 0,0:07:49.50,0:07:51.32,Default,,0000,0000,0000,,you sit across the table from that guy who Dialogue: 0,0:07:51.32,0:07:53.44,Default,,0000,0000,0000,,always like to use a foreign word for something Dialogue: 0,0:07:53.44,0:07:57.14,Default,,0000,0000,0000,,just to sound clever, right? Right. That's\Nwhat we're Dialogue: 0,0:07:57.14,0:08:00.47,Default,,0000,0000,0000,,doing, right. Like, it doesn't make a lot\Nof Dialogue: 0,0:08:00.47,0:08:00.79,Default,,0000,0000,0000,,sense. Dialogue: 0,0:08:00.79,0:08:03.76,Default,,0000,0000,0000,,Now, here's one you may initially disagree\Nwith. I Dialogue: 0,0:08:03.76,0:08:06.48,Default,,0000,0000,0000,,believe that Rails believes that models descend\Nfrom ActiveRecord, Dialogue: 0,0:08:06.48,0:08:09.87,Default,,0000,0000,0000,,or at the very least an ORM. Now, if Dialogue: 0,0:08:09.87,0:08:12.30,Default,,0000,0000,0000,,you disagree with me, I have three words for Dialogue: 0,0:08:12.30,0:08:17.29,Default,,0000,0000,0000,,you. Rails generate model. Dialogue: 0,0:08:17.29,0:08:20.34,Default,,0000,0000,0000,,What do you get? You get an ActiveRecord subclass, Dialogue: 0,0:08:20.34,0:08:23.26,Default,,0000,0000,0000,,right. Now, you might say, well that's silly,\Nright. Dialogue: 0,0:08:23.26,0:08:26.32,Default,,0000,0000,0000,,But this is the first exposure that Rails\Ndevelopers Dialogue: 0,0:08:26.32,0:08:28.61,Default,,0000,0000,0000,,are likely to have to what goes in a Dialogue: 0,0:08:28.61,0:08:31.20,Default,,0000,0000,0000,,model's directory, and I have talked to extremely\Nsmart Dialogue: 0,0:08:31.20,0:08:34.03,Default,,0000,0000,0000,,developers who have told me that they went\Na Dialogue: 0,0:08:34.03,0:08:36.68,Default,,0000,0000,0000,,number of years before they realized they\Ncould stick Dialogue: 0,0:08:36.68,0:08:39.82,Default,,0000,0000,0000,,plain-old Ruby classes in app models, because\Nthey just Dialogue: 0,0:08:39.82,0:08:42.68,Default,,0000,0000,0000,,thought that, that's not what models are.\NRight? Dialogue: 0,0:08:42.68,0:08:45.28,Default,,0000,0000,0000,,And so, rightfully so then, Rails believes\Nthat the Dialogue: 0,0:08:45.28,0:08:47.99,Default,,0000,0000,0000,,data is the domain, right. That's the ActiveRecord\Npattern. Dialogue: 0,0:08:47.99,0:08:50.23,Default,,0000,0000,0000,,That's the whole point of it. And if you Dialogue: 0,0:08:50.23,0:08:52.45,Default,,0000,0000,0000,,don't believe me, I'll show you some README\Ninformation, Dialogue: 0,0:08:52.45,0:08:53.17,Default,,0000,0000,0000,,right. Dialogue: 0,0:08:53.17,0:08:55.99,Default,,0000,0000,0000,,The prime directive is that we're minimizing\Nthe code Dialogue: 0,0:08:55.99,0:08:59.82,Default,,0000,0000,0000,,needed to build a real-world domain model.\NLots of Dialogue: 0,0:08:59.82,0:09:03.06,Default,,0000,0000,0000,,reflection and runtime extension is the understatement\Nof the Dialogue: 0,0:09:03.06,0:09:10.06,Default,,0000,0000,0000,,year. And magic is not inherently a bad word. Dialogue: 0,0:09:10.27,0:09:13.69,Default,,0000,0000,0000,,Now, what this really comes down to is, is Dialogue: 0,0:09:13.69,0:09:18.33,Default,,0000,0000,0000,,Rails was very much a reaction to very configuration-heavy Dialogue: 0,0:09:18.33,0:09:24.13,Default,,0000,0000,0000,,frameworks in Java, XML files and the like.\NBig Dialogue: 0,0:09:24.13,0:09:26.78,Default,,0000,0000,0000,,reaction to that, right. So what we had determined Dialogue: 0,0:09:26.78,0:09:29.51,Default,,0000,0000,0000,,at that point was that configuration is the\Ndevil, Dialogue: 0,0:09:29.51,0:09:33.64,Default,,0000,0000,0000,,right. And once you have, once you have determined Dialogue: 0,0:09:33.64,0:09:35.78,Default,,0000,0000,0000,,that there is a greater evil out there, then Dialogue: 0,0:09:35.78,0:09:38.01,Default,,0000,0000,0000,,a lot of lesser evils start to seem pretty Dialogue: 0,0:09:38.01,0:09:41.09,Default,,0000,0000,0000,,great by comparison, right. So you can rationalize\Nyourself Dialogue: 0,0:09:41.09,0:09:43.76,Default,,0000,0000,0000,,into a really tricky spot. Dialogue: 0,0:09:43.76,0:09:46.93,Default,,0000,0000,0000,,And so, our goal is to be able to Dialogue: 0,0:09:46.93,0:09:50.60,Default,,0000,0000,0000,,write class Post inherits from ActiveRecord::Base\Nend and have Dialogue: 0,0:09:50.60,0:09:54.64,Default,,0000,0000,0000,,magic happen, right. Like, for instance, we\Ninfer, and Dialogue: 0,0:09:54.64,0:09:56.19,Default,,0000,0000,0000,,I want to talk a little about, about one Dialogue: 0,0:09:56.19,0:09:58.63,Default,,0000,0000,0000,,thing that we do in that case, right. We Dialogue: 0,0:09:58.63,0:10:02.83,Default,,0000,0000,0000,,infer what the attributes should be on that,\Non Dialogue: 0,0:10:02.83,0:10:05.17,Default,,0000,0000,0000,,that model without writing a single line of\Ncode. Dialogue: 0,0:10:05.17,0:10:08.05,Default,,0000,0000,0000,,Now, there's a problem with that. Namely,\Nthat in Dialogue: 0,0:10:08.05,0:10:10.15,Default,,0000,0000,0000,,order to infer the attribute names, you must\Nfirst Dialogue: 0,0:10:10.15,0:10:13.14,Default,,0000,0000,0000,,invent the universe. So I want to walk us Dialogue: 0,0:10:13.14,0:10:17.28,Default,,0000,0000,0000,,through what that looks like. We're gonna\Ndo one Dialogue: 0,0:10:17.28,0:10:19.36,Default,,0000,0000,0000,,deep dive into some Rails internals, and then\NI Dialogue: 0,0:10:19.36,0:10:21.40,Default,,0000,0000,0000,,promise we'll come back up for air and we'll, Dialogue: 0,0:10:21.40,0:10:24.63,Default,,0000,0000,0000,,we'll talk about happy things. Dialogue: 0,0:10:24.63,0:10:28.74,Default,,0000,0000,0000,,So, so you might imagine pretty, pretty early\Non, Dialogue: 0,0:10:28.74,0:10:32.74,Default,,0000,0000,0000,,that we're gonna go ahead and initialize a\Nmodule, Dialogue: 0,0:10:32.74,0:10:34.68,Default,,0000,0000,0000,,and we're gonna actually have a module to\Nstore Dialogue: 0,0:10:34.68,0:10:36.92,Default,,0000,0000,0000,,our attribute methods in. That's actually\Nsomething I kind Dialogue: 0,0:10:36.92,0:10:39.53,Default,,0000,0000,0000,,of like, right, because as a Rubyist, I expect Dialogue: 0,0:10:39.53,0:10:40.91,Default,,0000,0000,0000,,to be able to call super if I define Dialogue: 0,0:10:40.91,0:10:42.40,Default,,0000,0000,0000,,my own method on the class, so that makes Dialogue: 0,0:10:42.40,0:10:43.92,Default,,0000,0000,0000,,a lot of sense, right. Dialogue: 0,0:10:43.92,0:10:45.05,Default,,0000,0000,0000,,So if we look at what happens when we Dialogue: 0,0:10:45.05,0:10:47.65,Default,,0000,0000,0000,,generate the module, we have a new anonymous\Nmodule Dialogue: 0,0:10:47.65,0:10:50.04,Default,,0000,0000,0000,,that extends Mutex, cause we don't want to\Nbe Dialogue: 0,0:10:50.04,0:10:53.07,Default,,0000,0000,0000,,modifying the module from two different threads. Dialogue: 0,0:10:53.07,0:10:56.44,Default,,0000,0000,0000,,And, then in method_missing, we have this\Nhandy little Dialogue: 0,0:10:56.44,0:11:02.03,Default,,0000,0000,0000,,hook that defines the attribute methods, right.\NAnd so, Dialogue: 0,0:11:02.03,0:11:06.48,Default,,0000,0000,0000,,in method_missing, we call this every single\Ntime, right. Dialogue: 0,0:11:06.48,0:11:09.29,Default,,0000,0000,0000,,And the idea being that once we've defined\Nthe Dialogue: 0,0:11:09.29,0:11:10.83,Default,,0000,0000,0000,,methods, they're, we're not gonna hit method_missing,\Nat least Dialogue: 0,0:11:10.83,0:11:13.66,Default,,0000,0000,0000,,for those methods anymore. Dialogue: 0,0:11:13.66,0:11:15.32,Default,,0000,0000,0000,,And so we bail out, if, in fact, we've Dialogue: 0,0:11:15.32,0:11:21.11,Default,,0000,0000,0000,,already generated them. And we call super\Nwith column Dialogue: 0,0:11:21.11,0:11:23.98,Default,,0000,0000,0000,,names, right. Now, where do we get column\Nnames Dialogue: 0,0:11:23.98,0:11:26.75,Default,,0000,0000,0000,,from? Well, it's not there. In fact, method_missing\Nwas Dialogue: 0,0:11:26.75,0:11:29.74,Default,,0000,0000,0000,,the only thing that actually sits on, on the Dialogue: 0,0:11:29.74,0:11:31.53,Default,,0000,0000,0000,,instance level. The rest of the stuff that\Nwe're Dialogue: 0,0:11:31.53,0:11:33.31,Default,,0000,0000,0000,,gonna be looking at sits on the singleton.\NIt Dialogue: 0,0:11:33.31,0:11:36.30,Default,,0000,0000,0000,,sits on the subclass of ActiveRecord itself\Nas a Dialogue: 0,0:11:36.30,0:11:37.43,Default,,0000,0000,0000,,class method. Dialogue: 0,0:11:37.43,0:11:41.15,Default,,0000,0000,0000,,So, when we call super, we're actually calling\Nsuper Dialogue: 0,0:11:41.15,0:11:45.27,Default,,0000,0000,0000,,into ActiveModels. Definition of defining\Nattributes, right. So we're Dialogue: 0,0:11:45.27,0:11:47.60,Default,,0000,0000,0000,,saying, define attributes methods from ActiveModel.\NWe're passing it Dialogue: 0,0:11:47.60,0:11:50.86,Default,,0000,0000,0000,,the column names. So here's column names.\NWell, column Dialogue: 0,0:11:50.86,0:11:54.61,Default,,0000,0000,0000,,names is, again, a singleton method. It knows\Nthat Dialogue: 0,0:11:54.61,0:11:57.65,Default,,0000,0000,0000,,it needs columns, right. And below here, we\Nhave Dialogue: 0,0:11:57.65,0:11:58.46,Default,,0000,0000,0000,,columns. Dialogue: 0,0:11:58.46,0:12:01.89,Default,,0000,0000,0000,,Well, columns needs the connections, for starters,\Nto the Dialogue: 0,0:12:01.89,0:12:03.54,Default,,0000,0000,0000,,database to talk, to figure out, you know,\Nwhat Dialogue: 0,0:12:03.54,0:12:05.36,Default,,0000,0000,0000,,table it's gonna read from. And it also needs Dialogue: 0,0:12:05.36,0:12:08.16,Default,,0000,0000,0000,,to determine table name, right. So now we\Nneed Dialogue: 0,0:12:08.16,0:12:11.47,Default,,0000,0000,0000,,to know the table name. So we don't have Dialogue: 0,0:12:11.47,0:12:13.62,Default,,0000,0000,0000,,the table name yet, so we call a reset Dialogue: 0,0:12:13.62,0:12:18.48,Default,,0000,0000,0000,,table name, and most of the time I'm gonna Dialogue: 0,0:12:18.48,0:12:20.53,Default,,0000,0000,0000,,skip past some of the, some of the more Dialogue: 0,0:12:20.53,0:12:22.76,Default,,0000,0000,0000,,convoluted things and just talk about the\Ncompute table Dialogue: 0,0:12:22.76,0:12:24.30,Default,,0000,0000,0000,,name, right. So we have to compute the table Dialogue: 0,0:12:24.30,0:12:27.37,Default,,0000,0000,0000,,name. It makes sense, right? Dialogue: 0,0:12:27.37,0:12:29.48,Default,,0000,0000,0000,,So, this is kind of a big method. Hopefully Dialogue: 0,0:12:29.48,0:12:31.34,Default,,0000,0000,0000,,you all can see the, the part that matters, Dialogue: 0,0:12:31.34,0:12:35.60,Default,,0000,0000,0000,,which is we call undecorated table name with\Nthe, Dialogue: 0,0:12:35.60,0:12:37.76,Default,,0000,0000,0000,,again, we're sitting on the class. So name\Nrefers Dialogue: 0,0:12:37.76,0:12:39.84,Default,,0000,0000,0000,,to class dot name, right. The string name\Nof Dialogue: 0,0:12:39.84,0:12:43.28,Default,,0000,0000,0000,,the class. The full module name. Dialogue: 0,0:12:43.28,0:12:47.35,Default,,0000,0000,0000,,And, undecorated table name basically does\Nexactly what you Dialogue: 0,0:12:47.35,0:12:50.32,Default,,0000,0000,0000,,see here. Let's say we have a namespace model, Dialogue: 0,0:12:50.32,0:12:54.74,Default,,0000,0000,0000,,Conferences::RailsConf becomes RailsConf becomes\Nrails underscore conf becomes rails_confs, Dialogue: 0,0:12:54.74,0:12:59.13,Default,,0000,0000,0000,,OK. Which is great. And then, of course, if Dialogue: 0,0:12:59.13,0:13:01.32,Default,,0000,0000,0000,,we have Animals::Moose it becomes Moose it\Nbecomes moose Dialogue: 0,0:13:01.32,0:13:05.36,Default,,0000,0000,0000,,it becomes mooses. Which makes lots of sense,\Nright? Dialogue: 0,0:13:05.36,0:13:12.13,Default,,0000,0000,0000,,Well, that means we need to handle irregular\Npluralization. Dialogue: 0,0:13:12.13,0:13:14.17,Default,,0000,0000,0000,,So we check and we see whether or not Dialogue: 0,0:13:14.17,0:13:18.94,Default,,0000,0000,0000,,there's a default pluralization to find for\Nmoose. There Dialogue: 0,0:13:18.94,0:13:21.21,Default,,0000,0000,0000,,is not. There, there, there are some interesting\Nones, Dialogue: 0,0:13:21.21,0:13:23.59,Default,,0000,0000,0000,,I think. We've got, like, sheep. We do have Dialogue: 0,0:13:23.59,0:13:27.60,Default,,0000,0000,0000,,sheep, so we're at least in the ball park. Dialogue: 0,0:13:27.60,0:13:30.77,Default,,0000,0000,0000,,We have jeans. We have fish. But we don't Dialogue: 0,0:13:30.77,0:13:32.21,Default,,0000,0000,0000,,have moose. Dialogue: 0,0:13:32.21,0:13:36.11,Default,,0000,0000,0000,,So, we go into an initializer and we set Dialogue: 0,0:13:36.11,0:13:43.11,Default,,0000,0000,0000,,inflect.uncountable "moose" and then it works,\Nright. But. Configuration. Dialogue: 0,0:13:43.65,0:13:46.22,Default,,0000,0000,0000,,Or we can say self dot table_name equal 'moose' Dialogue: 0,0:13:46.22,0:13:50.07,Default,,0000,0000,0000,,and then bypass all of that altogether, right.\NBut, Dialogue: 0,0:13:50.07,0:13:51.88,Default,,0000,0000,0000,,again, configuration. Dialogue: 0,0:13:51.88,0:13:54.54,Default,,0000,0000,0000,,Now, if configuration is the devil and magic\Nis Dialogue: 0,0:13:54.54,0:13:58.53,Default,,0000,0000,0000,,the goal, then we have to think to ourselves, Dialogue: 0,0:13:58.53,0:14:00.79,Default,,0000,0000,0000,,what is, what is magic, really? And, and an Dialogue: 0,0:14:00.79,0:14:06.07,Default,,0000,0000,0000,,enjoyable magic trick is basically willful\Nsuspension of disbelief, Dialogue: 0,0:14:06.07,0:14:09.46,Default,,0000,0000,0000,,right. So, that is, if this magician came\Nup Dialogue: 0,0:14:09.46,0:14:11.88,Default,,0000,0000,0000,,and said, I'm going to saw my assistant in Dialogue: 0,0:14:11.88,0:14:14.52,Default,,0000,0000,0000,,half, and you didn't think, there's a trick\Nhere, Dialogue: 0,0:14:14.52,0:14:17.01,Default,,0000,0000,0000,,like, it's based in the rules of reality,\Nlike, Dialogue: 0,0:14:17.01,0:14:19.15,Default,,0000,0000,0000,,there's something going on. It would be pretty\Nhorrified, Dialogue: 0,0:14:19.15,0:14:21.88,Default,,0000,0000,0000,,right. We'd be like, I don't be- where have Dialogue: 0,0:14:21.88,0:14:24.48,Default,,0000,0000,0000,,I gone? Like, what is going on here, right? Dialogue: 0,0:14:24.48,0:14:27.27,Default,,0000,0000,0000,,And so there is this level where we would Dialogue: 0,0:14:27.27,0:14:29.97,Default,,0000,0000,0000,,do better to consider, how can we root this Dialogue: 0,0:14:29.97,0:14:32.63,Default,,0000,0000,0000,,kind of magic in some reality that the average Dialogue: 0,0:14:32.63,0:14:35.22,Default,,0000,0000,0000,,person is going to be able to understand?\NAnd Dialogue: 0,0:14:35.22,0:14:37.51,Default,,0000,0000,0000,,then kind of build on that knowledge, sort\Nof Dialogue: 0,0:14:37.51,0:14:39.74,Default,,0000,0000,0000,,scaffold, if you will. And, otherwise, you\Nend up Dialogue: 0,0:14:39.74,0:14:41.72,Default,,0000,0000,0000,,with what I, what I referred to as douche Dialogue: 0,0:14:41.72,0:14:44.31,Default,,0000,0000,0000,,bag magic, which magic that bites you, magic\Nthat Dialogue: 0,0:14:44.31,0:14:47.07,Default,,0000,0000,0000,,screws you over in all sorts of wonderful\Nways. Dialogue: 0,0:14:47.07,0:14:51.54,Default,,0000,0000,0000,,So, let's imagine, for a moment, a world,\Na Dialogue: 0,0:14:51.54,0:14:55.06,Default,,0000,0000,0000,,world where we do have magic that we can Dialogue: 0,0:14:55.06,0:15:01.25,Default,,0000,0000,0000,,understand. And, so let's just say we have\NImaginaryRecord::Record Dialogue: 0,0:15:01.25,0:15:04.60,Default,,0000,0000,0000,,that always asks us to configure a table name. Dialogue: 0,0:15:04.60,0:15:07.39,Default,,0000,0000,0000,,That always asks us to define the attributes\Nin Dialogue: 0,0:15:07.39,0:15:10.82,Default,,0000,0000,0000,,a very mapper style, data mapper style. Right? Dialogue: 0,0:15:10.82,0:15:12.98,Default,,0000,0000,0000,,Given an attribute name, tell it's how its\Nto Dialogue: 0,0:15:12.98,0:15:14.02,Default,,0000,0000,0000,,load the attributes. Tell it how to load the Dialogue: 0,0:15:14.02,0:15:15.45,Default,,0000,0000,0000,,attributes. Maybe some other stuff. We don't,\Nwe're just, Dialogue: 0,0:15:15.45,0:15:18.53,Default,,0000,0000,0000,,we're imagining here, right. We're, we're\Njust in your Dialogue: 0,0:15:18.53,0:15:20.02,Default,,0000,0000,0000,,imagination. Dialogue: 0,0:15:20.02,0:15:22.63,Default,,0000,0000,0000,,And then let's say that we have a MagicRecord Dialogue: 0,0:15:22.63,0:15:26.48,Default,,0000,0000,0000,,that inherits from the ImaginaryRecord::Record,\Nand does all the Dialogue: 0,0:15:26.48,0:15:30.88,Default,,0000,0000,0000,,same stuff that we did before, except it calls Dialogue: 0,0:15:30.88,0:15:34.23,Default,,0000,0000,0000,,these methods on the class in order to set Dialogue: 0,0:15:34.23,0:15:36.34,Default,,0000,0000,0000,,the table name programmatically, in order\Nto set the Dialogue: 0,0:15:36.34,0:15:37.01,Default,,0000,0000,0000,,attributes programmatically, right. Dialogue: 0,0:15:37.01,0:15:41.28,Default,,0000,0000,0000,,Well, that would be pretty cool. We would\Nhave Dialogue: 0,0:15:41.28,0:15:43.13,Default,,0000,0000,0000,,to make some trade offs, but we'd basically\Nget Dialogue: 0,0:15:43.13,0:15:45.51,Default,,0000,0000,0000,,to the point where we could do something like Dialogue: 0,0:15:45.51,0:15:48.45,Default,,0000,0000,0000,,inherit from MagicRecord and get the exact\Nsame behavior Dialogue: 0,0:15:48.45,0:15:51.93,Default,,0000,0000,0000,,as we wanted. But as a freebie, now we Dialogue: 0,0:15:51.93,0:15:54.01,Default,,0000,0000,0000,,have the ability to drop down another layer,\Nif Dialogue: 0,0:15:54.01,0:15:57.00,Default,,0000,0000,0000,,we want. And to actually define this stuff\Nwith Dialogue: 0,0:15:57.00,0:15:58.06,Default,,0000,0000,0000,,less magic. Dialogue: 0,0:15:58.06,0:16:01.80,Default,,0000,0000,0000,,And you say, well that's great. So that's\Nattributes. Dialogue: 0,0:16:01.80,0:16:04.62,Default,,0000,0000,0000,,We kind of understand that. That's pretty\Nsimple, right. Dialogue: 0,0:16:04.62,0:16:08.07,Default,,0000,0000,0000,,Big whoop. ActiveRecord also does all these\Nother things, Dialogue: 0,0:16:08.07,0:16:11.17,Default,,0000,0000,0000,,I mean, you know, it's got like attribute\Ntypecasting Dialogue: 0,0:16:11.17,0:16:13.78,Default,,0000,0000,0000,,and associations and serializations and secure\Npasswords and transactions Dialogue: 0,0:16:13.78,0:16:17.00,Default,,0000,0000,0000,,and macro reflection and nested attributes,\Ntime stamps, lifecycle Dialogue: 0,0:16:17.00,0:16:20.84,Default,,0000,0000,0000,,callbacks, validations, dirty tracking, mass\Nassignment, sanitation, to name Dialogue: 0,0:16:20.84,0:16:23.88,Default,,0000,0000,0000,,some, and oh, by the way, we have querying Dialogue: 0,0:16:23.88,0:16:26.83,Default,,0000,0000,0000,,and persisting, right. That's kind of a important\Nthing Dialogue: 0,0:16:26.83,0:16:29.67,Default,,0000,0000,0000,,in a persistence library. Dialogue: 0,0:16:29.67,0:16:33.63,Default,,0000,0000,0000,,And so, I say yeah. Yeah, exactly. That's.\NThat's Dialogue: 0,0:16:33.63,0:16:36.02,Default,,0000,0000,0000,,an interesting problem that we have, right.\NBecause they're Dialogue: 0,0:16:36.02,0:16:38.33,Default,,0000,0000,0000,,all kind of living in one place, and how Dialogue: 0,0:16:38.33,0:16:43.15,Default,,0000,0000,0000,,do you expose this kind of interface, this\Nkind Dialogue: 0,0:16:43.15,0:16:47.06,Default,,0000,0000,0000,,of way of interacting with, with your library,\Nto Dialogue: 0,0:16:47.06,0:16:48.59,Default,,0000,0000,0000,,cover all of these things. And my answer would Dialogue: 0,0:16:48.59,0:16:51.35,Default,,0000,0000,0000,,be basically that you, you don't. You, you\Nallow Dialogue: 0,0:16:51.35,0:16:53.33,Default,,0000,0000,0000,,this to tell you maybe I've got a crazy Dialogue: 0,0:16:53.33,0:16:54.34,Default,,0000,0000,0000,,idea. Dialogue: 0,0:16:54.34,0:16:58.70,Default,,0000,0000,0000,,So, this is the ancestry chain of, of an Dialogue: 0,0:16:58.70,0:17:01.94,Default,,0000,0000,0000,,ActiveRecord::Base subclass. I just wanted\Nto show it to Dialogue: 0,0:17:01.94,0:17:08.04,Default,,0000,0000,0000,,you real quickly. Now, yeah. Yeah. Three cheers\Nfor Dialogue: 0,0:17:08.04,0:17:11.96,Default,,0000,0000,0000,,the, for the ancestry chain of ActieRecord::Base.\NSo, somebody's Dialogue: 0,0:17:11.96,0:17:15.43,Default,,0000,0000,0000,,clapping. Oh no. Right. Dialogue: 0,0:17:15.43,0:17:18.33,Default,,0000,0000,0000,,SO, in Rails we call this clarity. You may Dialogue: 0,0:17:18.33,0:17:25.33,Default,,0000,0000,0000,,have heard that earlier. Because API surface\Narea is Dialogue: 0,0:17:25.69,0:17:29.42,Default,,0000,0000,0000,,irrelevant. We don't care about that. In other\Nwords, Dialogue: 0,0:17:29.42,0:17:32.94,Default,,0000,0000,0000,,the Single Responsibility Principle is super\Nsimple for sufficiently Dialogue: 0,0:17:32.94,0:17:38.17,Default,,0000,0000,0000,,large values of responsibility. Like, if you're\Nresponsibility is Dialogue: 0,0:17:38.17,0:17:40.79,Default,,0000,0000,0000,,to do everything, then you just say, OK, gotta Dialogue: 0,0:17:40.79,0:17:43.63,Default,,0000,0000,0000,,do everything. It's gotta work, right. That's\Nmy responsibility. Dialogue: 0,0:17:43.63,0:17:47.32,Default,,0000,0000,0000,,Well, it works. All right. Done. Dialogue: 0,0:17:47.32,0:17:50.36,Default,,0000,0000,0000,,And so awhile back, actually last weekend,\NI Tweeted Dialogue: 0,0:17:50.36,0:17:55.02,Default,,0000,0000,0000,,some of these statistics about an observation\Non an, Dialogue: 0,0:17:55.02,0:17:58.77,Default,,0000,0000,0000,,a brand new Rails 4.1 app, what a subclass Dialogue: 0,0:17:58.77,0:18:02.10,Default,,0000,0000,0000,,of ActiveRecord has, what the view has, and\Nwhat Dialogue: 0,0:18:02.10,0:18:06.19,Default,,0000,0000,0000,,the controller has in terms of ancestors,\Npublic protected Dialogue: 0,0:18:06.19,0:18:08.83,Default,,0000,0000,0000,,class methods, public protected instance methods,\Nand same for Dialogue: 0,0:18:08.83,0:18:10.78,Default,,0000,0000,0000,,private methods, right. Dialogue: 0,0:18:10.78,0:18:13.94,Default,,0000,0000,0000,,Now, look. It may very well be that this Dialogue: 0,0:18:13.94,0:18:16.26,Default,,0000,0000,0000,,is exactly the API size that we need. I'm Dialogue: 0,0:18:16.26,0:18:17.75,Default,,0000,0000,0000,,not gonna argue that one way or the other Dialogue: 0,0:18:17.75,0:18:21.07,Default,,0000,0000,0000,,right now. But what I will say is that Dialogue: 0,0:18:21.07,0:18:23.56,Default,,0000,0000,0000,,there are other ways to get there. Just because Dialogue: 0,0:18:23.56,0:18:25.34,Default,,0000,0000,0000,,we want these methods does not mean they all Dialogue: 0,0:18:25.34,0:18:28.32,Default,,0000,0000,0000,,actually have to be implemented in modules\Nthat are Dialogue: 0,0:18:28.32,0:18:31.96,Default,,0000,0000,0000,,included onto the class. Dialogue: 0,0:18:31.96,0:18:34.14,Default,,0000,0000,0000,,And so what I'm getting at is that, it's Dialogue: 0,0:18:34.14,0:18:37.22,Default,,0000,0000,0000,,very, very hard to keep track of just what Dialogue: 0,0:18:37.22,0:18:40.34,Default,,0000,0000,0000,,you're doing. I've been writing Rails for\Nover seven Dialogue: 0,0:18:40.34,0:18:42.16,Default,,0000,0000,0000,,years. I'm not exactly sure how long at this Dialogue: 0,0:18:42.16,0:18:45.59,Default,,0000,0000,0000,,point. But, I know that, since I've been doing Dialogue: 0,0:18:45.59,0:18:48.79,Default,,0000,0000,0000,,it, I still have to have documentation open\Nmost Dialogue: 0,0:18:48.79,0:18:51.25,Default,,0000,0000,0000,,of the time when I'm doing anything serious.\NLike, Dialogue: 0,0:18:51.25,0:18:53.64,Default,,0000,0000,0000,,maybe I'm just dumb. Possible. I don't know.\NBut Dialogue: 0,0:18:53.64,0:18:57.39,Default,,0000,0000,0000,,I need documentation. It's a really big namespace\Nto Dialogue: 0,0:18:57.39,0:18:58.90,Default,,0000,0000,0000,,try to keep in your head all at one Dialogue: 0,0:18:58.90,0:18:59.60,Default,,0000,0000,0000,,point. Dialogue: 0,0:18:59.60,0:19:04.72,Default,,0000,0000,0000,,So, this is on, online at GitHub, and you Dialogue: 0,0:19:04.72,0:19:07.15,Default,,0000,0000,0000,,are free to do science to verify my empirical Dialogue: 0,0:19:07.15,0:19:11.48,Default,,0000,0000,0000,,observations and see whether or not they are\Naccurate, Dialogue: 0,0:19:11.48,0:19:13.31,Default,,0000,0000,0000,,and I would love to see PRs to this Dialogue: 0,0:19:13.31,0:19:17.33,Default,,0000,0000,0000,,repo, actually, with, you know, different\Nversions of Rails Dialogue: 0,0:19:17.33,0:19:19.46,Default,,0000,0000,0000,,to see how things have changed, complexity-wise. Dialogue: 0,0:19:19.46,0:19:22.48,Default,,0000,0000,0000,,Now, it's not enough really for ActiveRecord\Nto just Dialogue: 0,0:19:22.48,0:19:25.94,Default,,0000,0000,0000,,do this on its own. It actually encourages\Nus Dialogue: 0,0:19:25.94,0:19:31.02,Default,,0000,0000,0000,,to do this, right. Rails has this whole helper Dialogue: 0,0:19:31.02,0:19:33.55,Default,,0000,0000,0000,,thing, right. And, let me give you an example Dialogue: 0,0:19:33.55,0:19:36.22,Default,,0000,0000,0000,,of something I actually encountered and, I'm\Nembarrassed to Dialogue: 0,0:19:36.22,0:19:38.29,Default,,0000,0000,0000,,say, spent like half a day trouble shooting\Nwith Dialogue: 0,0:19:38.29,0:19:40.39,Default,,0000,0000,0000,,the, with helpers. Dialogue: 0,0:19:40.39,0:19:44.08,Default,,0000,0000,0000,,So, I decided I had a really great idea, Dialogue: 0,0:19:44.08,0:19:45.84,Default,,0000,0000,0000,,and I was gonna use something that I heard Dialogue: 0,0:19:45.84,0:19:48.84,Default,,0000,0000,0000,,that OO developers like to do, which is polymorphism, Dialogue: 0,0:19:48.84,0:19:50.37,Default,,0000,0000,0000,,and use it at the view layer, right. And Dialogue: 0,0:19:50.37,0:19:54.25,Default,,0000,0000,0000,,I'm like, I can have something that is summarizable, Dialogue: 0,0:19:54.25,0:19:56.02,Default,,0000,0000,0000,,and so I might have a helper for posts Dialogue: 0,0:19:56.02,0:19:57.94,Default,,0000,0000,0000,,that's summary, and I might have a helper\Nfor Dialogue: 0,0:19:57.94,0:20:00.15,Default,,0000,0000,0000,,reviews that's summary. Dialogue: 0,0:20:00.15,0:20:02.55,Default,,0000,0000,0000,,And I can share a partial that prints that Dialogue: 0,0:20:02.55,0:20:06.17,Default,,0000,0000,0000,,summary in an appropriate way for that particular\Nthing, Dialogue: 0,0:20:06.17,0:20:08.50,Default,,0000,0000,0000,,right. That seemed pretty cool. So this is\Nhow Dialogue: 0,0:20:08.50,0:20:12.06,Default,,0000,0000,0000,,it would look in a partial. And in development Dialogue: 0,0:20:12.06,0:20:16.22,Default,,0000,0000,0000,,it worked wonderfully. It worked exactly the\Nway I Dialogue: 0,0:20:16.22,0:20:18.45,Default,,0000,0000,0000,,expected. And then I deployed to production. Dialogue: 0,0:20:18.45,0:20:23.53,Default,,0000,0000,0000,,Now, how many of you think it worked? Right. Dialogue: 0,0:20:23.53,0:20:25.84,Default,,0000,0000,0000,,How many of you think it didn't work. Well, Dialogue: 0,0:20:25.84,0:20:29.15,Default,,0000,0000,0000,,it's kind of a trick question, because honestly\Nyou Dialogue: 0,0:20:29.15,0:20:30.92,Default,,0000,0000,0000,,can't really tell me, because you don't have\Nenough Dialogue: 0,0:20:30.92,0:20:34.81,Default,,0000,0000,0000,,information right now. Because there's this\Nthing, right. Dialogue: 0,0:20:34.81,0:20:38.62,Default,,0000,0000,0000,,OK, so, seven years ago, there was a commit Dialogue: 0,0:20:38.62,0:20:41.39,Default,,0000,0000,0000,,to Rails that said, we are going to make Dialogue: 0,0:20:41.39,0:20:43.21,Default,,0000,0000,0000,,it default assumption you want all helpers\Nall the Dialogue: 0,0:20:43.21,0:20:48.83,Default,,0000,0000,0000,,time. No comment. Dialogue: 0,0:20:48.83,0:20:51.95,Default,,0000,0000,0000,,And, for a long period of time, I'd like Dialogue: 0,0:20:51.95,0:20:53.46,Default,,0000,0000,0000,,to imagine it was some kind of a dark Dialogue: 0,0:20:53.46,0:20:55.53,Default,,0000,0000,0000,,age in Rails. There was really no way to Dialogue: 0,0:20:55.53,0:20:57.64,Default,,0000,0000,0000,,opt out of this, per se, until a patch Dialogue: 0,0:20:57.64,0:21:00.30,Default,,0000,0000,0000,,came in that added include all helpers as\Na Dialogue: 0,0:21:00.30,0:21:03.58,Default,,0000,0000,0000,,configuration option. So I thought, this is\Ngreat. I Dialogue: 0,0:21:03.58,0:21:07.27,Default,,0000,0000,0000,,found this, now I found this after hours of Dialogue: 0,0:21:07.27,0:21:10.05,Default,,0000,0000,0000,,searching, like, because I just somehow missed\Nthe memo Dialogue: 0,0:21:10.05,0:21:11.57,Default,,0000,0000,0000,,that we had done that. It was way back Dialogue: 0,0:21:11.57,0:21:13.29,Default,,0000,0000,0000,,in 2.3, like, this has been the way for Dialogue: 0,0:21:13.29,0:21:14.43,Default,,0000,0000,0000,,awhile, right. Dialogue: 0,0:21:14.43,0:21:17.07,Default,,0000,0000,0000,,But, like I just kind of assume, like, it's Dialogue: 0,0:21:17.07,0:21:21.73,Default,,0000,0000,0000,,named post_helper, it should help posts. Not,\Nlike, other Dialogue: 0,0:21:21.73,0:21:24.42,Default,,0000,0000,0000,,things. But that's not how it works. So there's Dialogue: 0,0:21:24.42,0:21:28.11,Default,,0000,0000,0000,,this kind of big namespace, right. And so,\NI Dialogue: 0,0:21:28.11,0:21:31.30,Default,,0000,0000,0000,,would recommend that nearly all of you consider\Nadding Dialogue: 0,0:21:31.30,0:21:35.47,Default,,0000,0000,0000,,this to to your application dot rb. You will Dialogue: 0,0:21:35.47,0:21:37.80,Default,,0000,0000,0000,,be much more sane for it. If you're going Dialogue: 0,0:21:37.80,0:21:40.29,Default,,0000,0000,0000,,to use helpers, at the very least, having\Na Dialogue: 0,0:21:40.29,0:21:42.05,Default,,0000,0000,0000,,namespace that you can kind of control. If\Nyou Dialogue: 0,0:21:42.05,0:21:44.46,Default,,0000,0000,0000,,want to be available to all controllers, then\Nthrow Dialogue: 0,0:21:44.46,0:21:46.87,Default,,0000,0000,0000,,it in application_helper or have a module.\NYou can Dialogue: 0,0:21:46.87,0:21:48.84,Default,,0000,0000,0000,,still use modules, I hear. It works. Dialogue: 0,0:21:48.84,0:21:50.92,Default,,0000,0000,0000,,Now, we did all this in the name of Dialogue: 0,0:21:50.92,0:21:55.09,Default,,0000,0000,0000,,convenience, right. Convenience is, is going\Nto trump everything Dialogue: 0,0:21:55.09,0:21:58.12,Default,,0000,0000,0000,,else. We want convenient usage at expense\Nof anything Dialogue: 0,0:21:58.12,0:22:02.87,Default,,0000,0000,0000,,else. And, you know, so I own a house. Dialogue: 0,0:22:02.87,0:22:05.90,Default,,0000,0000,0000,,And I think to myself often that, you know, Dialogue: 0,0:22:05.90,0:22:09.52,Default,,0000,0000,0000,,when nature calls, I have, like, to get up Dialogue: 0,0:22:09.52,0:22:12.14,Default,,0000,0000,0000,,and like, go to a special room to go Dialogue: 0,0:22:12.14,0:22:14.76,Default,,0000,0000,0000,,do my business, right. Dialogue: 0,0:22:14.76,0:22:15.85,Default,,0000,0000,0000,,[laughter] Dialogue: 0,0:22:15.85,0:22:20.30,Default,,0000,0000,0000,,And I mean that's really inconvenient. So\Nlike, why Dialogue: 0,0:22:20.30,0:22:23.00,Default,,0000,0000,0000,,don't I just install a toilet, like, in every Dialogue: 0,0:22:23.00,0:22:26.30,Default,,0000,0000,0000,,room in the house, right? Because then, like,\Nif Dialogue: 0,0:22:26.30,0:22:28.70,Default,,0000,0000,0000,,I'm watching the tube, it doesn't matter you\Nknow. Dialogue: 0,0:22:28.70,0:22:31.24,Default,,0000,0000,0000,,Do my thing. It's all good. but the problem Dialogue: 0,0:22:31.24,0:22:34.15,Default,,0000,0000,0000,,with that is, right, that first off, you've\Ngot, Dialogue: 0,0:22:34.15,0:22:37.34,Default,,0000,0000,0000,,like, plumbing now to help support this, this\Naspiration Dialogue: 0,0:22:37.34,0:22:40.66,Default,,0000,0000,0000,,of having a toilet in every room. And plumbers Dialogue: 0,0:22:40.66,0:22:43.02,Default,,0000,0000,0000,,are expensive and, like, stuff breaks and\Nthen it's Dialogue: 0,0:22:43.02,0:22:45.21,Default,,0000,0000,0000,,like, I've got a leak and I've got damage Dialogue: 0,0:22:45.21,0:22:48.12,Default,,0000,0000,0000,,and stuff, and then the other problem is,\Nlike, Dialogue: 0,0:22:48.12,0:22:51.18,Default,,0000,0000,0000,,every room is a toilet, right. Dialogue: 0,0:22:51.18,0:22:56.33,Default,,0000,0000,0000,,So, I would encourage you to consider that\Nif Dialogue: 0,0:22:56.33,0:22:58.59,Default,,0000,0000,0000,,this is kind of what you're looking for, if Dialogue: 0,0:22:58.59,0:23:02.70,Default,,0000,0000,0000,,a giant namespace of, of, of methods and functions Dialogue: 0,0:23:02.70,0:23:04.85,Default,,0000,0000,0000,,is what you would really like to have, then Dialogue: 0,0:23:04.85,0:23:09.82,Default,,0000,0000,0000,,have I got the language for you. Dialogue: 0,0:23:09.82,0:23:16.12,Default,,0000,0000,0000,,It is super convenient, like, everything is\Nat arm's Dialogue: 0,0:23:16.12,0:23:17.52,Default,,0000,0000,0000,,length. What's that? You want to do something\Nwith Dialogue: 0,0:23:17.52,0:23:20.61,Default,,0000,0000,0000,,a string and an array, yeah, doesn't matter.\NMySQL, Dialogue: 0,0:23:20.61,0:23:24.72,Default,,0000,0000,0000,,sure. Absolutely. I mean, just a thought. Dialogue: 0,0:23:24.72,0:23:30.09,Default,,0000,0000,0000,,So now another, another Rails opinion is,\Nwho needs Dialogue: 0,0:23:30.09,0:23:35.71,Default,,0000,0000,0000,,classes when we've got modules? And I say\Nthis Dialogue: 0,0:23:35.71,0:23:40.33,Default,,0000,0000,0000,,primarily because of one interesting piece\Nof code, which Dialogue: 0,0:23:40.33,0:23:47.33,Default,,0000,0000,0000,,is ActiveSupport::Concern. So, ActiveSupport::Concern\Nyou may think is mainly Dialogue: 0,0:23:47.54,0:23:50.42,Default,,0000,0000,0000,,for having a convention around having a class\Nmethods Dialogue: 0,0:23:50.42,0:23:54.03,Default,,0000,0000,0000,,module inside your module. And instance methods\Nand so Dialogue: 0,0:23:54.03,0:23:56.52,Default,,0000,0000,0000,,forth. But it's not. Dialogue: 0,0:23:56.52,0:24:00.14,Default,,0000,0000,0000,,The problem the it's designed to solve is\Nthat, Dialogue: 0,0:24:00.14,0:24:02.71,Default,,0000,0000,0000,,in this world, the Ruby world, the one that Dialogue: 0,0:24:02.71,0:24:06.89,Default,,0000,0000,0000,,we live in lots of times, we, we actually Dialogue: 0,0:24:06.89,0:24:09.15,Default,,0000,0000,0000,,would have to include. There's a lot of extension Dialogue: 0,0:24:09.15,0:24:11.42,Default,,0000,0000,0000,,onto a class, right, when you include a module Dialogue: 0,0:24:11.42,0:24:13.18,Default,,0000,0000,0000,,in the Rails world. Like, a lot of the Dialogue: 0,0:24:13.18,0:24:15.49,Default,,0000,0000,0000,,modules that Rails is built on go and do Dialogue: 0,0:24:15.49,0:24:18.11,Default,,0000,0000,0000,,metaprogramming and add methods to the singleton\Nor whatever Dialogue: 0,0:24:18.11,0:24:19.98,Default,,0000,0000,0000,,onto the class itself, right. Dialogue: 0,0:24:19.98,0:24:22.41,Default,,0000,0000,0000,,And if you're adding stuff to the singleton,\Nthen Dialogue: 0,0:24:22.41,0:24:25.28,Default,,0000,0000,0000,,it's not sufficient for you to go ahead and, Dialogue: 0,0:24:25.28,0:24:27.87,Default,,0000,0000,0000,,and do that in a module that is itself Dialogue: 0,0:24:27.87,0:24:29.81,Default,,0000,0000,0000,,included, right. Because when it gets included\Nin the Dialogue: 0,0:24:29.81,0:24:32.23,Default,,0000,0000,0000,,module, it modifies the module singleton,\Nnot the class Dialogue: 0,0:24:32.23,0:24:33.66,Default,,0000,0000,0000,,singleton. With me so far? Dialogue: 0,0:24:33.66,0:24:36.54,Default,,0000,0000,0000,,Right. This is a huge problem. So. So let's Dialogue: 0,0:24:36.54,0:24:39.61,Default,,0000,0000,0000,,solve it. Now, we have this ability to have Dialogue: 0,0:24:39.61,0:24:44.79,Default,,0000,0000,0000,,dependencies that get trapped by ActiveSupport::Concern,\Nso that each Dialogue: 0,0:24:44.79,0:24:47.77,Default,,0000,0000,0000,,singleton knows what, what its dependencies\Nare, and then Dialogue: 0,0:24:47.77,0:24:51.65,Default,,0000,0000,0000,,at the time that you include the, the dependency Dialogue: 0,0:24:51.65,0:24:53.75,Default,,0000,0000,0000,,that you're really looking for, it can also\Ngo Dialogue: 0,0:24:53.75,0:24:55.58,Default,,0000,0000,0000,,back and include into your module all the\Nother Dialogue: 0,0:24:55.58,0:24:57.41,Default,,0000,0000,0000,,ones that it needed, and so then that way Dialogue: 0,0:24:57.41,0:24:59.66,Default,,0000,0000,0000,,they can do their metaprogramming magic on\Nyour singleton Dialogue: 0,0:24:59.66,0:25:01.65,Default,,0000,0000,0000,,instead of their singleton. Dialogue: 0,0:25:01.65,0:25:04.89,Default,,0000,0000,0000,,It's great. And it's, you know, so what it Dialogue: 0,0:25:04.89,0:25:06.65,Default,,0000,0000,0000,,is is that there was this, this, this problem. Dialogue: 0,0:25:06.65,0:25:11.72,Default,,0000,0000,0000,,There was this problem that we had. And, you Dialogue: 0,0:25:11.72,0:25:14.66,Default,,0000,0000,0000,,know, we decided to bundle a, a, a free Dialogue: 0,0:25:14.66,0:25:18.85,Default,,0000,0000,0000,,razor with every yak. And, I mean, I guess Dialogue: 0,0:25:18.85,0:25:22.53,Default,,0000,0000,0000,,that's one solution, sure. And so, so I've\Nbeen Dialogue: 0,0:25:22.53,0:25:25.43,Default,,0000,0000,0000,,thinking a lot about this lately. Dialogue: 0,0:25:25.43,0:25:27.29,Default,,0000,0000,0000,,And one of the things that sort of bothers Dialogue: 0,0:25:27.29,0:25:29.62,Default,,0000,0000,0000,,me is that, you know, we're regularly told\Nnot Dialogue: 0,0:25:29.62,0:25:34.49,Default,,0000,0000,0000,,to, not to fight the framework, right. But\Nour Dialogue: 0,0:25:34.49,0:25:39.12,Default,,0000,0000,0000,,framework pretty actively fights the language.\NThere are things Dialogue: 0,0:25:39.12,0:25:41.80,Default,,0000,0000,0000,,that the language is saying, hey, this might\Nbe Dialogue: 0,0:25:41.80,0:25:43.16,Default,,0000,0000,0000,,crazy. Maybe you don't want to do this. And Dialogue: 0,0:25:43.16,0:25:46.98,Default,,0000,0000,0000,,we're like, I won't do what you tell me. Dialogue: 0,0:25:46.98,0:25:50.63,Default,,0000,0000,0000,,I will do exactly what I want to do. Dialogue: 0,0:25:50.63,0:25:54.59,Default,,0000,0000,0000,,And it encourages this, this kind of module-centric\Ndesign. Dialogue: 0,0:25:54.59,0:25:56.75,Default,,0000,0000,0000,,Limits the entry points that we can have.\NSo, Dialogue: 0,0:25:56.75,0:25:58.83,Default,,0000,0000,0000,,you know, Yehuda made a really great point,\Nactually, Dialogue: 0,0:25:58.83,0:26:00.96,Default,,0000,0000,0000,,when he talked about that we're kind of on Dialogue: 0,0:26:00.96,0:26:03.99,Default,,0000,0000,0000,,the 400th story, right. And, and I agree.\NWe Dialogue: 0,0:26:03.99,0:26:06.60,Default,,0000,0000,0000,,are, we are like way up here in terms Dialogue: 0,0:26:06.60,0:26:08.12,Default,,0000,0000,0000,,of abstraction. Dialogue: 0,0:26:08.12,0:26:12.18,Default,,0000,0000,0000,,But, like, I've heard rumors that, like, maybe,\Non Dialogue: 0,0:26:12.18,0:26:14.73,Default,,0000,0000,0000,,most buildings, like, those other floors like\Nhave people Dialogue: 0,0:26:14.73,0:26:18.28,Default,,0000,0000,0000,,in them, and like, they do things. And like Dialogue: 0,0:26:18.28,0:26:21.17,Default,,0000,0000,0000,,maybe you can not just be trapped on the Dialogue: 0,0:26:21.17,0:26:23.10,Default,,0000,0000,0000,,400th floor forever, but maybe you want to\Nlike Dialogue: 0,0:26:23.10,0:26:25.78,Default,,0000,0000,0000,,go down, cause like, I heard, like, on floor Dialogue: 0,0:26:25.78,0:26:29.33,Default,,0000,0000,0000,,350 there's like an ice cream store, and like, Dialogue: 0,0:26:29.33,0:26:31.71,Default,,0000,0000,0000,,I like ice cream. Right. So maybe I want Dialogue: 0,0:26:31.71,0:26:33.02,Default,,0000,0000,0000,,to go down and have some ice cream. Dialogue: 0,0:26:33.02,0:26:36.52,Default,,0000,0000,0000,,But, like, I can't. Because I could only do Dialogue: 0,0:26:36.52,0:26:39.72,Default,,0000,0000,0000,,things with things that are instantiatable,\Nright. And if Dialogue: 0,0:26:39.72,0:26:42.11,Default,,0000,0000,0000,,everything is a module, I'm not instantiating\Nthat. I Dialogue: 0,0:26:42.11,0:26:44.53,Default,,0000,0000,0000,,guess I could write my own class and include Dialogue: 0,0:26:44.53,0:26:47.05,Default,,0000,0000,0000,,half of what's going on, but that seems like Dialogue: 0,0:26:47.05,0:26:49.19,Default,,0000,0000,0000,,I'm just perpetuating the problem. Dialogue: 0,0:26:49.19,0:26:54.47,Default,,0000,0000,0000,,So, here's another, here's another Rails opinion.\NRails believes Dialogue: 0,0:26:54.47,0:26:59.39,Default,,0000,0000,0000,,that your conventions suck. First example\Nis, now, I Dialogue: 0,0:26:59.39,0:27:01.25,Default,,0000,0000,0000,,know it's gonna be hard for you to believe, Dialogue: 0,0:27:01.25,0:27:05.73,Default,,0000,0000,0000,,but there were conventions for building applications\Nbefore Rails Dialogue: 0,0:27:05.73,0:27:08.71,Default,,0000,0000,0000,,came out. Like, people were actually building\N- I Dialogue: 0,0:27:08.71,0:27:12.82,Default,,0000,0000,0000,,know, it's a little weird. They were building\Nweb Dialogue: 0,0:27:12.82,0:27:14.22,Default,,0000,0000,0000,,applications, and, and one of the things that\Nthey Dialogue: 0,0:27:14.22,0:27:16.10,Default,,0000,0000,0000,,used was JavaScript, right. Dialogue: 0,0:27:16.10,0:27:19.87,Default,,0000,0000,0000,,Now, love or hate JavaScript, it, it, it's\Nhere Dialogue: 0,0:27:19.87,0:27:21.62,Default,,0000,0000,0000,,to stay at this point. We, we, we're gonna Dialogue: 0,0:27:21.62,0:27:25.29,Default,,0000,0000,0000,,be writing it. And so, Rails, once upon a Dialogue: 0,0:27:25.29,0:27:28.33,Default,,0000,0000,0000,,time - you guys remember this? You remember\Nthis? Dialogue: 0,0:27:28.33,0:27:32.50,Default,,0000,0000,0000,,Like, let's, so. If this was before your time Dialogue: 0,0:27:32.50,0:27:35.11,Default,,0000,0000,0000,,with Rails, we had, we had this great idea, Dialogue: 0,0:27:35.11,0:27:39.58,Default,,0000,0000,0000,,right, which is, JavaScript's a pain to write.\NAnd Dialogue: 0,0:27:39.58,0:27:44.22,Default,,0000,0000,0000,,let's write Ruby that writes JavaScript instead.\NAnd so Dialogue: 0,0:27:44.22,0:27:46.82,Default,,0000,0000,0000,,we called that RJS, and you could write these, Dialogue: 0,0:27:46.82,0:27:48.42,Default,,0000,0000,0000,,there were these methods that if you said\Npage Dialogue: 0,0:27:48.42,0:27:50.65,Default,,0000,0000,0000,,dot whatever, it would generate some JavaScript.\NAnd you Dialogue: 0,0:27:50.65,0:27:52.72,Default,,0000,0000,0000,,could go look at the JavaScript and it was, Dialogue: 0,0:27:52.72,0:27:55.00,Default,,0000,0000,0000,,you know, about what you would expect generated\NJavaScript Dialogue: 0,0:27:55.00,0:27:57.26,Default,,0000,0000,0000,,to be. Dialogue: 0,0:27:57.26,0:27:59.88,Default,,0000,0000,0000,,And then we decided, you know, OK, maybe that Dialogue: 0,0:27:59.88,0:28:01.97,Default,,0000,0000,0000,,was crazy. But we're still not happy with\Nthe Dialogue: 0,0:28:01.97,0:28:06.60,Default,,0000,0000,0000,,whole state that we have to write JavaScript.\NSo Dialogue: 0,0:28:06.60,0:28:09.86,Default,,0000,0000,0000,,we decided to use JavaScript that looks like\NRuby, Dialogue: 0,0:28:09.86,0:28:14.68,Default,,0000,0000,0000,,right. OK. Great. All right. Fine. I can see Dialogue: 0,0:28:14.68,0:28:17.40,Default,,0000,0000,0000,,that. Dialogue: 0,0:28:17.40,0:28:21.13,Default,,0000,0000,0000,,And then, at that point, now, we were at Dialogue: 0,0:28:21.13,0:28:24.36,Default,,0000,0000,0000,,a point where there's this other convention,\Nwhere like, Dialogue: 0,0:28:24.36,0:28:26.81,Default,,0000,0000,0000,,if you're using jQuery, and many of us are, Dialogue: 0,0:28:26.81,0:28:31.01,Default,,0000,0000,0000,,like, let's say, let's say that I want to Dialogue: 0,0:28:31.01,0:28:33.53,Default,,0000,0000,0000,,render, I have decided I'm gonna be on the Dialogue: 0,0:28:33.53,0:28:35.76,Default,,0000,0000,0000,,straight and narrow, I am going to render\Nmy, Dialogue: 0,0:28:35.76,0:28:40.22,Default,,0000,0000,0000,,my, my views in Ruby. I want to render Dialogue: 0,0:28:40.22,0:28:41.89,Default,,0000,0000,0000,,static html that I spit out. But I need Dialogue: 0,0:28:41.89,0:28:45.87,Default,,0000,0000,0000,,some dynamic parts, and so I'm gonna render\Nsome, Dialogue: 0,0:28:45.87,0:28:48.58,Default,,0000,0000,0000,,some JavaScript as well that's gonna do some\Nthings, Dialogue: 0,0:28:48.58,0:28:49.96,Default,,0000,0000,0000,,right. Use jQuery. Dialogue: 0,0:28:49.96,0:28:51.51,Default,,0000,0000,0000,,This is a pretty standard convention, right.\NI mean, Dialogue: 0,0:28:51.51,0:28:53.47,Default,,0000,0000,0000,,how many of you have this exact code in Dialogue: 0,0:28:53.47,0:28:56.22,Default,,0000,0000,0000,,your code base somewhere, right. If you're\Nnot raising Dialogue: 0,0:28:56.22,0:29:00.53,Default,,0000,0000,0000,,your hand, I'm very shocked. So, we thought,\Nyou Dialogue: 0,0:29:00.53,0:29:02.47,Default,,0000,0000,0000,,know, that's, that's great. It's really cool\Nto be Dialogue: 0,0:29:02.47,0:29:04.66,Default,,0000,0000,0000,,able to hook into $(document).ready and do\Nsome stuff. Dialogue: 0,0:29:04.66,0:29:08.75,Default,,0000,0000,0000,,And so, so Rails said, that's a horrible idea. Dialogue: 0,0:29:08.75,0:29:12.58,Default,,0000,0000,0000,,You should use Turbolinks. And so now, look,\Nyou Dialogue: 0,0:29:12.58,0:29:16.34,Default,,0000,0000,0000,,can yank Turbolinks out of your gemfile and\Nthat's Dialogue: 0,0:29:16.34,0:29:18.63,Default,,0000,0000,0000,,true. You can do that, right. But it's my Dialogue: 0,0:29:18.63,0:29:22.90,Default,,0000,0000,0000,,opinion that convention should probably not\Ncompletely break someone's Dialogue: 0,0:29:22.90,0:29:25.43,Default,,0000,0000,0000,,expectations if they're doing server-side\Nrendering, and this is Dialogue: 0,0:29:25.43,0:29:27.41,Default,,0000,0000,0000,,something that you, you are going to run into Dialogue: 0,0:29:27.41,0:29:28.99,Default,,0000,0000,0000,,if you're just starting out with Rails. You'll\Nbe Dialogue: 0,0:29:28.99,0:29:30.33,Default,,0000,0000,0000,,like, well, why isn't this doing? Well, we\Ndon't Dialogue: 0,0:29:30.33,0:29:31.84,Default,,0000,0000,0000,,fire. We don't fire the doc. Dialogue: 0,0:29:31.84,0:29:34.78,Default,,0000,0000,0000,,No, there are, there are other gems that will Dialogue: 0,0:29:34.78,0:29:37.14,Default,,0000,0000,0000,,make this seem like that is not the case. Dialogue: 0,0:29:37.14,0:29:39.05,Default,,0000,0000,0000,,But the fact of the matter is, it's gonna Dialogue: 0,0:29:39.05,0:29:42.18,Default,,0000,0000,0000,,bite you. So, so Rails said, you know, we Dialogue: 0,0:29:42.18,0:29:45.84,Default,,0000,0000,0000,,have opinions about how you should write JavaScript. Dialogue: 0,0:29:45.84,0:29:47.60,Default,,0000,0000,0000,,Rails has opinions about how you should maintain\Ndata Dialogue: 0,0:29:47.60,0:29:54.60,Default,,0000,0000,0000,,integrity as well. And so in the Rails world, Dialogue: 0,0:29:54.97,0:29:57.32,Default,,0000,0000,0000,,this is a typical, typical way to handle some, Dialogue: 0,0:29:57.32,0:30:00.04,Default,,0000,0000,0000,,some validation of data integrity, right.\NMaybe you make Dialogue: 0,0:30:00.04,0:30:02.80,Default,,0000,0000,0000,,sure that you have a customer, and you need Dialogue: 0,0:30:02.80,0:30:07.15,Default,,0000,0000,0000,,a unique reference number, and you have a\Ntypo Dialogue: 0,0:30:07.15,0:30:08.02,Default,,0000,0000,0000,,there. Dialogue: 0,0:30:08.02,0:30:10.95,Default,,0000,0000,0000,,validates_associates. Validates :associates\Nand :line_items, right. And you won't Dialogue: 0,0:30:10.95,0:30:15.52,Default,,0000,0000,0000,,save an order unless its :line_items are valid.\NAnd Dialogue: 0,0:30:15.52,0:30:20.02,Default,,0000,0000,0000,,that's really interesting to me, because objects,\Nunfortunately, you Dialogue: 0,0:30:20.02,0:30:22.82,Default,,0000,0000,0000,,know, they don't really understand their relations\Nto other Dialogue: 0,0:30:22.82,0:30:25.57,Default,,0000,0000,0000,,things very well, because those live somewhere\Nelse. They're Dialogue: 0,0:30:25.57,0:30:28.84,Default,,0000,0000,0000,,in the data store separate, right. And, you\Nknow, Dialogue: 0,0:30:28.84,0:30:30.79,Default,,0000,0000,0000,,I, I really think that it would be great, Dialogue: 0,0:30:30.79,0:30:33.62,Default,,0000,0000,0000,,like, if there was some sort of a system Dialogue: 0,0:30:33.62,0:30:36.15,Default,,0000,0000,0000,,that we could use. So, like, I don't know, Dialogue: 0,0:30:36.15,0:30:41.27,Default,,0000,0000,0000,,it would be like a system for managing, I Dialogue: 0,0:30:41.27,0:30:48.22,Default,,0000,0000,0000,,don't know, relational data, maybe? I don't\Nknow. Dialogue: 0,0:30:48.22,0:30:50.89,Default,,0000,0000,0000,,It would be great if we had one of Dialogue: 0,0:30:50.89,0:30:55.47,Default,,0000,0000,0000,,those. And it turns out that, like, we do. Dialogue: 0,0:30:55.47,0:30:59.00,Default,,0000,0000,0000,,And they are, like, super good at understanding\Nrelationships Dialogue: 0,0:30:59.00,0:31:02.92,Default,,0000,0000,0000,,between data. And they are super good at,\Nat Dialogue: 0,0:31:02.92,0:31:05.23,Default,,0000,0000,0000,,validating the data that goes in and out and Dialogue: 0,0:31:05.23,0:31:09.90,Default,,0000,0000,0000,,ensuring that things are atomic, right, and\Nthat, that Dialogue: 0,0:31:09.90,0:31:12.37,Default,,0000,0000,0000,,our updates are not gonna run into race conditions Dialogue: 0,0:31:12.37,0:31:14.40,Default,,0000,0000,0000,,and the like, right? Dialogue: 0,0:31:14.40,0:31:16.40,Default,,0000,0000,0000,,I mean, and I'm talking about, even the, let's Dialogue: 0,0:31:16.40,0:31:21.59,Default,,0000,0000,0000,,say, less than civilized versions of databases,\Nthose are, Dialogue: 0,0:31:21.59,0:31:24.07,Default,,0000,0000,0000,,those are also able, able to do pretty well Dialogue: 0,0:31:24.07,0:31:27.72,Default,,0000,0000,0000,,at this. Because, Ruby, the Ruby land has\Nto Dialogue: 0,0:31:27.72,0:31:29.55,Default,,0000,0000,0000,,cross a process boundary to know any of this Dialogue: 0,0:31:29.55,0:31:33.11,Default,,0000,0000,0000,,stuff, and that's pretty lossy, really. Dialogue: 0,0:31:33.11,0:31:35.15,Default,,0000,0000,0000,,So, I don't think it would be fair, you Dialogue: 0,0:31:35.15,0:31:36.96,Default,,0000,0000,0000,,know, I've griped a lot at this point about Dialogue: 0,0:31:36.96,0:31:38.29,Default,,0000,0000,0000,,a few of the opinions that I think Rails Dialogue: 0,0:31:38.29,0:31:41.31,Default,,0000,0000,0000,,has, and I feel like you came here hoping Dialogue: 0,0:31:41.31,0:31:43.11,Default,,0000,0000,0000,,that I would offer you some solutions, right.\NI Dialogue: 0,0:31:43.11,0:31:47.63,Default,,0000,0000,0000,,want to show you some solutions that I've\Nfound. Dialogue: 0,0:31:47.63,0:31:53.53,Default,,0000,0000,0000,,These are my solutions. They look pretty nice,\NI Dialogue: 0,0:31:53.53,0:31:54.30,Default,,0000,0000,0000,,think. Dialogue: 0,0:31:54.30,0:31:55.08,Default,,0000,0000,0000,,Science. Dialogue: 0,0:31:55.08,0:32:00.33,Default,,0000,0000,0000,,No. So, I've been doing this thing lately,\Nand Dialogue: 0,0:32:00.33,0:32:04.54,Default,,0000,0000,0000,,I'm calling it IDD. And that stands for Ignorance-Driven Dialogue: 0,0:32:04.54,0:32:10.97,Default,,0000,0000,0000,,Development. It's really blissful. And it's\Nthis, this crazy Dialogue: 0,0:32:10.97,0:32:15.97,Default,,0000,0000,0000,,idea that, like, maybe starting with Rails\Ng model, Dialogue: 0,0:32:15.97,0:32:19.40,Default,,0000,0000,0000,,like starting out thinking about your persistence,\Nis maybe Dialogue: 0,0:32:19.40,0:32:21.30,Default,,0000,0000,0000,,not the way to go. Dialogue: 0,0:32:21.30,0:32:23.47,Default,,0000,0000,0000,,If you're thinking about your persistence\Nfor - I Dialogue: 0,0:32:23.47,0:32:26.47,Default,,0000,0000,0000,,mean, I can tell you, all right. Raise your Dialogue: 0,0:32:26.47,0:32:30.05,Default,,0000,0000,0000,,hand if you have stopped to consider what\Nyour Dialogue: 0,0:32:30.05,0:32:32.13,Default,,0000,0000,0000,,database scheme, schema is gonna look like\Nafter you've Dialogue: 0,0:32:32.13,0:32:33.92,Default,,0000,0000,0000,,typed Rails g model, and you're just kind\Nof Dialogue: 0,0:32:33.92,0:32:37.30,Default,,0000,0000,0000,,frozen there, like, crap. Analysis paralysis\Nsets in, right. Dialogue: 0,0:32:37.30,0:32:40.66,Default,,0000,0000,0000,,Because, like, migrations are a pain and databases\Nare, Dialogue: 0,0:32:40.66,0:32:43.30,Default,,0000,0000,0000,,ew, yuck. We want to do everything in Ruby, Dialogue: 0,0:32:43.30,0:32:44.01,Default,,0000,0000,0000,,right? Dialogue: 0,0:32:44.01,0:32:45.99,Default,,0000,0000,0000,,And, and so that's a problem, right, because\NI Dialogue: 0,0:32:45.99,0:32:47.84,Default,,0000,0000,0000,,don't necessarily know what the best way to\Nstore Dialogue: 0,0:32:47.84,0:32:49.63,Default,,0000,0000,0000,,my data is off the top of my head, Dialogue: 0,0:32:49.63,0:32:52.71,Default,,0000,0000,0000,,right? I may find that out as I go. Dialogue: 0,0:32:52.71,0:32:54.99,Default,,0000,0000,0000,,So here's a crazy idea. Dialogue: 0,0:32:54.99,0:32:57.70,Default,,0000,0000,0000,,Start with Ruby and ignore persistence, off\Nthe bat. Dialogue: 0,0:32:57.70,0:33:00.95,Default,,0000,0000,0000,,Like, probably that is not your domain. Your\Ndomain Dialogue: 0,0:33:00.95,0:33:03.07,Default,,0000,0000,0000,,is not to be a CRUD app. Most of Dialogue: 0,0:33:03.07,0:33:04.84,Default,,0000,0000,0000,,us here, anyway, our domain is not to just Dialogue: 0,0:33:04.84,0:33:06.60,Default,,0000,0000,0000,,be a CRUD app, right. We have some business Dialogue: 0,0:33:06.60,0:33:08.24,Default,,0000,0000,0000,,logic. Dialogue: 0,0:33:08.24,0:33:11.49,Default,,0000,0000,0000,,And after you start with Ruby, then you start Dialogue: 0,0:33:11.49,0:33:14.34,Default,,0000,0000,0000,,to identify the scary things, right. And this\Nis Dialogue: 0,0:33:14.34,0:33:16.24,Default,,0000,0000,0000,,like the part of our domain that we're really Dialogue: 0,0:33:16.24,0:33:19.07,Default,,0000,0000,0000,,scared we're not gonna be able to implement.\NLike, Dialogue: 0,0:33:19.07,0:33:21.02,Default,,0000,0000,0000,,what is the thing that's gonna be super hairy, Dialogue: 0,0:33:21.02,0:33:22.96,Default,,0000,0000,0000,,that we're just kind of like, afraid to tackle, Dialogue: 0,0:33:22.96,0:33:25.90,Default,,0000,0000,0000,,right. And removing the, like, the analysis\Nparalysis that Dialogue: 0,0:33:25.90,0:33:28.16,Default,,0000,0000,0000,,can set in when you're trying to figure out Dialogue: 0,0:33:28.16,0:33:29.70,Default,,0000,0000,0000,,where your, what your data's gonna look like,\Nwhile Dialogue: 0,0:33:29.70,0:33:31.75,Default,,0000,0000,0000,,you're just kind of playing around with, with\Nan Dialogue: 0,0:33:31.75,0:33:33.87,Default,,0000,0000,0000,,algorithm, is great, because it gives you\Nthis sort Dialogue: 0,0:33:33.87,0:33:35.67,Default,,0000,0000,0000,,of power to attack the scary things. You can Dialogue: 0,0:33:35.67,0:33:39.95,Default,,0000,0000,0000,,do, I know it's crazy to say, some TDD Dialogue: 0,0:33:39.95,0:33:41.86,Default,,0000,0000,0000,,and attack these scary things. Dialogue: 0,0:33:41.86,0:33:44.01,Default,,0000,0000,0000,,And it's, the cost of experimentation is a\Nlot Dialogue: 0,0:33:44.01,0:33:46.10,Default,,0000,0000,0000,,lower when you're not messing around running\Nmigrations. You're Dialogue: 0,0:33:46.10,0:33:49.72,Default,,0000,0000,0000,,just running super fast tests. Everything\Nis really nice. Dialogue: 0,0:33:49.72,0:33:51.42,Default,,0000,0000,0000,,And you validate that the business logic that\Nyou're Dialogue: 0,0:33:51.42,0:33:54.08,Default,,0000,0000,0000,,trying to write is going to be sane before Dialogue: 0,0:33:54.08,0:33:56.22,Default,,0000,0000,0000,,you go any further. Dialogue: 0,0:33:56.22,0:33:58.54,Default,,0000,0000,0000,,And so, so what that might look like, for Dialogue: 0,0:33:58.54,0:34:00.88,Default,,0000,0000,0000,,instance, is let's say I have a monster class, Dialogue: 0,0:34:00.88,0:34:03.74,Default,,0000,0000,0000,,right. I simply give it some teeth and some Dialogue: 0,0:34:03.74,0:34:06.08,Default,,0000,0000,0000,,claws, right, and it can bite and it can Dialogue: 0,0:34:06.08,0:34:07.58,Default,,0000,0000,0000,,scratch, and I write my test. And let's just Dialogue: 0,0:34:07.58,0:34:09.77,Default,,0000,0000,0000,,assume that biting and scratching is a very,\Nvery Dialogue: 0,0:34:09.77,0:34:12.67,Default,,0000,0000,0000,,difficult thing for a monster to do, right. Dialogue: 0,0:34:12.67,0:34:15.33,Default,,0000,0000,0000,,And, and so it starts out that way. And Dialogue: 0,0:34:15.33,0:34:17.83,Default,,0000,0000,0000,,you gradually iterate on the things that you\Nwant Dialogue: 0,0:34:17.83,0:34:20.96,Default,,0000,0000,0000,,your monster to do, right. And then what you Dialogue: 0,0:34:20.96,0:34:25.08,Default,,0000,0000,0000,,find out is that, eventually, after having\Niterated through Dialogue: 0,0:34:25.08,0:34:27.75,Default,,0000,0000,0000,,maybe, maybe many, many iterations on what\Nthis class Dialogue: 0,0:34:27.75,0:34:30.60,Default,,0000,0000,0000,,looks like, what its collaborators might look\Nlike, you Dialogue: 0,0:34:30.60,0:34:32.82,Default,,0000,0000,0000,,get to a point where you're like, OK. I Dialogue: 0,0:34:32.82,0:34:34.51,Default,,0000,0000,0000,,know how to make this monster now. I know Dialogue: 0,0:34:34.51,0:34:36.71,Default,,0000,0000,0000,,how to, how to tackle it, right. Dialogue: 0,0:34:36.71,0:34:39.49,Default,,0000,0000,0000,,And now is a time for you to admit Dialogue: 0,0:34:39.49,0:34:42.60,Default,,0000,0000,0000,,persistence. Right, now you start to think,\NOK, well, Dialogue: 0,0:34:42.60,0:34:45.04,Default,,0000,0000,0000,,I've gotta persist this stuff somewhere. I\Nhave some, Dialogue: 0,0:34:45.04,0:34:46.69,Default,,0000,0000,0000,,some things about this business logic that\Nare gonna Dialogue: 0,0:34:46.69,0:34:49.58,Default,,0000,0000,0000,,require me to save some data to the database. Dialogue: 0,0:34:49.58,0:34:51.94,Default,,0000,0000,0000,,And so you decide, well, what database am\NI Dialogue: 0,0:34:51.94,0:34:54.20,Default,,0000,0000,0000,,gonna use? Or is it gonna be NoSQL or Dialogue: 0,0:34:54.20,0:34:55.49,Default,,0000,0000,0000,,is it gonna be SQL or is it gonna Dialogue: 0,0:34:55.49,0:34:59.43,Default,,0000,0000,0000,,be, I don't know, something in memory? Right. Dialogue: 0,0:34:59.43,0:35:03.03,Default,,0000,0000,0000,,And then from that point, let's just say you Dialogue: 0,0:35:03.03,0:35:06.54,Default,,0000,0000,0000,,decide, well, now I'm gonna do some ActiveRecord.\NAnd Dialogue: 0,0:35:06.54,0:35:09.33,Default,,0000,0000,0000,,so you say, all I do is now inherit Dialogue: 0,0:35:09.33,0:35:11.27,Default,,0000,0000,0000,,from ActiveRecord::Base. The teeth and claws\Nare no longer Dialogue: 0,0:35:11.27,0:35:15.79,Default,,0000,0000,0000,,supplied via injection. But instead they come\Nfrom relationships Dialogue: 0,0:35:15.79,0:35:19.14,Default,,0000,0000,0000,,in some way, and we maybe have determined\Nthat Dialogue: 0,0:35:19.14,0:35:23.53,Default,,0000,0000,0000,,we require that we have teeth and claws. Dialogue: 0,0:35:23.53,0:35:25.10,Default,,0000,0000,0000,,And then, you guys are gonna think. You notice Dialogue: 0,0:35:25.10,0:35:28.78,Default,,0000,0000,0000,,there's no methods here, right. Right. No\Nmethods. It's Dialogue: 0,0:35:28.78,0:35:31.66,Default,,0000,0000,0000,,not doing anything yet, except the ActiveRecord\Nstuff. You're Dialogue: 0,0:35:31.66,0:35:33.90,Default,,0000,0000,0000,,gonna think I'm trolling you. But here's what\NI've Dialogue: 0,0:35:33.90,0:35:35.61,Default,,0000,0000,0000,,started to do. Dialogue: 0,0:35:35.61,0:35:41.05,Default,,0000,0000,0000,,I use modules. Now, the way I see it, Dialogue: 0,0:35:41.05,0:35:42.65,Default,,0000,0000,0000,,you know, in firefighting there's this thing\Ncalled a Dialogue: 0,0:35:42.65,0:35:46.51,Default,,0000,0000,0000,,back fire, where it's like, OK, so, when they Dialogue: 0,0:35:46.51,0:35:48.66,Default,,0000,0000,0000,,say, like, fight fire with fire, that's actually\Na Dialogue: 0,0:35:48.66,0:35:51.04,Default,,0000,0000,0000,,thing. And like, I'm like, you know what,\NRails, Dialogue: 0,0:35:51.04,0:35:52.76,Default,,0000,0000,0000,,if you really wanna burn the whole place down, Dialogue: 0,0:35:52.76,0:35:54.38,Default,,0000,0000,0000,,that's OK. I got my own little fire going Dialogue: 0,0:35:54.38,0:35:56.91,Default,,0000,0000,0000,,over here. And it's gonna, it's gonna allow\Nme Dialogue: 0,0:35:56.91,0:35:59.29,Default,,0000,0000,0000,,to have some semblance of order. And let me Dialogue: 0,0:35:59.29,0:36:01.56,Default,,0000,0000,0000,,show you what that looks like. And before\Nyou Dialogue: 0,0:36:01.56,0:36:03.09,Default,,0000,0000,0000,,think that it won't work, I can only just Dialogue: 0,0:36:03.09,0:36:05.84,Default,,0000,0000,0000,,say that it has worked for me. Give it Dialogue: 0,0:36:05.84,0:36:08.62,Default,,0000,0000,0000,,a try. Strangely, I'm not going to prescribe\Nthat Dialogue: 0,0:36:08.62,0:36:10.32,Default,,0000,0000,0000,,it's gonna be the solution for everyone. I\Nknow Dialogue: 0,0:36:10.32,0:36:11.41,Default,,0000,0000,0000,,that's kind of the hip thing to do is Dialogue: 0,0:36:11.41,0:36:14.72,Default,,0000,0000,0000,,to say, like, my solution will work for you. Dialogue: 0,0:36:14.72,0:36:17.35,Default,,0000,0000,0000,,But it worked for me. Dialogue: 0,0:36:17.35,0:36:19.56,Default,,0000,0000,0000,,And what it would look like is this. So Dialogue: 0,0:36:19.56,0:36:23.86,Default,,0000,0000,0000,,I now have behaviors that I expose in modules, Dialogue: 0,0:36:23.86,0:36:30.46,Default,,0000,0000,0000,,right. These behaviors are specifically intended\Nto provide one Dialogue: 0,0:36:30.46,0:36:35.17,Default,,0000,0000,0000,,isolated thing, one isolated capability to\Nthe persisted record, Dialogue: 0,0:36:35.17,0:36:37.39,Default,,0000,0000,0000,,right. And so in this case, like, here is Dialogue: 0,0:36:37.39,0:36:41.74,Default,,0000,0000,0000,,the biting module, for instance, right. And\Nit knows Dialogue: 0,0:36:41.74,0:36:43.27,Default,,0000,0000,0000,,how to bite. And let's say this is after Dialogue: 0,0:36:43.27,0:36:45.04,Default,,0000,0000,0000,,we have developed all of our, all of our Dialogue: 0,0:36:45.04,0:36:47.21,Default,,0000,0000,0000,,stuff in plain Ruby, right, this is what we Dialogue: 0,0:36:47.21,0:36:49.51,Default,,0000,0000,0000,,landed on for what bite need to, need to Dialogue: 0,0:36:49.51,0:36:52.34,Default,,0000,0000,0000,,perform, right. Dialogue: 0,0:36:52.34,0:36:57.80,Default,,0000,0000,0000,,And so once we've done that, we can write Dialogue: 0,0:36:57.80,0:37:00.51,Default,,0000,0000,0000,,a class, you know, we can actually just test Dialogue: 0,0:37:00.51,0:37:03.24,Default,,0000,0000,0000,,against the class that limits the API service\Nthat Dialogue: 0,0:37:03.24,0:37:06.11,Default,,0000,0000,0000,,our behavior interacts with. This was the\Ngoal. Like, Dialogue: 0,0:37:06.11,0:37:10.13,Default,,0000,0000,0000,,this is why I do this at all, is Dialogue: 0,0:37:10.13,0:37:13.17,Default,,0000,0000,0000,,because thinking about how I'm gonna interact\Nwith this, Dialogue: 0,0:37:13.17,0:37:16.18,Default,,0000,0000,0000,,like, essentially infinite API that, that\Na lot of, Dialogue: 0,0:37:16.18,0:37:19.08,Default,,0000,0000,0000,,a lot of Rails provides, particularly ActiveRecord\Nprovides in Dialogue: 0,0:37:19.08,0:37:22.15,Default,,0000,0000,0000,,this case, is, is too hard for me. Cause Dialogue: 0,0:37:22.15,0:37:24.58,Default,,0000,0000,0000,,I'm dumb, OK. So, what I need is some Dialogue: 0,0:37:24.58,0:37:26.40,Default,,0000,0000,0000,,help to help me just be able to see Dialogue: 0,0:37:26.40,0:37:28.18,Default,,0000,0000,0000,,into the test. This is the part of the Dialogue: 0,0:37:28.18,0:37:29.55,Default,,0000,0000,0000,,API I care about. Dialogue: 0,0:37:29.55,0:37:31.84,Default,,0000,0000,0000,,And you may be concerned about this. You may Dialogue: 0,0:37:31.84,0:37:35.25,Default,,0000,0000,0000,,say, this looks a lot like ActiveSupport::Concern.\NI can Dialogue: 0,0:37:35.25,0:37:36.60,Default,,0000,0000,0000,,understand why you would say that. Let me\Nshow Dialogue: 0,0:37:36.60,0:37:39.25,Default,,0000,0000,0000,,you why that's not the case. So, earlier we Dialogue: 0,0:37:39.25,0:37:44.93,Default,,0000,0000,0000,,talked about how ActiveSupport::Concern's\Nprimary goal is to solve Dialogue: 0,0:37:44.93,0:37:48.21,Default,,0000,0000,0000,,the problem of modules that depend on other\Nmodules Dialogue: 0,0:37:48.21,0:37:51.37,Default,,0000,0000,0000,,that modify their base class, right. Dialogue: 0,0:37:51.37,0:37:53.77,Default,,0000,0000,0000,,The intention in this, and that might look\Nlike Dialogue: 0,0:37:53.77,0:37:55.38,Default,,0000,0000,0000,,this. Like, let's say now there's like a whole Dialogue: 0,0:37:55.38,0:37:58.29,Default,,0000,0000,0000,,fighting behavior that might bite and might\Nscratch, we Dialogue: 0,0:37:58.29,0:38:00.50,Default,,0000,0000,0000,,don't know yet. There may be some probability\Nassociated Dialogue: 0,0:38:00.50,0:38:02.87,Default,,0000,0000,0000,,with it, that against a particular target\Nor maybe Dialogue: 0,0:38:02.87,0:38:05.25,Default,,0000,0000,0000,,more than one target or whatever, and so it Dialogue: 0,0:38:05.25,0:38:08.83,Default,,0000,0000,0000,,sort of has this dependency, not just on the Dialogue: 0,0:38:08.83,0:38:11.19,Default,,0000,0000,0000,,API that the class that it's being included\Ninto Dialogue: 0,0:38:11.19,0:38:14.07,Default,,0000,0000,0000,,has, but also the stuff that's getting included\Ninto Dialogue: 0,0:38:14.07,0:38:16.76,Default,,0000,0000,0000,,that class already. So it expects bite and\Nscratch, Dialogue: 0,0:38:16.76,0:38:19.83,Default,,0000,0000,0000,,which are provided by other two behaviors.\NSo, that Dialogue: 0,0:38:19.83,0:38:23.73,Default,,0000,0000,0000,,kind of thing becomes actually painful. That\Nactually becomes Dialogue: 0,0:38:23.73,0:38:27.35,Default,,0000,0000,0000,,painful when you're not using ActiveSupport::Concern. Dialogue: 0,0:38:27.35,0:38:29.97,Default,,0000,0000,0000,,And so, what you actually have here is a Dialogue: 0,0:38:29.97,0:38:32.13,Default,,0000,0000,0000,,canary in the coal mine, a sentinel animal,\Nright. Dialogue: 0,0:38:32.13,0:38:35.21,Default,,0000,0000,0000,,It's, it's something that's telling you, there's\Nthis thing Dialogue: 0,0:38:35.21,0:38:38.24,Default,,0000,0000,0000,,that's doing more than one kind of thing that's Dialogue: 0,0:38:38.24,0:38:43.10,Default,,0000,0000,0000,,more complex, right. And it really isn't fully\Nencapsulated Dialogue: 0,0:38:43.10,0:38:46.21,Default,,0000,0000,0000,,in the stuff that I've got so far. And Dialogue: 0,0:38:46.21,0:38:48.72,Default,,0000,0000,0000,,it leads you to understand that maybe there's\Nanother Dialogue: 0,0:38:48.72,0:38:51.28,Default,,0000,0000,0000,,thing. Like maybe there's an encounter, right,\Nand it Dialogue: 0,0:38:51.28,0:38:53.77,Default,,0000,0000,0000,,might include one or more combatants that\Nselect targets Dialogue: 0,0:38:53.77,0:38:56.29,Default,,0000,0000,0000,,and do one of their actions, right. Either\Nbite Dialogue: 0,0:38:56.29,0:38:59.33,Default,,0000,0000,0000,,or scratch. All right. Dialogue: 0,0:38:59.33,0:39:02.01,Default,,0000,0000,0000,,So, to kind of start to sum things up, Dialogue: 0,0:39:02.01,0:39:04.36,Default,,0000,0000,0000,,it, we, we, a lot of us work in Dialogue: 0,0:39:04.36,0:39:07.66,Default,,0000,0000,0000,,the startup world, right. And it's really\Nfrustrating and Dialogue: 0,0:39:07.66,0:39:09.98,Default,,0000,0000,0000,,surprising to me that we embrace this idea\Nof Dialogue: 0,0:39:09.98,0:39:13.46,Default,,0000,0000,0000,,a minimal, minimum viable product in the startup\Nworld, Dialogue: 0,0:39:13.46,0:39:15.52,Default,,0000,0000,0000,,right. Build the smallest thing that could\Npossibly work Dialogue: 0,0:39:15.52,0:39:17.27,Default,,0000,0000,0000,,and then go from there. Dialogue: 0,0:39:17.27,0:39:21.90,Default,,0000,0000,0000,,I, I kind of feel like in software, the Dialogue: 0,0:39:21.90,0:39:25.55,Default,,0000,0000,0000,,whole goal, really, is to make as few decisions Dialogue: 0,0:39:25.55,0:39:28.54,Default,,0000,0000,0000,,as you possibly can in order to make, get Dialogue: 0,0:39:28.54,0:39:31.42,Default,,0000,0000,0000,,the desired result, right. Every decision\Nyou defer till Dialogue: 0,0:39:31.42,0:39:34.46,Default,,0000,0000,0000,,later is going to give you some capability\Nto Dialogue: 0,0:39:34.46,0:39:37.50,Default,,0000,0000,0000,,be able to react to change, right. So I Dialogue: 0,0:39:37.50,0:39:39.69,Default,,0000,0000,0000,,would like to see us, both in Rails and Dialogue: 0,0:39:39.69,0:39:41.42,Default,,0000,0000,0000,,in the software that we write, start off with Dialogue: 0,0:39:41.42,0:39:46.38,Default,,0000,0000,0000,,fewer opinions. Start off with fewer assumptions.\NMake sure Dialogue: 0,0:39:46.38,0:39:48.45,Default,,0000,0000,0000,,that the floors that we build have a purpose. Dialogue: 0,0:39:48.45,0:39:49.65,Default,,0000,0000,0000,,One great way to do that is to make Dialogue: 0,0:39:49.65,0:39:51.37,Default,,0000,0000,0000,,sure that you can instantiate a lot of the Dialogue: 0,0:39:51.37,0:39:52.26,Default,,0000,0000,0000,,things, right. Dialogue: 0,0:39:52.26,0:39:54.08,Default,,0000,0000,0000,,If you can instantiate a lot of the things Dialogue: 0,0:39:54.08,0:39:55.53,Default,,0000,0000,0000,,then they must have a purpose that we can Dialogue: 0,0:39:55.53,0:39:58.21,Default,,0000,0000,0000,,reason about. We can think about. As opposed\Nto, Dialogue: 0,0:39:58.21,0:40:01.58,Default,,0000,0000,0000,,well, they might modify five hundred methods\Non another Dialogue: 0,0:40:01.58,0:40:06.57,Default,,0000,0000,0000,,class. And in general, just be a considerate\Nsoftware Dialogue: 0,0:40:06.57,0:40:07.04,Default,,0000,0000,0000,,writer. Dialogue: 0,0:40:07.04,0:40:09.26,Default,,0000,0000,0000,,Thanks for your time.