railties 3.1.0.rc1 → 3.1.0.rc2
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +2 -0
- data/guides/assets/images/radar.png +0 -0
- data/guides/assets/images/vijaydev.jpg +0 -0
- data/guides/rails_guides/helpers.rb +1 -1
- data/guides/source/action_view_overview.textile +6 -103
- data/guides/source/active_record_basics.textile +2 -2
- data/guides/source/active_record_querying.textile +32 -4
- data/guides/source/active_record_validations_callbacks.textile +5 -3
- data/guides/source/active_support_core_extensions.textile +4 -4
- data/guides/source/api_documentation_guidelines.textile +2 -2
- data/guides/source/caching_with_rails.textile +5 -5
- data/guides/source/command_line.textile +78 -71
- data/guides/source/configuring.textile +90 -74
- data/guides/source/contribute.textile +2 -2
- data/guides/source/contributing_to_ruby_on_rails.textile +3 -3
- data/guides/source/credits.html.erb +16 -8
- data/guides/source/generators.textile +3 -3
- data/guides/source/getting_started.textile +1 -1
- data/guides/source/i18n.textile +1 -1
- data/guides/source/initialization.textile +311 -310
- data/guides/source/migrations.textile +4 -4
- data/guides/source/rails_on_rack.textile +6 -6
- data/guides/source/routing.textile +1 -1
- data/guides/source/testing.textile +2 -2
- data/lib/rails/application.rb +17 -12
- data/lib/rails/commands.rb +1 -1
- data/lib/rails/commands/benchmarker.rb +3 -3
- data/lib/rails/commands/console.rb +2 -1
- data/lib/rails/commands/profiler.rb +3 -3
- data/lib/rails/commands/server.rb +2 -1
- data/lib/rails/configuration.rb +6 -0
- data/lib/rails/engine.rb +1 -1
- data/lib/rails/generators.rb +8 -2
- data/lib/rails/generators/css/assets/assets_generator.rb +13 -0
- data/lib/rails/generators/{rails/assets/templates/stylesheet.css.scss → css/assets/templates/stylesheet.css} +1 -2
- data/lib/rails/generators/css/scaffold/scaffold_generator.rb +16 -0
- data/lib/rails/generators/rails/app/app_generator.rb +1 -1
- data/lib/rails/generators/rails/app/templates/Gemfile +2 -2
- data/lib/rails/generators/rails/app/templates/config/application.rb +0 -11
- data/lib/rails/generators/rails/app/templates/config/environments/development.rb.tt +3 -0
- data/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt +4 -2
- data/lib/rails/generators/rails/app/templates/config/initializers/wrap_parameters.rb.tt +2 -2
- data/lib/rails/generators/rails/app/templates/test/performance/browsing_test.rb +1 -1
- data/lib/rails/generators/rails/assets/USAGE +1 -1
- data/lib/rails/generators/rails/assets/assets_generator.rb +2 -9
- data/lib/rails/generators/rails/plugin/templates/Rakefile.tt +3 -3
- data/lib/rails/generators/rails/plugin_new/templates/Rakefile +8 -3
- data/lib/rails/generators/rails/scaffold/scaffold_generator.rb +2 -11
- data/lib/rails/generators/test_unit/performance/templates/performance_test.rb +1 -1
- data/lib/rails/railtie.rb +7 -7
- data/lib/rails/railtie/configurable.rb +2 -0
- data/lib/rails/tasks/assets.rake +12 -1
- data/lib/rails/tasks/documentation.rake +8 -2
- data/lib/rails/tasks/misc.rake +1 -1
- data/lib/rails/version.rb +1 -1
- metadata +56 -9
- data/lib/rails/generators/rails/scaffold/templates/scaffold.css.scss +0 -58
@@ -9,18 +9,14 @@ Ruby on Rails Guides: Credits
|
|
9
9
|
|
10
10
|
<% end %>
|
11
11
|
|
12
|
-
<h3 class="section">Rails
|
12
|
+
<h3 class="section">Rails Guides Reviewers</h3>
|
13
13
|
|
14
|
-
<%= author('
|
15
|
-
|
16
|
-
<% end %>
|
17
|
-
|
18
|
-
<%= author('Pratik Naik', 'lifo') do %>
|
19
|
-
Pratik Naik is a Ruby on Rails consultant with <a href="http://www.actionrails.com">ActionRails</a> and also a member of the <a href="http://rubyonrails.org/core">Rails core team</a>. He maintains a blog at <a href="http://m.onkey.org">has_many :bugs, :through => :rails</a> and has an active <a href="http://twitter.com/lifo">twitter account</a>.
|
14
|
+
<%= author('Vijay Dev', 'vijaydev', 'vijaydev.jpg') do %>
|
15
|
+
Vijayakumar, found as Vijay Dev on the web, is a web applications developer and an open source enthusiast who lives in Chennai, India. He started using Rails in 2009 and began actively contributing to Rails documentation in late 2010. He <a href="https://twitter.com/vijay_dev">tweets</a> a lot and also <a href="http://vijaydev.wordpress.com">blogs</a>.
|
20
16
|
<% end %>
|
21
17
|
|
22
18
|
<%= author('Xavier Noria', 'fxn', 'fxn.png') do %>
|
23
|
-
Xavier Noria has been into Ruby on Rails since 2005. He is a Rails
|
19
|
+
Xavier Noria has been into Ruby on Rails since 2005. He is a Rails core team member and enjoys combining his passion for Rails and his past life as a proofreader of math textbooks. Xavier is currently an independent Ruby on Rails consultant. Oh, he also <a href="http://twitter.com/fxn">tweets</a> and can be found everywhere as "fxn".
|
24
20
|
<% end %>
|
25
21
|
|
26
22
|
<h3 class="section">Rails Guides Designers</h3>
|
@@ -31,6 +27,10 @@ Ruby on Rails Guides: Credits
|
|
31
27
|
|
32
28
|
<h3 class="section">Rails Guides Authors</h3>
|
33
29
|
|
30
|
+
<%= author('Ryan Bigg', 'radar', 'radar.png') do %>
|
31
|
+
Ryan Bigg works as a consultant at <a href="http://rubyx.com">RubyX</a> and has been working with Rails since 2006. He's co-authoring a book called <a href="http://manning.com/katz">Rails 3 in Action</a> and he's written many gems which can be seen on <a href="http://github.com/radar">his GitHub page</a> and he also tweets prolifically as <a href="http://twitter.com/ryanbigg">@ryanbigg</a>.
|
32
|
+
<% end %>
|
33
|
+
|
34
34
|
<%= author('Frederick Cheung', 'fcheung') do %>
|
35
35
|
Frederick Cheung is Chief Wizard at Texperts where he has been using Rails since 2006. He is based in Cambridge (UK) and when not consuming fine ales he blogs at <a href="http://www.spacevatican.org">spacevatican.org</a>.
|
36
36
|
<% end %>
|
@@ -43,6 +43,10 @@ Ruby on Rails Guides: Credits
|
|
43
43
|
Jeff Dean is a software engineer with <a href="http://pivotallabs.com">Pivotal Labs</a>.
|
44
44
|
<% end %>
|
45
45
|
|
46
|
+
<%= author('Mike Gunderloy', 'mgunderloy') do %>
|
47
|
+
Mike Gunderloy is a consultant with <a href="http://www.actionrails.com">ActionRails</a>. He brings 25 years of experience in a variety of languages to bear on his current work with Rails. His near-daily links and other blogging can be found at <a href="http://afreshcup.com">A Fresh Cup</a> and he <a href="http://twitter.com/MikeG1">twitters</a> too much.
|
48
|
+
<% end %>
|
49
|
+
|
46
50
|
<%= author('Mikel Lindsaar', 'raasdnil') do %>
|
47
51
|
Mikel Lindsaar has been working with Rails since 2006 and is the author of the Ruby <a href="https://github.com/mikel/mail">Mail gem</a> and core contributor (he helped re-write Action Mailer's API). Mikel is the founder of <a href="http://rubyx.com/">RubyX</a>, has a <a href="http://lindsaar.net/">blog</a> and <a href="http://twitter.com/raasdnil">tweets</a>.
|
48
52
|
<% end %>
|
@@ -55,6 +59,10 @@ Ruby on Rails Guides: Credits
|
|
55
59
|
James Miller is a software developer for <a href="http://www.jk-tech.com">JK Tech</a> in San Diego, CA. You can find James on GitHub, Gmail, Twitter, and Freenode as "bensie".
|
56
60
|
<% end %>
|
57
61
|
|
62
|
+
<%= author('Pratik Naik', 'lifo') do %>
|
63
|
+
Pratik Naik is a Ruby on Rails consultant with <a href="http://www.actionrails.com">ActionRails</a> and also a member of the <a href="http://rubyonrails.org/core">Rails core team</a>. He maintains a blog at <a href="http://m.onkey.org">has_many :bugs, :through => :rails</a> and has an active <a href="http://twitter.com/lifo">twitter account</a>.
|
64
|
+
<% end %>
|
65
|
+
|
58
66
|
<%= author('Emilio Tagua', 'miloops') do %>
|
59
67
|
Emilio Tagua —a.k.a. miloops— is an Argentinian entrepreneur, developer, open source contributor and Rails evangelist. Cofounder of <a href="http://eventioz.com">Eventioz</a>. He has been using Rails since 2006 and contributing since early 2008. Can be found at gmail, twitter, freenode, everywhere as "miloops".
|
60
68
|
<% end %>
|
@@ -46,7 +46,7 @@ class InitializerGenerator < Rails::Generators::Base
|
|
46
46
|
end
|
47
47
|
</ruby>
|
48
48
|
|
49
|
-
NOTE: +create_file+ is a method provided by +Thor::Actions
|
49
|
+
NOTE: +create_file+ is a method provided by +Thor::Actions+. Documentation for +create_file+ and other Thor methods can be found in "Thor's documentation":http://rdoc.info/github/wycats/thor/master/Thor/Actions.html
|
50
50
|
|
51
51
|
Our new generator is quite simple: it inherits from +Rails::Generators::Base+ and has one method definition. Each public method in the generator is executed when a generator is invoked. Finally, we invoke the +create_file+ method that will create a file at the given destination with the given content. If you are familiar with the Rails Application Templates API, you'll feel right at home with the new generators API.
|
52
52
|
|
@@ -131,7 +131,7 @@ And let's execute our generator:
|
|
131
131
|
$ rails generate initializer core_extensions
|
132
132
|
</shell>
|
133
133
|
|
134
|
-
We can see that now
|
134
|
+
We can see that now an initializer named core_extensions was created at +config/initializers/core_extensions.rb+ with the contents of our template. That means that +copy_file+ copied a file in our source root to the destination path we gave. The method +file_name+ is automatically created when we inherit from +Rails::Generators::NamedBase+.
|
135
135
|
|
136
136
|
The methods that are available for generators are covered in the "final section":#generator-methods of this guide.
|
137
137
|
|
@@ -365,7 +365,7 @@ $ rails generate scaffold Comment body:text
|
|
365
365
|
|
366
366
|
Fallbacks allow your generators to have a single responsibility, increasing code reuse and reducing the amount of duplication.
|
367
367
|
|
368
|
-
h3. Application
|
368
|
+
h3. Application Templates
|
369
369
|
|
370
370
|
Now that you've seen how generators can be used _inside_ an application, did you know they can also be used to _generate_ applications too? This kind of generator is referred as a "template".
|
371
371
|
|
@@ -503,7 +503,7 @@ def index
|
|
503
503
|
end
|
504
504
|
</ruby>
|
505
505
|
|
506
|
-
+Post.all+ calls the +Post+ model to return all of the posts currently in the database. The result of this call is an array of posts that we store in
|
506
|
+
+Post.all+ calls the +Post+ model to return all of the posts currently in the database. The result of this call is an array of posts that we store in an instance variable called +@posts+.
|
507
507
|
|
508
508
|
TIP: For more information on finding records with Active Record, see "Active Record Query Interface":active_record_querying.html.
|
509
509
|
|
data/guides/source/i18n.textile
CHANGED
@@ -809,7 +809,7 @@ That does not mean you're stuck with these limitations, though. The Ruby I18n ge
|
|
809
809
|
I18n.backend = Globalize::Backend::Static.new
|
810
810
|
</ruby>
|
811
811
|
|
812
|
-
You can also use the Chain backend to chain multiple backends together. This is useful when you want to use standard translations with a Simple backend but store custom application translations in a database or other backends. For example, you could use the
|
812
|
+
You can also use the Chain backend to chain multiple backends together. This is useful when you want to use standard translations with a Simple backend but store custom application translations in a database or other backends. For example, you could use the Active Record backend and fall back to the (default) Simple backend:
|
813
813
|
|
814
814
|
<ruby>
|
815
815
|
I18n.backend = I18n::Backend::Chain.new(I18n::Backend::ActiveRecord.new, I18n.backend)
|
@@ -20,15 +20,15 @@ h4. +bin/rails+
|
|
20
20
|
The actual +rails+ command is kept in _bin/rails_ at the and goes like this:
|
21
21
|
|
22
22
|
<ruby>
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
23
|
+
#!/usr/bin/env ruby
|
24
|
+
|
25
|
+
begin
|
26
|
+
require "rails/cli"
|
27
|
+
rescue LoadError
|
28
|
+
railties_path = File.expand_path('../../railties/lib', __FILE__)
|
29
|
+
$:.unshift(railties_path)
|
30
|
+
require "rails/cli"
|
31
|
+
end
|
32
32
|
</ruby>
|
33
33
|
|
34
34
|
This file will attempt to load +rails/cli+ and if it cannot find it then add the +railties/lib+ path to the load path (+$:+) and will then try to require it again.
|
@@ -38,22 +38,22 @@ h4. +railites/lib/rails/cli.rb+
|
|
38
38
|
This file looks like this:
|
39
39
|
|
40
40
|
<ruby>
|
41
|
-
|
42
|
-
|
41
|
+
require 'rbconfig'
|
42
|
+
require 'rails/script_rails_loader'
|
43
43
|
|
44
|
-
|
45
|
-
|
46
|
-
|
44
|
+
# If we are inside a Rails application this method performs an exec and thus
|
45
|
+
# the rest of this script is not run.
|
46
|
+
Rails::ScriptRailsLoader.exec_script_rails!
|
47
47
|
|
48
|
-
|
49
|
-
|
48
|
+
require 'rails/ruby_version_check'
|
49
|
+
Signal.trap("INT") { puts; exit }
|
50
50
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
51
|
+
if ARGV.first == 'plugin'
|
52
|
+
ARGV.shift
|
53
|
+
require 'rails/commands/plugin_new'
|
54
|
+
else
|
55
|
+
require 'rails/commands/application'
|
56
|
+
end
|
57
57
|
</ruby>
|
58
58
|
|
59
59
|
The +rbconfig+ file here is out of Ruby's standard library and provides us with the +RbConfig+ class which contains useful information dependent on how Ruby was compiled. We'll see this in use in +railties/lib/rails/script_rails_loader+.
|
@@ -76,46 +76,46 @@ The +rails/script_rails_loader+ file uses +RbConfig::Config+ to gather up the +b
|
|
76
76
|
Back in +rails/cli+, the next line is this:
|
77
77
|
|
78
78
|
<ruby>
|
79
|
-
|
79
|
+
Rails::ScriptRailsLoader.exec_script_rails!
|
80
80
|
</ruby>
|
81
81
|
|
82
82
|
This method is defined in +rails/script_rails_loader+ like this:
|
83
83
|
|
84
84
|
<ruby>
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
end
|
94
|
-
rescue SystemCallError
|
95
|
-
# could not chdir, no problem just return
|
85
|
+
def self.exec_script_rails!
|
86
|
+
cwd = Dir.pwd
|
87
|
+
return unless in_rails_application? || in_rails_application_subdirectory?
|
88
|
+
exec RUBY, SCRIPT_RAILS, *ARGV if in_rails_application?
|
89
|
+
Dir.chdir("..") do
|
90
|
+
# Recurse in a chdir block: if the search fails we want to be sure
|
91
|
+
# the application is generated in the original working directory.
|
92
|
+
exec_script_rails! unless cwd == Dir.pwd
|
96
93
|
end
|
94
|
+
rescue SystemCallError
|
95
|
+
# could not chdir, no problem just return
|
96
|
+
end
|
97
97
|
</ruby>
|
98
98
|
|
99
99
|
This method will first check if the current working directory (+cwd+) is a Rails application or is a subdirectory of one. The way to determine this is defined in the +in_rails_application?+ method like this:
|
100
100
|
|
101
101
|
<ruby>
|
102
|
-
|
103
|
-
|
104
|
-
|
102
|
+
def self.in_rails_application?
|
103
|
+
File.exists?(SCRIPT_RAILS)
|
104
|
+
end
|
105
105
|
</ruby>
|
106
106
|
|
107
107
|
The +SCRIPT_RAILS+ constant defined earlier is used here, with +File.exists?+ checking for its presence in the current directory. If this method returns +false+, then +in_rails_application_subdirectory?+ will be used:
|
108
108
|
|
109
109
|
<ruby>
|
110
|
-
|
111
|
-
|
112
|
-
|
110
|
+
def self.in_rails_application_subdirectory?(path = Pathname.new(Dir.pwd))
|
111
|
+
File.exists?(File.join(path, SCRIPT_RAILS)) || !path.root? && in_rails_application_subdirectory?(path.parent)
|
112
|
+
end
|
113
113
|
</ruby>
|
114
114
|
|
115
115
|
This climbs the directory tree until it reaches a path which contains a +script/rails+ file. If a directory is reached which contains this file then this line will run:
|
116
116
|
|
117
117
|
<ruby>
|
118
|
-
|
118
|
+
exec RUBY, SCRIPT_RAILS, *ARGV if in_rails_application?
|
119
119
|
</ruby>
|
120
120
|
|
121
121
|
This is effectively the same as doing +ruby script/rails [arguments]+. Where +[arguments]+ at this point in time is simply "server".
|
@@ -125,9 +125,9 @@ h4. +script/rails+
|
|
125
125
|
This file looks like this:
|
126
126
|
|
127
127
|
<ruby>
|
128
|
-
|
129
|
-
|
130
|
-
|
128
|
+
APP_PATH = File.expand_path('../../config/application', __FILE__)
|
129
|
+
require File.expand_path('../../config/boot', __FILE__)
|
130
|
+
require 'rails/commands'
|
131
131
|
</ruby>
|
132
132
|
|
133
133
|
The +APP_PATH+ constant here will be used later in +rails/commands+. The +config/boot+ file that +script/rails+ references is the +config/boot.rb+ file in our application which is responsible for loading Bundler and setting it up.
|
@@ -137,19 +137,19 @@ h4. +config/boot.rb+
|
|
137
137
|
+config/boot.rb+ contains this:
|
138
138
|
|
139
139
|
<ruby>
|
140
|
-
|
140
|
+
require 'rubygems'
|
141
141
|
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
142
|
+
# Set up gems listed in the Gemfile.
|
143
|
+
gemfile = File.expand_path('../../Gemfile', __FILE__)
|
144
|
+
begin
|
145
|
+
ENV['BUNDLE_GEMFILE'] = gemfile
|
146
|
+
require 'bundler'
|
147
|
+
Bundler.setup
|
148
|
+
rescue Bundler::GemNotFound => e
|
149
|
+
STDERR.puts e.message
|
150
|
+
STDERR.puts "Try running `bundle install`."
|
151
|
+
exit!
|
152
|
+
end if File.exist?(gemfile)
|
153
153
|
</ruby>
|
154
154
|
|
155
155
|
In a standard Rails application, there's a +Gemfile+ which declares all dependencies of the application. +config/boot.rb+ sets +ENV["BUNDLE_GEMFILE"]+ to the location of this file, then requires Bundler and calls +Bundler.setup+ which adds the dependencies of the application (including all the Rails parts) to the load path, making them available for the application to load. The gems that a Rails 3.1 application depends on are as follows:
|
@@ -186,34 +186,34 @@ h4. +rails/commands.rb+
|
|
186
186
|
Once +config/boot.rb+ has finished, the next file that is required is +rails/commands+ which will execute a command based on the arguments passed in. In this case, the +ARGV+ array simply contains +server+ which is extracted into the +command+ variable using these lines:
|
187
187
|
|
188
188
|
<ruby>
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
189
|
+
aliases = {
|
190
|
+
"g" => "generate",
|
191
|
+
"c" => "console",
|
192
|
+
"s" => "server",
|
193
|
+
"db" => "dbconsole"
|
194
|
+
}
|
195
195
|
|
196
|
-
|
197
|
-
|
196
|
+
command = ARGV.shift
|
197
|
+
command = aliases[command] || command
|
198
198
|
</ruby>
|
199
199
|
|
200
200
|
If we used <tt>s</tt> rather than +server+, Rails will use the +aliases+ defined in the file and match them to their respective commands. With the +server+ command, Rails will run this code:
|
201
201
|
|
202
202
|
<ruby>
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
203
|
+
when 'server'
|
204
|
+
# Change to the application's path if there is no config.ru file in current dir.
|
205
|
+
# This allows us to run script/rails server from other directories, but still get
|
206
|
+
# the main config.ru and properly set the tmp directory.
|
207
|
+
Dir.chdir(File.expand_path('../../', APP_PATH)) unless File.exists?(File.expand_path("config.ru"))
|
208
|
+
|
209
|
+
require 'rails/commands/server'
|
210
|
+
Rails::Server.new.tap { |server|
|
211
|
+
# We need to require application after the server sets environment,
|
212
|
+
# otherwise the --environment option given to the server won't propagate.
|
213
|
+
require APP_PATH
|
214
|
+
Dir.chdir(Rails.application.root)
|
215
|
+
server.start
|
216
|
+
}
|
217
217
|
</ruby>
|
218
218
|
|
219
219
|
This file will change into the root of the directory (a path two directories back from +APP_PATH+ which points at +config/application.rb+), but only if the +config.ru+ file isn't found. This then requires +rails/commands/server+ which requires +action_dispatch+ and sets up the +Rails::Server+ class.
|
@@ -239,7 +239,7 @@ The +methods.rb+ file is responsible for defining methods such as +camelize+, +u
|
|
239
239
|
In this file there are a lot of lines such as this inside the +ActiveSupport+ module:
|
240
240
|
|
241
241
|
<ruby>
|
242
|
-
|
242
|
+
autoload :Inflector
|
243
243
|
</ruby>
|
244
244
|
|
245
245
|
Due to the overriding of the +autoload+ method, Ruby will know to look for this file at +activesupport/lib/active_support/inflector.rb+ when the +Inflector+ class is first referenced.
|
@@ -263,10 +263,10 @@ h4. +rails/commands/server.rb+
|
|
263
263
|
The +Rails::Server+ class is defined in this file as inheriting from +Rack::Server+. When +Rails::Server.new+ is called, this calls the +initialize+ method in +rails/commands/server.rb+:
|
264
264
|
|
265
265
|
<ruby>
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
266
|
+
def initialize(*)
|
267
|
+
super
|
268
|
+
set_environment
|
269
|
+
end
|
270
270
|
</ruby>
|
271
271
|
|
272
272
|
Firstly, +super+ is called which calls the +initialize+ method on +Rack::Server+.
|
@@ -278,10 +278,10 @@ h4. Rack: +lib/rack/server.rb+
|
|
278
278
|
The +initialize+ method in +Rack::Server+ simply sets a couple of variables:
|
279
279
|
|
280
280
|
<ruby>
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
281
|
+
def initialize(options = nil)
|
282
|
+
@options = options
|
283
|
+
@app = options[:app] if options && options[:app]
|
284
|
+
end
|
285
285
|
</ruby>
|
286
286
|
|
287
287
|
In this case, +options+ will be +nil+ so nothing happens in this method.
|
@@ -289,64 +289,64 @@ In this case, +options+ will be +nil+ so nothing happens in this method.
|
|
289
289
|
After +super+ has finished in +Rack::Server+, we jump back to +rails/commands/server.rb+. At this point, +set_environment+ is called within the context of the +Rails::Server+ object and this method doesn't appear to do much at first glance:
|
290
290
|
|
291
291
|
<ruby>
|
292
|
-
|
293
|
-
|
294
|
-
|
292
|
+
def set_environment
|
293
|
+
ENV["RAILS_ENV"] ||= options[:environment]
|
294
|
+
end
|
295
295
|
</ruby>
|
296
296
|
|
297
297
|
In fact, the +options+ method here does quite a lot. This method is defined in +Rack::Server+ like this:
|
298
298
|
|
299
299
|
<ruby>
|
300
|
-
|
301
|
-
|
302
|
-
|
300
|
+
def options
|
301
|
+
@options ||= parse_options(ARGV)
|
302
|
+
end
|
303
303
|
</ruby>
|
304
304
|
|
305
305
|
Then +parse_options+ is defined like this:
|
306
306
|
|
307
307
|
<ruby>
|
308
|
-
|
309
|
-
|
308
|
+
def parse_options(args)
|
309
|
+
options = default_options
|
310
310
|
|
311
|
-
|
312
|
-
|
313
|
-
|
311
|
+
# Don't evaluate CGI ISINDEX parameters.
|
312
|
+
# http://hoohoo.ncsa.uiuc.edu/cgi/cl.html
|
313
|
+
args.clear if ENV.include?("REQUEST_METHOD")
|
314
314
|
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
315
|
+
options.merge! opt_parser.parse! args
|
316
|
+
options[:config] = ::File.expand_path(options[:config])
|
317
|
+
ENV["RACK_ENV"] = options[:environment]
|
318
|
+
options
|
319
|
+
end
|
320
320
|
</ruby>
|
321
321
|
|
322
322
|
With the +default_options+ set to this:
|
323
323
|
|
324
324
|
<ruby>
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
325
|
+
def default_options
|
326
|
+
{
|
327
|
+
:environment => ENV['RACK_ENV'] || "development",
|
328
|
+
:pid => nil,
|
329
|
+
:Port => 9292,
|
330
|
+
:Host => "0.0.0.0",
|
331
|
+
:AccessLog => [],
|
332
|
+
:config => "config.ru"
|
333
|
+
}
|
334
|
+
end
|
335
335
|
</ruby>
|
336
336
|
|
337
337
|
There is no +REQUEST_METHOD+ key in +ENV+ so we can skip over that line. The next line merges in the options from +opt_parser+ which is defined plainly in +Rack::Server+
|
338
338
|
|
339
339
|
<ruby>
|
340
|
-
|
341
|
-
|
342
|
-
|
340
|
+
def opt_parser
|
341
|
+
Options.new
|
342
|
+
end
|
343
343
|
</ruby>
|
344
344
|
|
345
345
|
The class *is* defined in +Rack::Server+, but is overwritten in +Rails::Server+ to take different arguments. Its +parse!+ method begins like this:
|
346
346
|
|
347
347
|
<ruby>
|
348
|
-
|
349
|
-
|
348
|
+
def parse!(args)
|
349
|
+
args, options = args.dup, {}
|
350
350
|
|
351
351
|
opt_parser = OptionParser.new do |opts|
|
352
352
|
opts.banner = "Usage: rails server [mongrel, thin, etc] [options]"
|
@@ -362,100 +362,101 @@ h4. +Rails::Server#start+
|
|
362
362
|
This method is defined like this:
|
363
363
|
|
364
364
|
<ruby>
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
end
|
376
|
-
|
377
|
-
super
|
378
|
-
ensure
|
379
|
-
# The '-h' option calls exit before @options is set.
|
380
|
-
# If we call 'options' with it unset, we get double help banners.
|
381
|
-
puts 'Exiting' unless @options && options[:daemonize]
|
365
|
+
def start
|
366
|
+
puts "=> Booting #{ActiveSupport::Inflector.demodulize(server)}"
|
367
|
+
puts "=> Rails #{Rails.version} application starting in #{Rails.env} on http://#{options[:Host]}:#{options[:Port]}"
|
368
|
+
puts "=> Call with -d to detach" unless options[:daemonize]
|
369
|
+
trap(:INT) { exit }
|
370
|
+
puts "=> Ctrl-C to shutdown server" unless options[:daemonize]
|
371
|
+
|
372
|
+
#Create required tmp directories if not found
|
373
|
+
%w(cache pids sessions sockets).each do |dir_to_make|
|
374
|
+
FileUtils.mkdir_p(Rails.root.join('tmp', dir_to_make))
|
382
375
|
end
|
376
|
+
|
377
|
+
super
|
378
|
+
ensure
|
379
|
+
# The '-h' option calls exit before @options is set.
|
380
|
+
# If we call 'options' with it unset, we get double help banners.
|
381
|
+
puts 'Exiting' unless @options && options[:daemonize]
|
382
|
+
end
|
383
383
|
</ruby>
|
384
384
|
|
385
385
|
This is where the first output of the Rails initialization happens. This method creates a trap for +INT+ signals, so if you +CTRL+C+ the server, it will exit the process. As we can see from the code here, it will create the +tmp/cache+, +tmp/pids+, +tmp/sessions+ and +tmp/sockets+ directories if they don't already exist prior to calling +super+. The +super+ method will call +Rack::Server.start+ which begins its definition like this:
|
386
386
|
|
387
387
|
<ruby>
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
388
|
+
def start
|
389
|
+
if options[:warn]
|
390
|
+
$-w = true
|
391
|
+
end
|
392
392
|
|
393
|
-
|
394
|
-
|
395
|
-
|
393
|
+
if includes = options[:include]
|
394
|
+
$LOAD_PATH.unshift(*includes)
|
395
|
+
end
|
396
396
|
|
397
|
-
|
398
|
-
|
399
|
-
|
397
|
+
if library = options[:require]
|
398
|
+
require library
|
399
|
+
end
|
400
400
|
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
401
|
+
if options[:debug]
|
402
|
+
$DEBUG = true
|
403
|
+
require 'pp'
|
404
|
+
p options[:server]
|
405
|
+
pp wrapped_app
|
406
|
+
pp app
|
407
|
+
end
|
408
|
+
end
|
408
409
|
</ruby>
|
409
410
|
|
410
411
|
In a Rails application, these options are not set at all and therefore aren't used at all. The first line of code that's executed in this method is a call to this method:
|
411
412
|
|
412
413
|
<ruby>
|
413
|
-
|
414
|
+
wrapped_app
|
414
415
|
</ruby>
|
415
416
|
|
416
417
|
This method calls another method:
|
417
418
|
|
418
419
|
<ruby>
|
419
|
-
|
420
|
+
@wrapped_app ||= build_app app
|
420
421
|
</ruby>
|
421
422
|
|
422
423
|
Then the +app+ method here is defined like so:
|
423
424
|
|
424
425
|
<ruby>
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
end
|
430
|
-
|
431
|
-
app, options = Rack::Builder.parse_file(self.options[:config], opt_parser)
|
432
|
-
self.options.merge! options
|
433
|
-
app
|
426
|
+
def app
|
427
|
+
@app ||= begin
|
428
|
+
if !::File.exist? options[:config]
|
429
|
+
abort "configuration #{options[:config]} not found"
|
434
430
|
end
|
431
|
+
|
432
|
+
app, options = Rack::Builder.parse_file(self.options[:config], opt_parser)
|
433
|
+
self.options.merge! options
|
434
|
+
app
|
435
435
|
end
|
436
|
+
end
|
436
437
|
</ruby>
|
437
438
|
|
438
439
|
The +options[:config]+ value defaults to +config.ru+ which contains this:
|
439
440
|
|
440
441
|
<ruby>
|
441
|
-
|
442
|
+
# This file is used by Rack-based servers to start the application.
|
442
443
|
|
443
|
-
|
444
|
-
|
444
|
+
require ::File.expand_path('../config/environment', __FILE__)
|
445
|
+
run YourApp::Application
|
445
446
|
</ruby>
|
446
447
|
|
447
448
|
|
448
449
|
The +Rack::Builder.parse_file+ method here takes the content from this +config.ru+ file and parses it using this code:
|
449
450
|
|
450
451
|
<ruby>
|
451
|
-
|
452
|
+
app = eval "Rack::Builder.new {( " + cfgfile + "\n )}.to_app",
|
452
453
|
TOPLEVEL_BINDING, config
|
453
454
|
</ruby>
|
454
455
|
|
455
456
|
The <ruby>initialize</ruby> method will take the block here and execute it within an instance of +Rack::Builder+. This is where the majority of the initialization process of Rails happens. The chain of events that this simple line sets off will be the focus of a large majority of this guide. The +require+ line for +config/environment.rb+ in +config.ru+ is the first to run:
|
456
457
|
|
457
458
|
<ruby>
|
458
|
-
|
459
|
+
require ::File.expand_path('../config/environment', __FILE__)
|
459
460
|
</ruby>
|
460
461
|
|
461
462
|
h4. +config/environment.rb+
|
@@ -475,7 +476,7 @@ h3. Loading Rails
|
|
475
476
|
The next line in +config/application.rb+ is:
|
476
477
|
|
477
478
|
<ruby>
|
478
|
-
|
479
|
+
require 'rails/all'
|
479
480
|
</ruby>
|
480
481
|
|
481
482
|
h4. +railties/lib/rails/all.rb+
|
@@ -483,20 +484,20 @@ h4. +railties/lib/rails/all.rb+
|
|
483
484
|
This file is responsible for requiring all the individual parts of Rails like so:
|
484
485
|
|
485
486
|
<ruby>
|
486
|
-
|
487
|
+
require "rails"
|
487
488
|
|
488
|
-
|
489
|
+
%w(
|
489
490
|
active_record
|
490
491
|
action_controller
|
491
492
|
action_mailer
|
492
493
|
active_resource
|
493
494
|
rails/test_unit
|
494
|
-
|
495
|
-
|
496
|
-
|
497
|
-
|
498
|
-
end
|
495
|
+
).each do |framework|
|
496
|
+
begin
|
497
|
+
require "#{framework}/railtie"
|
498
|
+
rescue LoadError
|
499
499
|
end
|
500
|
+
end
|
500
501
|
</ruby>
|
501
502
|
|
502
503
|
First off the line is the +rails+ require itself.
|
@@ -518,9 +519,9 @@ h4. +active_support/core_ext/kernel/reporting.rb+
|
|
518
519
|
This is the first of the many Active Support core extensions that come with Rails. This one in particular defines methods in the +Kernel+ module which is mixed in to the +Object+ class so the methods are available on +main+ and can therefore be called like this:
|
519
520
|
|
520
521
|
<ruby>
|
521
|
-
|
522
|
-
|
523
|
-
|
522
|
+
silence_warnings do
|
523
|
+
# some code
|
524
|
+
end
|
524
525
|
</ruby>
|
525
526
|
|
526
527
|
These methods can be used to silence STDERR responses and the +silence_stream+ allows you to also silence other streams. Additionally, this mixin allows you to suppress exceptions and capture streams. For more information see the "Silencing Warnings, Streams, and Exceptions":http://guides.rubyonrails.org/active_support_core_extensions.html#silencing-warnings-streams-and-exceptions section from the Active Support Core Extensions Guide.
|
@@ -635,14 +636,14 @@ h4. +railties/lib/rails/rack.rb+
|
|
635
636
|
The final file to be loaded by +railties/lib/rails/configuration.rb+ is +rails/rack+ which defines some simple autoloads:
|
636
637
|
|
637
638
|
<ruby>
|
638
|
-
|
639
|
-
|
640
|
-
|
641
|
-
|
642
|
-
|
643
|
-
|
644
|
-
end
|
639
|
+
module Rails
|
640
|
+
module Rack
|
641
|
+
autoload :Debugger, "rails/rack/debugger"
|
642
|
+
autoload :Logger, "rails/rack/logger"
|
643
|
+
autoload :LogTailer, "rails/rack/log_tailer"
|
644
|
+
autoload :Static, "rails/rack/static"
|
645
645
|
end
|
646
|
+
end
|
646
647
|
</ruby>
|
647
648
|
|
648
649
|
Once this file is finished loading, then the +Rails::Configuration+ class is initialized. This completes the loading of +railties/lib/rails/configuration.rb+ and now we jump back to the loading of +railties/lib/rails/railtie.rb+, where the next file loaded is +active_support/inflector+.
|
@@ -652,12 +653,12 @@ h4. +activesupport/lib/active_support/inflector.rb+
|
|
652
653
|
+active_support/inflector.rb+ requires a series of file which are responsible for setting up the basics for knowing how to pluralize and singularize words. These files are:
|
653
654
|
|
654
655
|
<ruby>
|
655
|
-
|
656
|
-
|
657
|
-
|
656
|
+
require 'active_support/inflector/inflections'
|
657
|
+
require 'active_support/inflector/transliterate'
|
658
|
+
require 'active_support/inflector/methods'
|
658
659
|
|
659
|
-
|
660
|
-
|
660
|
+
require 'active_support/inflections'
|
661
|
+
require 'active_support/core_ext/string/inflections'
|
661
662
|
</ruby>
|
662
663
|
|
663
664
|
The +active_support/inflector/methods+ file has already been required by +active_support/autoload+ and so won't be loaded again here.
|
@@ -721,22 +722,22 @@ h4. +activesupport/lib/active_support/i18n_railtie.rb+
|
|
721
722
|
This file is the first file that sets up configuration with these lines inside the class:
|
722
723
|
|
723
724
|
<ruby>
|
724
|
-
|
725
|
-
|
726
|
-
|
727
|
-
|
728
|
-
|
725
|
+
class Railtie < Rails::Railtie
|
726
|
+
config.i18n = ActiveSupport::OrderedOptions.new
|
727
|
+
config.i18n.railties_load_path = []
|
728
|
+
config.i18n.load_path = []
|
729
|
+
config.i18n.fallbacks = ActiveSupport::OrderedOptions.new
|
729
730
|
</ruby>
|
730
731
|
|
731
732
|
By inheriting from +Rails::Railtie+ the +Rails::Railtie#inherited+ method is called:
|
732
733
|
|
733
734
|
<ruby>
|
734
|
-
|
735
|
-
|
736
|
-
|
737
|
-
|
738
|
-
end
|
735
|
+
def inherited(base)
|
736
|
+
unless base.abstract_railtie?
|
737
|
+
base.send(:include, Railtie::Configurable)
|
738
|
+
subclasses << base
|
739
739
|
end
|
740
|
+
end
|
740
741
|
</ruby>
|
741
742
|
|
742
743
|
This first checks if the Railtie that's inheriting it is a component of Rails itself:
|
@@ -763,15 +764,15 @@ end
|
|
763
764
|
The +config+ method used at the top of +I18n::Railtie+ is defined on +Rails::Railtie+ and is defined like this:
|
764
765
|
|
765
766
|
<ruby>
|
766
|
-
|
767
|
-
|
768
|
-
|
767
|
+
def config
|
768
|
+
@config ||= Railtie::Configuration.new
|
769
|
+
end
|
769
770
|
</ruby>
|
770
771
|
|
771
772
|
At this point, that +Railtie::Configuration+ constant is automatically loaded which causes the +rails/railties/configuration+ file to be loaded. The line for this is this particular line in +railties/lib/rails/railtie.rb+:
|
772
773
|
|
773
774
|
<ruby>
|
774
|
-
|
775
|
+
autoload :Configuration, "rails/railtie/configuration"
|
775
776
|
</ruby>
|
776
777
|
|
777
778
|
h4. +railties/lib/rails/railtie/configuration.rb+
|
@@ -781,15 +782,15 @@ This file begins with a require out to +rails/configuration+ which has already b
|
|
781
782
|
This file defines the +Rails::Railtie::Configuration+ class which is responsible for providing a way to easily configure railties and it's the +initialize+ method here which is called by the +config+ method back in the +i18n_railtie.rb+ file. The methods on this object don't exist, and so are rescued by the +method_missing+ defined further down in +configuration.rb+:
|
782
783
|
|
783
784
|
<ruby>
|
784
|
-
|
785
|
-
|
786
|
-
|
787
|
-
|
788
|
-
|
789
|
-
|
790
|
-
|
791
|
-
end
|
785
|
+
def method_missing(name, *args, &blk)
|
786
|
+
if name.to_s =~ /=$/
|
787
|
+
@@options[$`.to_sym] = args.first
|
788
|
+
elsif @@options.key?(name)
|
789
|
+
@@options[name]
|
790
|
+
else
|
791
|
+
super
|
792
792
|
end
|
793
|
+
end
|
793
794
|
</ruby>
|
794
795
|
|
795
796
|
So therefore when an option is referred to it simply stores the value as the key if it's used in a setter context, or retrieves it if used in a getter context. Nothing fancy going on there.
|
@@ -799,21 +800,21 @@ h4. Back to +activesupport/lib/active_support/i18n_railtie.rb+
|
|
799
800
|
After the configuration method the +reloader+ method is defined, and then the first of of Railties' initializers is defined: +i18n.callbacks+.
|
800
801
|
|
801
802
|
<ruby>
|
802
|
-
|
803
|
-
|
804
|
-
|
805
|
-
end
|
803
|
+
initializer "i18n.callbacks" do
|
804
|
+
ActionDispatch::Reloader.to_prepare do
|
805
|
+
I18n::Railtie.reloader.execute_if_updated
|
806
806
|
end
|
807
|
+
end
|
807
808
|
</ruby>
|
808
809
|
|
809
810
|
The +initializer+ method (from the +Rails::Initializable+ module) here doesn't run the block, but rather stores it to be run later on:
|
810
811
|
|
811
812
|
<ruby>
|
812
|
-
|
813
|
-
|
814
|
-
|
815
|
-
|
816
|
-
|
813
|
+
def initializer(name, opts = {}, &blk)
|
814
|
+
raise ArgumentError, "A block must be passed when defining an initializer" unless blk
|
815
|
+
opts[:after] ||= initializers.last.name unless initializers.empty? || initializers.find { |i| i.name == opts[:before] }
|
816
|
+
initializers << Initializer.new(name, nil, opts, &blk)
|
817
|
+
end
|
817
818
|
</ruby>
|
818
819
|
|
819
820
|
An initializer can be configured to run before or after another initializer, which we'll see a couple of times throughout this initialization process. Anything that inherits from +Rails::Railtie+ may also make use of the +initializer+ method, something which is covered in the "Configuration guide":[http://ryanbigg.com/guides/configuring.html#rails-railtie-initializer].
|
@@ -821,25 +822,25 @@ An initializer can be configured to run before or after another initializer, whi
|
|
821
822
|
The +Initializer+ class here is defined within the +Rails::Initializable+ module and its +initialize+ method is defined to just set up a couple of variables:
|
822
823
|
|
823
824
|
<ruby>
|
824
|
-
|
825
|
-
|
826
|
-
|
825
|
+
def initialize(name, context, options, &block)
|
826
|
+
@name, @context, @options, @block = name, context, options, block
|
827
|
+
end
|
827
828
|
</ruby>
|
828
829
|
|
829
830
|
Once this +initialize+ method is finished, the object is added to the object the +initializers+ method returns:
|
830
831
|
|
831
832
|
<ruby>
|
832
|
-
|
833
|
-
|
834
|
-
|
833
|
+
def initializers
|
834
|
+
@initializers ||= self.class.initializers_for(self)
|
835
|
+
end
|
835
836
|
</ruby>
|
836
837
|
|
837
838
|
If +@initializers+ isn't set (which it won't be at this point), the +intializers_for+ method will be called for this class.
|
838
839
|
|
839
840
|
<ruby>
|
840
|
-
|
841
|
-
|
842
|
-
|
841
|
+
def initializers_for(binding)
|
842
|
+
Collection.new(initializers_chain.map { |i| i.bind(binding) })
|
843
|
+
end
|
843
844
|
</ruby>
|
844
845
|
|
845
846
|
The +Collection+ class in +railties/lib/rails/initializable.rb+ inherits from +Array+ and includes the +TSort+ module which is used to sort out the order of the initializers based on the order they are placed in.
|
@@ -847,22 +848,22 @@ The +Collection+ class in +railties/lib/rails/initializable.rb+ inherits from +A
|
|
847
848
|
The +initializers_chain+ method referenced in the +initializers_for+ method is defined like this:
|
848
849
|
|
849
850
|
<rub>
|
850
|
-
|
851
|
-
|
852
|
-
|
853
|
-
|
854
|
-
|
855
|
-
end
|
856
|
-
initializers
|
851
|
+
def initializers_chain
|
852
|
+
initializers = Collection.new
|
853
|
+
ancestors.reverse_each do | klass |
|
854
|
+
next unless klass.respond_to?(:initializers)
|
855
|
+
initializers = initializers + klass.initializers
|
857
856
|
end
|
857
|
+
initializers
|
858
|
+
end
|
858
859
|
</ruby>
|
859
860
|
|
860
861
|
This method collects the initializers from the ancestors of this class and adds them to a new +Collection+ object using the <tt>+</tt> method which is defined like this for the <tt>Collection</tt> class:
|
861
862
|
|
862
863
|
<ruby>
|
863
|
-
|
864
|
-
|
865
|
-
|
864
|
+
def +(other)
|
865
|
+
Collection.new(to_a + other.to_a)
|
866
|
+
end
|
866
867
|
</ruby>
|
867
868
|
|
868
869
|
So this <tt>+</tt> method is overriden to return a new collection comprising of the existing collection as an array and then using the <tt>Array#+</tt> method combines these two collections, returning a "super" +Collection+ object. In this case, the only initializer that's going to be in this new +Collection+ object is the +i18n.callbacks+ initializer.
|
@@ -870,34 +871,34 @@ So this <tt>+</tt> method is overriden to return a new collection comprising of
|
|
870
871
|
The next method to be called after this +initializer+ method is the +after_initialize+ method on the +config+ object, which is defined like this:
|
871
872
|
|
872
873
|
<ruby>
|
873
|
-
|
874
|
-
|
875
|
-
|
874
|
+
def after_initialize(&block)
|
875
|
+
ActiveSupport.on_load(:after_initialize, :yield => true, &block)
|
876
|
+
end
|
876
877
|
</ruby>
|
877
878
|
|
878
879
|
The +on_load+ method here is provided by the +active_support/lazy_load_hooks+ file which was required earlier and is defined like this:
|
879
880
|
|
880
881
|
<ruby>
|
881
|
-
|
882
|
-
|
883
|
-
|
884
|
-
|
885
|
-
|
886
|
-
end
|
882
|
+
def self.on_load(name, options = {}, &block)
|
883
|
+
if base = @loaded[name]
|
884
|
+
execute_hook(base, options, block)
|
885
|
+
else
|
886
|
+
@load_hooks[name] << [block, options]
|
887
887
|
end
|
888
|
+
end
|
888
889
|
</ruby>
|
889
890
|
|
890
891
|
The +@loaded+ variable here is a hash containing elements representing the different components of Rails that have been loaded at this stage. Currently, this hash is empty. So the +else+ is executed here, using the +@load_hooks+ variable defined in +active_support/lazy_load_hooks+:
|
891
892
|
|
892
893
|
<ruby>
|
893
|
-
|
894
|
+
@load_hooks = Hash.new {|h,k| h[k] = [] }
|
894
895
|
</ruby>
|
895
896
|
|
896
897
|
This defines a new hash which has keys that default to empty arrays. This saves Rails from having to do something like this instead:
|
897
898
|
|
898
899
|
<ruby>
|
899
|
-
|
900
|
-
|
900
|
+
@load_hooks[name] = []
|
901
|
+
@load_hooks[name] << [block, options]
|
901
902
|
</ruby>
|
902
903
|
|
903
904
|
The value added to this array here consists of the block and options passed to +after_initialize+.
|
@@ -929,11 +930,11 @@ h4. +activesupport/lib/action_dispatch.rb+
|
|
929
930
|
This file attempts to locate the +active_support+ and +active_model+ libraries by looking a couple of directories back from the current file and then adds the +active_support+ and +active_model+ +lib+ directories to the load path, but only if they aren't already, which they are.
|
930
931
|
|
931
932
|
<ruby>
|
932
|
-
|
933
|
-
|
933
|
+
activesupport_path = File.expand_path('../../../activesupport/lib', __FILE__)
|
934
|
+
$:.unshift(activesupport_path) if File.directory?(activesupport_path) && !$:.include?(activesupport_path)
|
934
935
|
|
935
|
-
|
936
|
-
|
936
|
+
activemodel_path = File.expand_path('../../../activemodel/lib', __FILE__)
|
937
|
+
$:.unshift(activemodel_path) if File.directory?(activemodel_path) && !$:.include?(activemodel_path)
|
937
938
|
</ruby>
|
938
939
|
|
939
940
|
In effect, these lines only define the +activesupport_path+ and +activemodel_path+ variables and nothing more.
|
@@ -941,23 +942,23 @@ In effect, these lines only define the +activesupport_path+ and +activemodel_pat
|
|
941
942
|
The next two requires in this file are already done, so they are not run:
|
942
943
|
|
943
944
|
<ruby>
|
944
|
-
|
945
|
-
|
945
|
+
require 'active_support'
|
946
|
+
require 'active_support/dependencies/autoload'
|
946
947
|
</ruby>
|
947
948
|
|
948
949
|
The following require is to +action_pack+ (+activesupport/lib/action_pack.rb+) which has a 22-line copyright notice at the top of it and ends in a simple require to +action_pack/version+. This file, like other +version.rb+ files before it, defines the +ActionPack::VERSION+ constant:
|
949
950
|
|
950
951
|
<ruby>
|
951
|
-
|
952
|
-
|
953
|
-
|
954
|
-
|
955
|
-
|
956
|
-
|
957
|
-
|
958
|
-
|
959
|
-
end
|
952
|
+
module ActionPack
|
953
|
+
module VERSION #:nodoc:
|
954
|
+
MAJOR = 3
|
955
|
+
MINOR = 1
|
956
|
+
TINY = 0
|
957
|
+
PRE = "beta"
|
958
|
+
|
959
|
+
STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.')
|
960
960
|
end
|
961
|
+
end
|
961
962
|
</ruby>
|
962
963
|
|
963
964
|
Once +action_pack+ is finished, then +active_model+ is required.
|
@@ -967,16 +968,16 @@ h4. +activemodel/lib/active_model.rb+
|
|
967
968
|
This file makes a require to +active_model/version+ which defines the version for Active Model:
|
968
969
|
|
969
970
|
<ruby>
|
970
|
-
|
971
|
-
|
972
|
-
|
973
|
-
|
974
|
-
|
975
|
-
|
976
|
-
|
977
|
-
|
978
|
-
end
|
971
|
+
module ActiveModel
|
972
|
+
module VERSION #:nodoc:
|
973
|
+
MAJOR = 3
|
974
|
+
MINOR = 1
|
975
|
+
TINY = 0
|
976
|
+
PRE = "beta"
|
977
|
+
|
978
|
+
STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.')
|
979
979
|
end
|
980
|
+
end
|
980
981
|
</ruby>
|
981
982
|
|
982
983
|
Once the +version.rb+ file is loaded, the +ActiveModel+ module has its autoloaded constants defined as well as a sub-module called +ActiveModel::Serializers+ which has autoloads of its own. When the +ActiveModel+ module is closed the +active_support/i18n+ file is required.
|
@@ -986,15 +987,15 @@ h4. +activesupport/lib/active_support/i18n.rb+
|
|
986
987
|
This is where the +i18n+ gem is required and first configured:
|
987
988
|
|
988
989
|
<ruby>
|
989
|
-
|
990
|
-
|
991
|
-
|
992
|
-
|
993
|
-
|
994
|
-
|
995
|
-
|
990
|
+
begin
|
991
|
+
require 'i18n'
|
992
|
+
require 'active_support/lazy_load_hooks'
|
993
|
+
rescue LoadError => e
|
994
|
+
$stderr.puts "You don't have i18n installed in your application. Please add it to your Gemfile and run bundle install"
|
995
|
+
raise e
|
996
|
+
end
|
996
997
|
|
997
|
-
|
998
|
+
I18n.load_path << "#{File.dirname(__FILE__)}/locale/en.yml"
|
998
999
|
</ruby>
|
999
1000
|
|
1000
1001
|
In effect, the +I18n+ module first defined by +i18n_railtie+ is extended by the +i18n+ gem, rather than the other way around. This has no ill effect. They both work on the same way.
|
@@ -1012,9 +1013,9 @@ h4. Back to +activesupport/lib/action_dispatch.rb+
|
|
1012
1013
|
The remainder of this file requires the +rack+ file from the Rack gem which defines the +Rack+ module. After +rack+, there's autoloads defined for the +Rack+, +ActionDispatch+, +ActionDispatch::Http+, +ActionDispatch::Session+. A new method called +autoload_under+ is used here, and this simply prefixes the files where the modules are autoloaded from with the path specified. For example here:
|
1013
1014
|
|
1014
1015
|
<ruby>
|
1015
|
-
|
1016
|
-
|
1017
|
-
|
1016
|
+
autoload_under 'testing' do
|
1017
|
+
autoload :Assertions
|
1018
|
+
...
|
1018
1019
|
</ruby>
|
1019
1020
|
|
1020
1021
|
The +Assertions+ module is in the +action_dispatch/testing+ folder rather than simply +action_dispatch+.
|
@@ -1046,25 +1047,25 @@ This file begins by detecting if the +lib+ directories of +active_support+ and +
|
|
1046
1047
|
The first three requires have already been done by other files and so aren't loaded here, but the 4th require, the one to +arel+ will require the file provided by the Arel gem, which defines the +Arel+ module.
|
1047
1048
|
|
1048
1049
|
<ruby>
|
1049
|
-
|
1050
|
-
|
1051
|
-
|
1052
|
-
|
1050
|
+
require 'active_support'
|
1051
|
+
require 'active_support/i18n'
|
1052
|
+
require 'active_model'
|
1053
|
+
require 'arel'
|
1053
1054
|
</ruby>
|
1054
1055
|
|
1055
1056
|
The 5th require in this file is one to +active_record/version+ which defines the +ActiveRecord::VERSION+ constant:
|
1056
1057
|
|
1057
1058
|
<ruby>
|
1058
|
-
|
1059
|
-
|
1060
|
-
|
1061
|
-
|
1062
|
-
|
1063
|
-
|
1064
|
-
|
1065
|
-
|
1066
|
-
end
|
1059
|
+
module ActiveRecord
|
1060
|
+
module VERSION #:nodoc:
|
1061
|
+
MAJOR = 3
|
1062
|
+
MINOR = 1
|
1063
|
+
TINY = 0
|
1064
|
+
PRE = "beta"
|
1065
|
+
|
1066
|
+
STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.')
|
1067
1067
|
end
|
1068
|
+
end
|
1068
1069
|
</ruby>
|
1069
1070
|
|
1070
1071
|
Once these requires are finished, the base for the +ActiveRecord+ module is defined along with its autoloads.
|
@@ -1072,9 +1073,9 @@ Once these requires are finished, the base for the +ActiveRecord+ module is defi
|
|
1072
1073
|
Near the end of the file, we see this line:
|
1073
1074
|
|
1074
1075
|
<ruby>
|
1075
|
-
|
1076
|
-
|
1077
|
-
|
1076
|
+
ActiveSupport.on_load(:active_record) do
|
1077
|
+
Arel::Table.engine = self
|
1078
|
+
end
|
1078
1079
|
</ruby>
|
1079
1080
|
|
1080
1081
|
This will set the engine for +Arel::Table+ to be +ActiveRecord::Base+.
|
@@ -1082,7 +1083,7 @@ This will set the engine for +Arel::Table+ to be +ActiveRecord::Base+.
|
|
1082
1083
|
The file then finishes with this line:
|
1083
1084
|
|
1084
1085
|
<ruby>
|
1085
|
-
|
1086
|
+
I18n.load_path << File.dirname(__FILE__) + '/active_record/locale/en.yml'
|
1086
1087
|
</ruby>
|
1087
1088
|
|
1088
1089
|
This will add the translations from +activerecord/lib/active_record/locale/en.yml+ to the load path for +I18n+, with this file being parsed when all the translations are loaded.
|
@@ -1092,8 +1093,8 @@ h4. Back to +activerecord/lib/active_record/railtie.rb+
|
|
1092
1093
|
The next two <tt>require</tt>s in this file aren't run because their files are already required, with +rails+ being required by +rails/all+ and +active_model/railtie+ being required from +action_dispatch+.
|
1093
1094
|
|
1094
1095
|
<ruby>
|
1095
|
-
|
1096
|
-
|
1096
|
+
require "rails"
|
1097
|
+
require "active_model/railtie"
|
1097
1098
|
</ruby>
|
1098
1099
|
|
1099
1100
|
The next +require+ in this file is to +action_controller/railtie+.
|
@@ -1103,9 +1104,9 @@ h4. +actionpack/lib/action_controller/railtie.rb+
|
|
1103
1104
|
This file begins with a couple more requires to files that have already been loaded:
|
1104
1105
|
|
1105
1106
|
<ruby>
|
1106
|
-
|
1107
|
-
|
1108
|
-
|
1107
|
+
require "rails"
|
1108
|
+
require "action_controller"
|
1109
|
+
require "action_dispatch/railtie"
|
1109
1110
|
</ruby>
|
1110
1111
|
|
1111
1112
|
However the require after these is to a file that hasn't yet been loaded, +action_view/railtie+, which begins by requiring +action_view+.
|