0:00:18.560,0:00:23.780 AKIRA MATSUDA: So. Welcome to Ruby on Rails[br]internal talk. 0:00:24.449,0:00:26.750 This is titled Ruby on Rails Hacking Guide, 0:00:26.750,0:00:30.989 which is deeply inspired by Minero Alki's[br]Legendary Ruby 0:00:30.989,0:00:34.579 book titles Rails- for, Ruby Hacking Guide. 0:00:34.579,0:00:38.719 So, before I get started, let me just introduce 0:00:38.719,0:00:43.590 myself. I am Akira Matsuda - amatsuda on GitHub 0:00:43.590,0:00:47.410 and Twitter. I'm a committer of Ruby and Ruby 0:00:47.410,0:00:52.000 on Rails projects and I'm from Japan. 0:00:52.000,0:00:55.579 As a individual on GitHub, I created a pagination 0:00:55.579,0:01:01.489 library called kaminari and active_decoractor,[br]action_args and et cetera, 0:01:01.489,0:01:04.599 et cetera. Such libraries. 0:01:04.599,0:01:08.149 As a Rails committer, ranked in here, in the 0:01:08.149,0:01:15.149 bottom, like, twenty-seventh. I've done 374[br]commits so far 0:01:15.310,0:01:19.600 and, since I made my first commit about six 0:01:19.600,0:01:20.939 years ago. 0:01:20.939,0:01:23.509 I initially titled this talk as Ruby on Rails 0:01:23.509,0:01:29.429 Hacking Guide, but I slightly changed my mind[br]after 0:01:29.429,0:01:34.109 I listened to DHH's keynote. This talk should[br]be 0:01:34.109,0:01:38.549 titled like Ruby on Rails Reading Guide. Since[br]we're 0:01:38.549,0:01:42.209 actually gonna spend the whole forty minutes[br]just for 0:01:42.209,0:01:46.249 reading the whole framework code. 0:01:46.249,0:01:50.259 And, not gonna talk anything about, like,[br]science. But 0:01:50.259,0:01:57.119 it's like, reading a novel, reading a story.[br]So, 0:01:57.119,0:01:59.489 why should we, why should we read Rails? I 0:01:59.489,0:02:04.179 think we have three big reasons here. 0:02:04.179,0:02:11.179 Firstly, as DHH defined, we're software writers,[br]and you 0:02:11.700,0:02:13.520 need to read a lot in order to be 0:02:13.520,0:02:17.610 a good writer, right. This is obvious. So,[br]we 0:02:17.610,0:02:20.770 need to read Rails to be a good Rails 0:02:20.770,0:02:27.200 programmer. And if you don't understand any[br]piece of 0:02:27.200,0:02:31.069 code in your application, that means you don't[br]really 0:02:31.069,0:02:34.140 understand your application. 0:02:34.140,0:02:38.860 So, don't let a magical piece of code exist 0:02:38.860,0:02:43.040 in your app. I know that Rails applications[br]are 0:02:43.040,0:02:50.040 filled with such magics like, for example,[br]like this. 0:02:50.680,0:02:55.510 It's such simple, just one line of Ruby code, 0:02:55.510,0:02:58.620 in just one method. But it, it really does 0:02:58.620,0:03:03.000 a lot of things for you, right. But we 0:03:03.000,0:03:06.109 need to be able to explain why, why is 0:03:06.109,0:03:13.109 this controller inheriting from ApplicationController[br]inheriting from ActionController::Base? We. 0:03:13.489,0:03:18.129 Or, how the http request actually calls this[br]in 0:03:18.129,0:03:22.650 index Ruby method. Or why are we setting this 0:03:22.650,0:03:28.269 u- users relation into a controller instance[br]variable. Et 0:03:28.269,0:03:30.790 cetera, et cetera. 0:03:30.790,0:03:36.219 Or, think about this example. This, this,[br]this is 0:03:36.219,0:03:41.709 a typical Rails-ish DSL. This reads good.[br]It's pretty 0:03:41.709,0:03:46.950 straight forward for readers, as a documentation.[br]But, you're 0:03:46.950,0:03:51.230 not an application reader, right. We, we're[br]application writer. 0:03:51.230,0:03:54.879 So you have to write this. And as a 0:03:54.879,0:03:57.840 writer, you don't, don't usually write when[br]you don't 0:03:57.840,0:04:02.200 understand what it means, right. 0:04:02.200,0:04:07.400 So, so a question. What, what, what is this 0:04:07.400,0:04:14.400 Rails.application.routes.draw, or get in the[br]second line. Looks like 0:04:15.219,0:04:21.029 a method call taking a hash parameter. What[br]is 0:04:21.029,0:04:26.430 it doing? Who actually knows, who here actually[br]knows 0:04:26.430,0:04:30.430 what's gonna happen with this code? Can explain? 0:04:30.430,0:04:37.430 Right. So, if you think, if you think you 0:04:41.870,0:04:45.970 can explain how this define a route, if, if 0:04:45.970,0:04:50.319 you cannot explain. Sorry. If you cannot explain[br]that 0:04:50.319,0:04:54.430 means for, it's just a magic. And that's why 0:04:54.430,0:04:58.960 you're, you're in this room now, right. So,[br]you'll 0:04:58.960,0:05:03.370 soon get to know what the get means. 0:05:03.370,0:05:08.400 And as the third reason to read Rails code 0:05:08.400,0:05:15.400 is because Rails.has_many :bugs. So, as I[br]told you, 0:05:16.569,0:05:19.050 I patched a lot. And mostly I, I patch 0:05:19.050,0:05:23.190 Rails because I hit bugs in my production[br]application. 0:05:23.190,0:05:29.139 And I guess, you all have the same experience. 0:05:29.139,0:05:34.280 I'm sure. Rails is basically buggy. And we[br]need 0:05:34.280,0:05:37.319 to deal with them. With the bugs. 0:05:37.319,0:05:41.150 So, naturally, Rails programmer job is not[br]just to 0:05:41.150,0:05:45.349 maintain the application, but you also need[br]to maintain 0:05:45.349,0:05:49.080 Rails framework as well. It's our job. And[br]it's 0:05:49.080,0:05:51.280 your job. So we need to be familiar with 0:05:51.280,0:05:55.250 the code base. 0:05:55.250,0:05:59.710 And strangely, this talk is kind of categorized[br]as 0:05:59.710,0:06:06.660 a novice talk. But, I'm not sure. I'm, I'm 0:06:06.660,0:06:13.660 gonna talk about the Rails internal. So. I[br]hope 0:06:14.110,0:06:15.509 you enjoy. 0:06:15.509,0:06:22.509 Let's begin. This is what I'm gonna talk.[br]So, 0:06:25.889,0:06:29.470 first of all, Ruby on Rails is a open-source 0:06:29.470,0:06:36.470 software on GitHub. There's no C-extension[br]inside. So. I 0:06:36.639,0:06:42.330 mean, there's, there's no C-code. 100% Ruby.[br]That means, 0:06:42.330,0:06:44.940 if you're a Ruby programmer, you just can[br]read 0:06:44.940,0:06:51.800 it and, and you can write it if necessary. 0:06:51.800,0:06:54.750 You can get its source code here, by git 0:06:54.750,0:07:01.750 cloning from GitHub. By the way, here's a[br]tiny 0:07:02.319,0:07:09.319 tip. How you can find the GitHub repository[br]for 0:07:10.240,0:07:14.919 the gem you use. You can use, you can 0:07:14.919,0:07:20.090 use a gem named gem-src. It's on, it's here 0:07:20.090,0:07:24.759 on GitHub. And please take a look at this 0:07:24.759,0:07:27.970 repository. This is how you can install it[br]and 0:07:27.970,0:07:29.599 how you can use it. 0:07:29.599,0:07:35.139 I'm not gonna explain here. But. So, what[br]this 0:07:35.139,0:07:40.569 does is after this gem installed, it will[br]automatically 0:07:40.569,0:07:45.560 git, git clone this source from GitHub repository.[br]So, 0:07:45.560,0:07:49.879 you, you need not to memorize the author's[br]name 0:07:49.879,0:07:52.330 or you can not, you don't need to search 0:07:52.330,0:07:58.629 on GitHub. As a gem install, it automatically[br]gets 0:07:58.629,0:08:01.699 the code from GitHub. It's so useful for social 0:08:01.699,0:08:07.169 coders. 0:08:07.169,0:08:14.169 Anyway. Let's go back to the Rails source.[br]Firstly, 0:08:17.539,0:08:21.319 let's see what's included in the gem. To know 0:08:21.319,0:08:24.250 what's included in gem, take a look at the 0:08:24.250,0:08:31.250 gemspec. So this is taken from the file rails.gemspec. 0:08:32.299,0:08:36.919 Here it defines the files included. It looks[br]like 0:08:36.919,0:08:42.729 it doesn't really include any program. It's[br]just documents, 0:08:42.729,0:08:45.000 right. 0:08:45.000,0:08:49.110 And you can find these declarations. A bunch[br]of 0:08:49.110,0:08:56.110 add_dependencies. So that means Rails has[br]no code inside, 0:08:58.060,0:09:03.760 but instead if defines several dependencies.[br]It means that 0:09:03.760,0:09:06.750 this is a meta, meta-gem, meta-package, to[br]install these 0:09:06.750,0:09:12.210 seven gems, right. 0:09:12.210,0:09:19.210 And these seven gems are in the Rails repository. 0:09:21.390,0:09:25.550 And Rails is a full-stack framework, a full-stack[br]MVC 0:09:25.550,0:09:28.410 framework. And all these M and V and C 0:09:28.410,0:09:34.850 are included in this one repository. So we[br]have 0:09:34.850,0:09:39.130 model, view, and controller. 0:09:39.130,0:09:42.070 And we have these gems. I'm sorry it's, can 0:09:42.070,0:09:44.800 you read it? I'm sorry it's hard to read. 0:09:44.800,0:09:51.800 Anyway. We have ActiveRecord, ActionPack and[br]ActionView. And this 0:09:52.380,0:09:59.380 is something called model, and these are views,[br]and 0:09:59.390,0:10:02.850 these are controllers. 0:10:02.850,0:10:07.100 So, Rails gem is a meta-package that depends[br]on 0:10:07.100,0:10:13.890 these seven gems. 0:10:13.890,0:10:16.510 So let's take a look at the Rails server 0:10:16.510,0:10:23.170 command and, and let me explain how, how the 0:10:23.170,0:10:27.420 Rails actually boots. For, starting up the[br]Rails server, 0:10:27.420,0:10:31.010 you just need to run Rails server command.[br]So, 0:10:31.010,0:10:34.720 what's happening internally when you execute[br]this command? 0:10:34.720,0:10:39.330 When I hit the Rails command it actually executes 0:10:39.330,0:10:43.820 bin slash rails in your application. So, let's[br]read 0:10:43.820,0:10:48.530 that file first. That file should look like[br]this. 0:10:48.530,0:10:52.510 It requires config/boot inside your application[br]first, and then 0:10:52.510,0:10:55.040 requires rails/commands. 0:10:55.040,0:11:01.210 Rails/boot looks like this. It just bundles[br]something. I'm 0:11:01.210,0:11:04.260 gonna skip the bundler part, because it's,[br]it's out 0:11:04.260,0:11:08.910 of today's scope, but it, it, it kind of 0:11:08.910,0:11:12.200 tweaks the $LOAD_PATH nicely. 0:11:12.200,0:11:19.200 And so the second line. Rails/commands. It[br]requires rails/commands. 0:11:24.880,0:11:29.240 So where is "rails" directory? You can find[br]"rails" 0:11:29.240,0:11:34.740 directory in the railties gem. There's a gem[br]called 0:11:34.740,0:11:40.460 railties, which I, I didn't explain. So, next[br]chapter 0:11:40.460,0:11:42.090 is about railties. 0:11:42.090,0:11:49.090 What, what actually railties is? Railties[br]is a very 0:11:49.870,0:11:56.570 wisely-crafted tiny library, initially created[br]by Yehuda Katz and 0:11:56.570,0:12:02.260 Carl, Carl Lerche. So let's dive into it. 0:12:02.260,0:12:09.260 Here's the gemspec. The gemspec says this[br]is about 0:12:10.630,0:12:17.130 Rails internals. And the gemspec shows that[br]now this 0:12:17.130,0:12:24.130 gem includes some libraries. Ruby files. Actually,[br]it includes 0:12:25.920,0:12:30.880 like this. So, when you step inside the railties 0:12:30.880,0:12:36.060 lib directory, you'll see these. One directory[br]and one 0:12:36.060,0:12:41.690 file called rails dot rb. 0:12:41.690,0:12:47.080 So these's the rails directory. And this is[br]how 0:12:47.080,0:12:51.990 Rails/commands dot rb looks like in the railties[br]gem. 0:12:51.990,0:12:58.640 It requires commands_tasks, and then invokes[br]a CommandTask with 0:12:58.640,0:13:05.640 a given command name. ARGV, right. 0:13:07.520,0:13:14.520 In this case, so, in this case server, right. 0:13:14.810,0:13:18.060 So this is the file named commands_tasks dot[br]rb. 0:13:18.060,0:13:21.950 It requires rails/commands/server first. So[br]let's take a look 0:13:21.950,0:13:28.950 at rails/commands/server. And this is rails/commands/server.[br]It requires, at 0:13:32.020,0:13:39.020 very top, it requires rails. So, then jump[br]to 0:13:40.480,0:13:43.810 rails dot rb. Rails dot rb was at the 0:13:43.810,0:13:48.450 very top of the repository, right. 0:13:48.450,0:13:51.580 So this is how rails dot rb looks like. 0:13:51.580,0:13:56.770 It requires rails/application. So, let's go[br]to rails/application. And 0:13:56.770,0:14:01.830 it defines a top-level module named Rails. 0:14:01.830,0:14:08.830 So rails/application, it requires rails/engine,[br]and it defines a 0:14:09.130,0:14:14.070 Rails Application class, inheriting Rails[br]Engine. 0:14:14.070,0:14:21.070 So, jump to rails/engine. Now, rails/engine[br]requires rails/railtie and 0:14:23.190,0:14:28.170 it, Rails Engine class inherits from Rails[br]Railtie. So, 0:14:28.170,0:14:31.360 next file is rails/railtie. 0:14:31.360,0:14:38.080 Railtie, it looks like this. It requires rails/initializable[br]and 0:14:38.080,0:14:41.510 rails/configuration. And defines Rails Railtie[br]class, that includes Rails 0:14:41.510,0:14:48.510 Initializable. So next follow the, next file[br]is rails/initializable. 0:14:48.610,0:14:55.610 It defines a Rails Initizable- Initializer. 0:14:58.980,0:15:05.080 So, what we learned so far is, railties defines 0:15:05.080,0:15:12.080 these core classes, like Application, Engine,[br]Railtie, Initializable. Which 0:15:16.520,0:15:23.520 are very, very important. Actually, the core[br]of Rails. 0:15:24.410,0:15:28.870 So railties is like this. It's the core of 0:15:28.870,0:15:32.200 Rails, in the middle. 0:15:32.200,0:15:34.970 And we had something called Plugin as well,[br]but 0:15:34.970,0:15:38.570 it was gone since Rails 4. 0:15:38.570,0:15:45.570 So, let's skip it. So railties is a library 0:15:48.910,0:15:55.910 providing something underneath the Rails Application.[br]And I have 0:15:57.180,0:16:04.180 another answer for you. Railties is, according[br]to Wikipedia, 0:16:08.410,0:16:13.270 this is the definition of something called[br]Railroad tie. 0:16:13.270,0:16:20.270 It's a rectangular piece of wood which is[br]laid 0:16:21.520,0:16:28.520 underneath the rails, sometimes called sleeper,[br]railway sleeper. 0:16:29.070,0:16:35.830 So this is rail ties. Consider this. The applications 0:16:35.830,0:16:42.200 are the trains that run on Rails, and railties, 0:16:42.200,0:16:46.420 Rails is the framework, and railties is something[br]lies 0:16:46.420,0:16:50.510 underneath the Rails framework. This is why[br]they named 0:16:50.510,0:16:55.450 it railties, I guess. This is a beautiful[br]metaphor, 0:16:55.450,0:16:58.190 isn't it? 0:16:58.190,0:17:01.500 So how does it work? Or, how can we 0:17:01.500,0:17:05.939 use it? This is how, how, how it's work. 0:17:05.939,0:17:10.169 We can git grep the whole railtie repository,[br]and 0:17:10.169,0:17:15.900 you can find some uses of railtie. These are 0:17:15.900,0:17:20.939 in, not only in railties, they're actually,[br]these are 0:17:20.939,0:17:25.339 in mailers, ActiveRecord, ActionPack, blah,[br]blah, blah. 0:17:25.339,0:17:30.379 We're gonna take it. So, so let's take a, 0:17:30.379,0:17:34.820 take a look at it, like this. So, each 0:17:34.820,0:17:39.159 component has its own railtie, inheriting[br]from Rails::Railtie, like 0:17:39.159,0:17:43.250 this. This is how we use railtie. 0:17:43.250,0:17:48.690 So, railtie is not only in the core, but 0:17:48.690,0:17:55.690 in, we can find railties everywhere. Railtie.[br]It's inside 0:17:55.690,0:18:00.779 each component, right. And, so, this is what's[br]written 0:18:00.779,0:18:03.580 inside the railtie class. 0:18:03.580,0:18:06.179 It has some, mainly we, we see two kinds 0:18:06.179,0:18:13.179 of class method calls, config and initializer,[br]right. These 0:18:14.429,0:18:21.429 are class method calls to railtie class. So,[br]what's 0:18:22.799,0:18:24.299 config? 0:18:24.299,0:18:31.299 This is the definition. Railtie config create[br]something. Instantiates 0:18:31.679,0:18:38.679 something like Railtie::Configuration. And[br]so config is a instance 0:18:41.639,0:18:47.070 of Railtie::Configuration. Railtie::Configuration[br]is something like this. It, it 0:18:47.070,0:18:52.220 has one method_missing method. And it accepts[br]any method 0:18:52.220,0:18:55.860 call and just stores the given name and arguments 0:18:55.860,0:19:02.570 and block into a class-level hash. 0:19:02.570,0:19:09.570 So, what is initializer? Initializer looks[br]like this. The, 0:19:10.590,0:19:15.600 it just keeps the given block as a proc 0:19:15.600,0:19:22.600 instance, with a name, with a given name,[br]right. 0:19:26.389,0:19:32.610 So, this is everything. This is what railties[br]is 0:19:32.610,0:19:38.019 doing. It, it sets something, some values[br]via config 0:19:38.019,0:19:42.950 method call and initializer method call. And[br]to, to 0:19:42.950,0:19:49.950 use them for the later use. 0:19:51.299,0:19:54.370 And railties is actually class, but it's prohibited[br]to 0:19:54.370,0:19:59.610 instantiate. So, you cannot make a instance[br]of the 0:19:59.610,0:20:06.610 railtie class. Instead, you just can inherit[br]and, when 0:20:07.809,0:20:13.960 inherited, it, it kind of memorizes the, the[br]children 0:20:13.960,0:20:17.889 class names. 0:20:17.889,0:20:24.759 So, this is a summary what, of what railties 0:20:24.759,0:20:27.759 is doing. Railties is a core of Rails that 0:20:27.759,0:20:30.779 provides Railtie, Engine, Application, et[br]cetera, and we can 0:20:30.779,0:20:34.870 find Railtie in other Rails components like[br]ActiveRecord, ActionPack. 0:20:34.870,0:20:38.580 And a railtie can keep config and initializer[br]values. 0:20:38.580,0:20:43.499 And Railtie ties up these railties, all right. 0:20:43.499,0:20:47.009 So, let's see how, how actually Rails server[br]ties 0:20:47.009,0:20:53.999 these up. And how, how Rails server boots.[br]So, 0:20:53.999,0:20:58.169 let's go back to rails/commands/commands_tasks[br]dot rb. After it 0:20:58.169,0:21:03.929 requiring rails/commands/server, it executes,[br]it requires the application and 0:21:03.929,0:21:07.340 then executes server dot start. 0:21:07.340,0:21:14.340 Server dot start is defined here, because[br]it was 0:21:15.909,0:21:22.909 defined in Rails/commands/server. Server dot[br]start calls, just calls 0:21:23.870,0:21:28.470 super. And super is, super class of this class 0:21:28.470,0:21:30.669 is Rack::Server. 0:21:30.669,0:21:36.870 So, welcome to the Rack world. Now, now we 0:21:36.870,0:21:43.870 need to read the Rack code. Oh my god. 0:21:48.330,0:21:51.970 This is not Rack hacking guide, so I'm just 0:21:51.970,0:21:58.970 gonna skip it. It. Anyway. Finally calls something[br]like 0:22:04.019,0:22:11.019 this, via rack/builder. It evaluates this[br]Ruby string. Like, 0:22:16.610,0:22:22.549 Rack::Builder dot new taking contents of config[br]dot ru 0:22:22.549,0:22:26.610 in your application. 0:22:26.610,0:22:33.610 And Rack::Builder just instance_evals the[br]given block. So, this 0:22:35.110,0:22:42.110 is what's written inside your application's[br]config dot ru. 0:22:43.940,0:22:50.940 It requires config/environment dot rb first,[br]and runs Rails.application. 0:22:52.299,0:22:55.220 Run is also a Rack command, I mean, Rack 0:22:55.220,0:22:58.379 method. 0:22:58.379,0:23:05.379 So, I just, I just, like, explained very fast, 0:23:07.519,0:23:11.730 like, how the method, method call goes. How[br]method 0:23:11.730,0:23:15.409 call graph looks like. So, I guess you find 0:23:15.409,0:23:19.759 it difficult to follow, and how can it actually 0:23:19.759,0:23:24.090 follow these method, method call graphs? 0:23:24.090,0:23:30.929 Here's one tip. Just, puts caller from, in[br]a 0:23:30.929,0:23:35.019 file inside your application. For, example,[br]in config dot 0:23:35.019,0:23:39.919 ru file, like this. Just add a puts caller 0:23:39.919,0:23:44.299 here. And run Rails server. Then, you'll get[br]an 0:23:44.299,0:23:50.870 output like this in your console. 0:23:50.870,0:23:55.730 And these, these are basically what I explained.[br]Like, 0:23:55.730,0:24:02.730 we see commands/task and server and, like,[br]Rack::Builder. 0:24:05.919,0:24:12.210 So, this is very useful. Like, when you get 0:24:12.210,0:24:17.940 lost in the Ruby, Ruby jungle, use puts caller 0:24:17.940,0:24:22.869 in caller locations, and that'll show you[br]the path 0:24:22.869,0:24:25.690 to the place you are. 0:24:25.690,0:24:32.690 All right. Anybody, but. The config dot ru[br]file 0:24:33.759,0:24:39.039 requires config/environment.rb, and this is,[br]as you know, what's 0:24:39.039,0:24:44.679 written inside the config/environment.rb.[br]It requires config/application dot rb 0:24:44.679,0:24:47.610 and calls Rails.application.initialize! 0:24:47.610,0:24:54.610 So, Rails.application.initialize! is the very,[br]very important method. As 0:24:57.809,0:25:01.720 you may notice from, because it, it has an 0:25:01.720,0:25:08.720 exclamation mark. This is what's written in[br]application.rb. Since, 0:25:09.220,0:25:13.529 Rails 4 point 1, it, it really has nothing 0:25:13.529,0:25:16.970 in its, in its class. 0:25:16.970,0:25:23.970 But, but it defines a class called Application,[br]inheriting 0:25:24.360,0:25:31.360 from Rails::Application. 0:25:33.499,0:25:39.460 Before that, it requires rails/all and bundles[br]all the 0:25:39.460,0:25:45.330 bundled gems. So this is rails dot, rails/all[br]dot 0:25:45.330,0:25:51.759 rb. What it actually does is something like[br]this. 0:25:51.759,0:25:57.909 It defines, so, it requires all these railties[br]that 0:25:57.909,0:26:04.909 I showed you before. Railties defines configs[br]and initializers, 0:26:06.330,0:26:10.879 as we have seen already. 0:26:10.879,0:26:17.879 And then, we call Rails.application.initialize[br]exclamation. So, so we, 0:26:22.039,0:26:27.929 we define initializers here and load all initializers[br]and 0:26:27.929,0:26:33.049 then initialize exclamation, right. 0:26:33.049,0:26:40.049 So, this is the initialize method. It run_initializers,[br]and 0:26:41.559,0:26:48.559 run_initializers, it calls run, run method[br]for, for each 0:26:53.059,0:26:59.830 initialize- initializable object in the initializers[br]collection. 0:26:59.830,0:27:06.070 So initializable looks like this. Run just[br]executes the 0:27:06.070,0:27:13.070 given argument. I mean, instance_exec through[br]stored proc inside 0:27:13.950,0:27:20.950 the same context, right. I mean, in this case, 0:27:23.080,0:27:27.119 at sign context is actually the application[br]instance, so 0:27:27.119,0:27:34.119 it just instance_execs the stored procs in[br]the initializers. 0:27:34.460,0:27:38.190 In the application's context. 0:27:38.190,0:27:45.190 So, I said initializers collection. Initializers[br]collection is this. 0:27:52.749,0:27:59.749 And initializers, so, initializers, yeah.[br]In rai- railties initializers 0:28:02.239,0:28:07.860 was created like this. So, what, what's in[br]the 0:28:07.860,0:28:13.669 initializer's collection is instances of Rails[br]initializer, initializable initializer. 0:28:13.669,0:28:20.320 Which, each initializer just, just holds a[br]proc instance, 0:28:20.320,0:28:24.159 right. 0:28:24.159,0:28:27.269 And as we've seen already these are called[br]from 0:28:27.269,0:28:33.129 each Railtie classes. 0:28:33.129,0:28:40.129 So. This is, this is what initialize do. And, 0:28:41.129,0:28:45.659 so let's go back to the server. As we've 0:28:45.659,0:28:52.659 seen, the start method calls super. I'm sorry.[br]I'll 0:28:52.730,0:28:54.440 skip this. 0:28:54.440,0:29:01.440 So. Summary. So, this is what we, what the 0:29:02.830,0:29:08.210 railtie does for booting up the Rails server.[br]Finally, 0:29:08.210,0:29:13.669 it runs Rails::Application in config dot ru.[br]Do you 0:29:13.669,0:29:17.610 remember? It's written in config dot ru file.[br]Run. 0:29:17.610,0:29:20.340 Run the application. 0:29:20.340,0:29:26.539 So what is run? What is run method? It's 0:29:26.539,0:29:31.499 defined like this. And with this, with this[br]definition, 0:29:31.499,0:29:38.499 the Rack server calls Rails.application dot[br]call. Rails.application responds 0:29:41.129,0:29:44.789 to call. So you can call this. That means 0:29:44.789,0:29:47.850 Rails.application is a Rack application. 0:29:47.850,0:29:54.489 And Rails.application as a Rack application,[br]it, it has 0:29:54.489,0:29:58.759 a call method like this. It calls super. The 0:29:58.759,0:30:05.759 super, the Rails.application super class was[br]Rails::Engine. So, so 0:30:07.429,0:30:08.999 jump to Rails::Engine. 0:30:08.999,0:30:15.999 Rails::Engine has this like call method. OK.[br]The call 0:30:16.080,0:30:22.769 goes to app dot call. App is something like 0:30:22.769,0:30:28.460 this. It's a config middleware that contains[br]default middleware 0:30:28.460,0:30:35.460 stack, and the endpoint, something called[br]endpoint. Look at 0:30:36.039,0:30:38.049 this. 0:30:38.049,0:30:44.330 So, what's the end point? End point is a 0:30:44.330,0:30:51.330 route. Route is a ActionDispatch::Routing::RouteSet[br]by default. OK. 0:30:56.169,0:31:03.169 So. So, the next thing is routes. Route is 0:31:06.989,0:31:13.989 usually defined in config/routes dot rb like[br]this. So, 0:31:14.379,0:31:21.289 let's think of this simple route. Routes,[br]Rails.application.routes is, 0:31:21.289,0:31:28.289 is ActionDispatch::Routing::RouteSet. It's[br]defined here in ActionDispatch gem, I'm 0:31:29.159,0:31:33.749 sorry. ActionPack gem in action_dispatch directory. 0:31:33.749,0:31:38.470 It, it also responds to call, as it's a 0:31:38.470,0:31:45.470 Rack application. And call goes to router[br]dot call. 0:31:47.460,0:31:54.460 Router is defined like this. Journey::Router.new.[br]So, so router 0:31:54.690,0:31:57.059 is a Journey thing. 0:31:57.059,0:32:04.059 Then, so Rails.application routes is also[br]a Rack application 0:32:14.080,0:32:17.989 that defines endpoint, and it finally goes[br]to the 0:32:17.989,0:32:20.679 Journey thing. But for now let's go back to 0:32:20.679,0:32:25.590 the Routes.draw DSL. 0:32:25.590,0:32:28.340 Here. 0:32:28.340,0:32:35.340 So, routes.draw is defined like this. It just[br]evaluates 0:32:37.059,0:32:44.059 the given block. In the ActionDispatch routing[br]mapper. So, 0:32:47.570,0:32:54.519 this DSL actually calls ActionDispatch::Routing::Mapper#get[br]method, right. And get 0:32:54.519,0:32:58.799 method is like this. It calls map_method.[br]map_method calls 0:32:58.799,0:33:05.600 match. match calls decomposed_match, and decomposed_match[br]calls add_route. 0:33:05.600,0:33:12.600 So, anyway. It finally goes to Mapper#add_route.[br]And Mapper 0:33:14.190,0:33:21.190 add_route calls Mapping dot new route. And[br]add_route returns 0:33:24.330,0:33:31.330 a, finally, it returns a Journey route. And[br]then, 0:33:31.879,0:33:37.789 like, adds the given, sorry, the traded route[br]into 0:33:37.789,0:33:42.649 the collection. Journey::Routes collection. 0:33:42.649,0:33:49.649 So. So, this is what the Journey does. And, 0:33:51.059,0:33:58.059 what's this? Yeah. It finally calls Mapper[br]to_route, Mapping#to_route, 0:33:58.609,0:34:02.340 so to_route is defined like this. 0:34:02.340,0:34:09.340 I'm just gonna skip this. It's, it just returns 0:34:11.379,0:34:16.219 the given app parameter, which was the endpoint[br]given 0:34:16.219,0:34:21.239 into the methods parameter. So it finally,[br]finally it, 0:34:21.239,0:34:28.010 it returns endpoint. And endpoint is if, if[br]it 0:34:28.010,0:34:32.679 responds_to call, just returns that. And if[br]not, call 0:34:32.679,0:34:34.500 Dispatcher. 0:34:34.500,0:34:41.500 So. So the, the. The hash value can, could 0:34:45.239,0:34:49.750 be respond_to call, for example, like this.[br]Or mounted 0:34:49.750,0:34:53.659 engine, for example. But usually it doesn't[br]respond to 0:34:53.659,0:35:00.660 call, so it calls dispatcher. Dispatcher is[br]a Routing::RouteSet::Dispatcher. 0:35:04.940,0:35:08.080 And Dispatcher is also a Rack app, so it 0:35:08.080,0:35:12.190 can be called. And the call the Dispatcher[br]goes 0:35:12.190,0:35:16.900 to, dispatch method. 0:35:16.900,0:35:23.900 Dispatch, so, it finally goes at the bottom[br]line. 0:35:25.030,0:35:28.470 It finally goes to controller dot action with[br]a 0:35:28.470,0:35:35.470 given action name, dot call. So, so finally,[br]what, 0:35:36.970,0:35:42.730 what the router finally calls is this. FooController[br]dot 0:35:42.730,0:35:49.730 action method with a given action, action[br]name. And 0:35:50.280,0:35:52.830 it returns something callable. 0:35:52.830,0:35:58.790 So, this is the route DSL. get "/hello" => 0:35:58.790,0:36:05.790 "foo#bar" maps to FooController dot action('bar'). 0:36:10.760,0:36:15.090 This is about Journey. And I think I have 0:36:15.090,0:36:17.150 no time, so I'm gonna skip this. I'm gonna 0:36:17.150,0:36:22.200 skip this long Journey. Anyway, it resolves[br]the route. 0:36:22.200,0:36:26.610 So, this is a summary. The, the main point 0:36:26.610,0:36:29.800 is that 'foo#bar' becomes a Rack application[br]generated by 0:36:29.800,0:36:33.740 FooController dot action('bar'). 0:36:33.740,0:36:39.870 So, the final chapter. Controllers and actions.[br]This, what's 0:36:39.870,0:36:42.770 gonna happen when the server got a request?[br]It, 0:36:42.770,0:36:49.770 it, it just calls this. So what is this? 0:36:50.500,0:36:57.500 Firstly, the action method is defined like[br]this. It's, 0:37:00.730,0:37:06.140 it calls the new dot dispatch inside the block. 0:37:06.140,0:37:09.260 New, new means Controller dot new. 0:37:09.260,0:37:16.260 So, dispatch, dispatch method creates set,[br]call set_response! and 0:37:16.430,0:37:20.310 then calls super. So, what this dispatch method[br]does 0:37:20.310,0:37:27.310 is creates Rails response object. And then[br]dispatch method, 0:37:29.720,0:37:34.320 then creates request object. Whoops. 0:37:34.320,0:37:39.990 All right. It sets the request object into[br]the 0:37:39.990,0:37:46.990 instance. And then calls process method. Dispatch[br]finally calls 0:37:47.730,0:37:53.940 ActionController::Metal#process. So, this[br]is what's written inside the process 0:37:53.940,0:37:58.590 method. process method calls process_action,[br]and process_action calls send_action, 0:37:58.590,0:38:05.590 and send_action is aliased to send. Ruby's[br]send method, 0:38:07.140,0:38:09.130 right. 0:38:09.130,0:38:16.130 So, FooController dot action('bar') creates[br]the Rails Request and 0:38:17.140,0:38:21.780 Response objects into the controller instance.[br]Then, it just 0:38:21.780,0:38:25.370 calls, calls the method name bar via Ruby[br]send 0:38:25.370,0:38:28.810 method, OK. 0:38:28.810,0:38:34.240 So, it can be like, FooController dot new,[br]with 0:38:34.240,0:38:38.400 something, dot bar. It's a very simple Ruby[br]method 0:38:38.400,0:38:43.080 call, finally. So, this is what's happening[br]inside the 0:38:43.080,0:38:50.080 HTTP request. When the Rails server accepts[br]the HTTP 0:38:51.980,0:38:57.360 request, it, it kind of, the Journey kind[br]of, 0:38:57.360,0:39:02.060 somehow, resolves the results, and finally[br]calls this simple 0:39:02.060,0:39:06.430 Ruby method. OK? 0:39:06.430,0:39:10.530 And I guess it's, yeah. I guess it's time. 0:39:10.530,0:39:17.530 I have thirty, thirty seconds left. So. 0:39:18.840,0:39:24.270 Obviously there's more and more and more topics[br]about 0:39:24.270,0:39:29.220 Rails internals, but unfortunately I had,[br]I just had 0:39:29.220,0:39:32.090 forty minutes. Forty minutes was not enough[br]to talk 0:39:32.090,0:39:37.740 about, like, ActiveRecord internals or helpers[br]or ActionPack, ActionController 0:39:37.740,0:39:40.940 - these things. 0:39:40.940,0:39:44.920 So, this is the end of my talk. But 0:39:44.920,0:39:49.930 I'm kind of planning to write a book titled 0:39:49.930,0:39:56.930 Ruby on Rails Hacking Guide. So, so hopefully.[br]I'm 0:39:57.580,0:39:59.810 planning to write it in Japanese first and[br]then 0:39:59.810,0:40:03.760 translate it into English later. So, hopefully[br]can find 0:40:03.760,0:40:07.330 it, like, next year, maybe. 0:40:07.330,0:40:12.900 And, yeah. I'll write everything in that book.[br]So 0:40:12.900,0:40:19.900 please wait until the book is coming. Thank[br]you 0:40:19.900,0:40:21.140 very much.