railties 3.0.0.beta3 → 3.0.0.beta4
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +5 -0
- data/README +118 -123
- data/guides/source/3_0_release_notes.textile +13 -11
- data/guides/source/action_controller_overview.textile +2 -2
- data/guides/source/action_mailer_basics.textile +70 -26
- data/guides/source/action_view_overview.textile +1 -1
- data/guides/source/active_record_basics.textile +9 -1
- data/guides/source/active_record_querying.textile +2 -2
- data/guides/source/active_support_core_extensions.textile +377 -9
- data/guides/source/activerecord_validations_callbacks.textile +98 -55
- data/guides/source/association_basics.textile +1 -1
- data/guides/source/caching_with_rails.textile +1 -1
- data/guides/source/command_line.textile +23 -23
- data/guides/source/configuring.textile +1 -3
- data/guides/source/contribute.textile +27 -28
- data/guides/source/credits.html.erb +4 -4
- data/guides/source/debugging_rails_applications.textile +2 -2
- data/guides/source/form_helpers.textile +7 -6
- data/guides/source/generators.textile +19 -29
- data/guides/source/getting_started.textile +106 -49
- data/guides/source/i18n.textile +27 -27
- data/guides/source/index.html.erb +18 -8
- data/guides/source/initialization.textile +140 -514
- data/guides/source/layout.html.erb +6 -4
- data/guides/source/layouts_and_rendering.textile +5 -5
- data/guides/source/migrations.textile +7 -3
- data/guides/source/nested_model_forms.textile +2 -2
- data/guides/source/performance_testing.textile +11 -12
- data/guides/source/plugins.textile +30 -30
- data/guides/source/rails_application_templates.textile +3 -3
- data/guides/source/rails_on_rack.textile +3 -66
- data/guides/source/routing.textile +10 -4
- data/guides/source/security.textile +1 -1
- data/guides/source/testing.textile +55 -52
- data/guides/w3c_validator.rb +67 -0
- data/lib/rails.rb +1 -0
- data/lib/rails/application.rb +49 -13
- data/lib/rails/application/bootstrap.rb +7 -6
- data/lib/rails/application/configuration.rb +24 -47
- data/lib/rails/application/finisher.rb +8 -3
- data/lib/rails/backtrace_cleaner.rb +11 -12
- data/lib/rails/commands.rb +54 -54
- data/lib/rails/commands/application.rb +7 -2
- data/lib/rails/commands/{performance/benchmarker.rb → benchmarker.rb} +0 -0
- data/lib/rails/commands/dbconsole.rb +4 -3
- data/lib/rails/commands/destroy.rb +1 -0
- data/lib/rails/commands/generate.rb +1 -0
- data/lib/rails/commands/{performance/profiler.rb → profiler.rb} +0 -0
- data/lib/rails/commands/runner.rb +4 -2
- data/lib/rails/configuration.rb +36 -0
- data/lib/rails/engine.rb +24 -24
- data/lib/rails/engine/configuration.rb +0 -1
- data/lib/rails/generators.rb +48 -10
- data/lib/rails/generators/actions.rb +5 -3
- data/lib/rails/generators/base.rb +23 -17
- data/lib/rails/generators/erb/scaffold/templates/_form.html.erb +9 -8
- data/lib/rails/generators/erb/scaffold/templates/show.html.erb +1 -1
- data/lib/rails/generators/generated_attribute.rb +7 -6
- data/lib/rails/generators/rails/app/USAGE +2 -2
- data/lib/rails/generators/rails/app/app_generator.rb +242 -97
- data/lib/rails/generators/rails/app/templates/Gemfile +3 -0
- data/lib/rails/generators/rails/app/templates/README +167 -130
- data/lib/rails/generators/rails/app/templates/Rakefile +0 -3
- data/lib/rails/generators/rails/app/templates/config/boot.rb +9 -2
- data/lib/rails/generators/rails/app/templates/config/databases/postgresql.yml +5 -5
- data/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt +4 -0
- data/lib/rails/generators/rails/app/templates/script/rails +2 -5
- data/lib/rails/generators/rails/generator/templates/%file_name%_generator.rb.tt +1 -3
- data/lib/rails/generators/rails/stylesheets/templates/scaffold.css +5 -9
- data/lib/rails/generators/test_case.rb +12 -0
- data/lib/rails/generators/test_unit/integration/templates/integration_test.rb +1 -1
- data/lib/rails/generators/test_unit/performance/templates/performance_test.rb +1 -1
- data/lib/rails/info.rb +0 -33
- data/lib/rails/log_subscriber.rb +13 -6
- data/lib/rails/rack/logger.rb +4 -3
- data/lib/rails/railtie.rb +4 -0
- data/lib/rails/railtie/configuration.rb +21 -4
- data/lib/rails/tasks/documentation.rake +2 -0
- data/lib/rails/tasks/framework.rake +22 -0
- data/lib/rails/tasks/middleware.rake +1 -1
- data/lib/rails/tasks/routes.rake +5 -1
- data/lib/rails/test_help.rb +3 -1
- data/lib/rails/test_unit/testing.rake +3 -1
- data/lib/rails/version.rb +1 -1
- metadata +12 -19
- data/lib/rails/application/metal_loader.rb +0 -50
- data/lib/rails/dispatcher.rb +0 -24
- data/lib/rails/generators/rails/mailer/USAGE +0 -15
- data/lib/rails/generators/rails/mailer/mailer_generator.rb +0 -14
- data/lib/rails/generators/rails/mailer/templates/mailer.rb +0 -16
- data/lib/rails/generators/rails/metal/USAGE +0 -8
- data/lib/rails/generators/rails/metal/metal_generator.rb +0 -11
- data/lib/rails/generators/rails/metal/templates/metal.rb +0 -12
data/guides/source/i18n.textile
CHANGED
@@ -97,19 +97,17 @@ The *translations load path* (+I18n.load_path+) is just a Ruby Array of paths to
|
|
97
97
|
|
98
98
|
NOTE: The backend will lazy-load these translations when a translation is looked up for the first time. This makes it possible to just swap the backend with something else even after translations have already been announced.
|
99
99
|
|
100
|
-
The default +
|
100
|
+
The default +application.rb+ files has instructions on how to add locales from another directory and how to set a different default locale. Just uncomment and edit the specific lines.
|
101
101
|
|
102
102
|
<ruby>
|
103
|
-
# The
|
104
|
-
#
|
105
|
-
# All files from config/locales/*.rb,yml are added automatically.
|
106
|
-
# config.i18n.load_path << Dir[File.join(RAILS_ROOT, 'my', 'locales', '*.{rb,yml}')]
|
103
|
+
# The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
|
104
|
+
# config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
|
107
105
|
# config.i18n.default_locale = :de
|
108
106
|
</ruby>
|
109
107
|
|
110
108
|
h4. Optional: Custom I18n Configuration Setup
|
111
109
|
|
112
|
-
For the sake of completeness, let's mention that if you do not want to use the +
|
110
|
+
For the sake of completeness, let's mention that if you do not want to use the +application.rb+ file for some reason, you can always wire up things manually, too.
|
113
111
|
|
114
112
|
To tell the I18n library where it can find your custom translation files you can specify the load path anywhere in your application - just make sure it gets run before any translations are actually looked up. You might also want to change the default locale. The simplest thing possible is to put the following into an initializer:
|
115
113
|
|
@@ -117,8 +115,7 @@ To tell the I18n library where it can find your custom translation files you can
|
|
117
115
|
# in config/initializers/locale.rb
|
118
116
|
|
119
117
|
# tell the I18n library where to find your translations
|
120
|
-
I18n.load_path
|
121
|
-
'*.{rb,yml}') ]
|
118
|
+
I18n.load_path += Dir[Rails.root.join('lib', 'locale', '*.{rb,yml}')]
|
122
119
|
|
123
120
|
# set default locale to something other than :en
|
124
121
|
I18n.default_locale = :pt
|
@@ -126,13 +123,13 @@ I18n.default_locale = :pt
|
|
126
123
|
|
127
124
|
h4. Setting and Passing the Locale
|
128
125
|
|
129
|
-
If you want to translate your Rails application to a *single language other than English* (the default locale), you can set I18n.default_locale to your locale in +
|
126
|
+
If you want to translate your Rails application to a *single language other than English* (the default locale), you can set I18n.default_locale to your locale in +application.rb+ or an initializer as shown above, and it will persist through the requests.
|
130
127
|
|
131
128
|
However, you would probably like to *provide support for more locales* in your application. In such case, you need to set and pass the locale between requests.
|
132
129
|
|
133
130
|
WARNING: You may be tempted to store the chosen locale in a _session_ or a _cookie_. *Do not do so*. The locale should be transparent and a part of the URL. This way you don't break people's basic assumptions about the web itself: if you send a URL of some page to a friend, she should see the same page, same content. A fancy word for this would be that you're being "_RESTful_":http://en.wikipedia.org/wiki/Representational_State_Transfer. Read more about the RESTful approach in "Stefan Tilkov's articles":http://www.infoq.com/articles/rest-introduction. There may be some exceptions to this rule, which are discussed below.
|
134
131
|
|
135
|
-
The _setting part_ is easy. You can set the locale in a +before_filter+ in the ApplicationController like this:
|
132
|
+
The _setting part_ is easy. You can set the locale in a +before_filter+ in the +ApplicationController+ like this:
|
136
133
|
|
137
134
|
<ruby>
|
138
135
|
before_filter :set_locale
|
@@ -161,7 +158,7 @@ You can implement it like this in your +ApplicationController+:
|
|
161
158
|
before_filter :set_locale
|
162
159
|
|
163
160
|
def set_locale
|
164
|
-
I18n.locale =
|
161
|
+
I18n.locale = extract_locale_from_tld
|
165
162
|
end
|
166
163
|
|
167
164
|
# Get locale from top-level domain or return nil if such locale is not available
|
@@ -209,7 +206,7 @@ Getting the locale from +params+ and setting it accordingly is not hard; includi
|
|
209
206
|
|
210
207
|
Rails contains infrastructure for "centralizing dynamic decisions about the URLs" in its "+ApplicationController#default_url_options+":http://api.rubyonrails.org/classes/ActionController/Base.html#M000515, which is useful precisely in this scenario: it enables us to set "defaults" for "+url_for+":http://api.rubyonrails.org/classes/ActionController/Base.html#M000503 and helper methods dependent on it (by implementing/overriding this method).
|
211
208
|
|
212
|
-
We can include something like this in our ApplicationController then:
|
209
|
+
We can include something like this in our +ApplicationController+ then:
|
213
210
|
|
214
211
|
<ruby>
|
215
212
|
# app/controllers/application_controller.rb
|
@@ -227,21 +224,23 @@ You probably want URLs to look like this: +www.example.com/en/books+ (which load
|
|
227
224
|
|
228
225
|
<ruby>
|
229
226
|
# config/routes.rb
|
230
|
-
|
227
|
+
scope "/:locale" do
|
228
|
+
resources :books
|
229
|
+
end
|
231
230
|
</ruby>
|
232
231
|
|
233
232
|
Now, when you call the +books_path+ method you should get +"/en/books"+ (for the default locale). An URL like +http://localhost:3001/nl/books+ should load the Netherlands locale, then, and following calls to +books_path+ should return +"/nl/books"+ (because the locale changed).
|
234
233
|
|
235
|
-
Of course, you need to take special care of the root URL (usually "homepage" or "dashboard") of your application. An URL like +http://localhost:3001/nl+ will not work automatically, because the +
|
234
|
+
Of course, you need to take special care of the root URL (usually "homepage" or "dashboard") of your application. An URL like +http://localhost:3001/nl+ will not work automatically, because the +root :to => "books#index"+ declaration in your +routes.rb+ doesn't take locale into account. (And rightly so: there's only one "root" URL.)
|
236
235
|
|
237
236
|
You would probably need to map URLs like these:
|
238
237
|
|
239
238
|
<ruby>
|
240
239
|
# config/routes.rb
|
241
|
-
|
240
|
+
match '/:locale' => 'dashboard#index'
|
242
241
|
</ruby>
|
243
242
|
|
244
|
-
Do take special care about the *order of your routes*, so this route declaration does not "eat" other ones. (You may want to add it directly before the +
|
243
|
+
Do take special care about the *order of your routes*, so this route declaration does not "eat" other ones. (You may want to add it directly before the +root :to+ declaration.)
|
245
244
|
|
246
245
|
IMPORTANT: This solution has currently one rather big *downside*. Due to the _default_url_options_ implementation, you have to pass the +:id+ option explicitly, like this: +link_to 'Show', book_url(:id => book)+ and not depend on Rails' magic in code like +link_to 'Show', book+. If this should be a problem, have a look at two plugins which simplify work with routes in this way: Sven Fuchs's "routing_filter":http://github.com/svenfuchs/routing-filter/tree/master and Raul Murciano's "translate_routes":http://github.com/raul/translate_routes/tree/master. See also the page "How to encode the current locale in the URL":http://rails-i18n.org/wiki/wikipages/how-to-encode-the-current-locale-in-the-url in the Rails i18n Wiki.
|
247
246
|
|
@@ -288,8 +287,8 @@ You most probably have something like this in one of your applications:
|
|
288
287
|
|
289
288
|
<ruby>
|
290
289
|
# config/routes.rb
|
291
|
-
|
292
|
-
|
290
|
+
Yourapp::Application.routes.draw do |map|
|
291
|
+
root :to => "home#index"
|
293
292
|
end
|
294
293
|
|
295
294
|
# app/controllers/home_controller.rb
|
@@ -422,8 +421,9 @@ This way, you can separate model and model attribute names from text inside view
|
|
422
421
|
NOTE: The default locale loading mechanism in Rails does not load locale files in nested dictionaries, like we have here. So, for this to work, we must explicitly tell Rails to look further:
|
423
422
|
|
424
423
|
<ruby>
|
425
|
-
# config/
|
426
|
-
config.i18n.load_path += Dir[
|
424
|
+
# config/application.rb
|
425
|
+
config.i18n.load_path += Dir[Rails.root.join('config', 'locales', '**', '*.{rb,yml}')]
|
426
|
+
|
427
427
|
</ruby>
|
428
428
|
|
429
429
|
Do check the "Rails i18n Wiki":http://rails-i18n.org/wiki for list of tools available for managing translations.
|
@@ -531,7 +531,7 @@ In many cases you want to abstract your translations so that *variables can be i
|
|
531
531
|
All options besides +:default+ and +:scope+ that are passed to +#translate+ will be interpolated to the translation:
|
532
532
|
|
533
533
|
<ruby>
|
534
|
-
I18n.backend.store_translations :en, :thanks => 'Thanks {
|
534
|
+
I18n.backend.store_translations :en, :thanks => 'Thanks %{name}!'
|
535
535
|
I18n.translate :thanks, :name => 'Jeremy'
|
536
536
|
# => 'Thanks Jeremy!'
|
537
537
|
</ruby>
|
@@ -540,14 +540,14 @@ If a translation uses +:default+ or +:scope+ as an interpolation variable, an I+
|
|
540
540
|
|
541
541
|
h4. Pluralization
|
542
542
|
|
543
|
-
In English there are only one singular and one plural form for a given string, e.g. "1 message" and "2 messages". Other languages ("Arabic":http://
|
543
|
+
In English there are only one singular and one plural form for a given string, e.g. "1 message" and "2 messages". Other languages ("Arabic":http://unicode.org/repos/cldr-tmp/trunk/diff/supplemental/language_plural_rules.html#ar, "Japanese":http://unicode.org/repos/cldr-tmp/trunk/diff/supplemental/language_plural_rules.html#ja, "Russian":http://unicode.org/repos/cldr-tmp/trunk/diff/supplemental/language_plural_rules.html#ru and many more) have different grammars that have additional or fewer "plural forms":http://unicode.org/repos/cldr-tmp/trunk/diff/supplemental/language_plural_rules.html. Thus, the I18n API provides a flexible pluralization feature.
|
544
544
|
|
545
545
|
The +:count+ interpolation variable has a special role in that it both is interpolated to the translation and used to pick a pluralization from the translations according to the pluralization rules defined by CLDR:
|
546
546
|
|
547
547
|
<ruby>
|
548
548
|
I18n.backend.store_translations :en, :inbox => {
|
549
549
|
:one => '1 message',
|
550
|
-
:other => '{
|
550
|
+
:other => '%{count} messages'
|
551
551
|
}
|
552
552
|
I18n.translate :inbox, :count => 2
|
553
553
|
# => '2 messages'
|
@@ -711,7 +711,7 @@ h5. Error Message Interpolation
|
|
711
711
|
|
712
712
|
The translated model name, translated attribute name, and value are always available for interpolation.
|
713
713
|
|
714
|
-
So, for example, instead of the default error message +"can not be blank"+ you could use the attribute name like this : +"Please fill in your {
|
714
|
+
So, for example, instead of the default error message +"can not be blank"+ you could use the attribute name like this : +"Please fill in your %{attribute}"+.
|
715
715
|
|
716
716
|
* +count+, where available, can be used for pluralization if present:
|
717
717
|
|
@@ -750,8 +750,8 @@ en:
|
|
750
750
|
errors:
|
751
751
|
template:
|
752
752
|
header:
|
753
|
-
one: "1 error prohibited this {
|
754
|
-
other: "{
|
753
|
+
one: "1 error prohibited this %{model} from being saved"
|
754
|
+
other: "%{count} errors prohibited this %{model} from being saved"
|
755
755
|
body: "There were problems with the following fields:"
|
756
756
|
</yaml>
|
757
757
|
|
@@ -769,7 +769,7 @@ h5. Action View Helper Methods
|
|
769
769
|
|
770
770
|
h5. Active Record Methods
|
771
771
|
|
772
|
-
* +human_name+ and +human_attribute_name+ use translations for model names and attribute names if available in the "activerecord.models":http://github.com/rails/rails/blob/master/activerecord/lib/active_record/locale/en.yml#
|
772
|
+
* +human_name+ and +human_attribute_name+ use translations for model names and attribute names if available in the "activerecord.models":http://github.com/rails/rails/blob/master/activerecord/lib/active_record/locale/en.yml#L29 scope. They also support translations for inherited class names (e.g. for use with STI) as explained above in "Error message scopes".
|
773
773
|
|
774
774
|
* +ActiveRecord::Errors#generate_message+ (which is used by Active Record validations but may also be used manually) uses +human_name+ and +human_attribute_name+ (see above). It also translates the error message and supports translations for inherited class names as explained above in "Error message scopes".
|
775
775
|
|
@@ -88,10 +88,6 @@ Ruby on Rails Guides
|
|
88
88
|
|
89
89
|
<dl>
|
90
90
|
|
91
|
-
<%= guide("Rails on Rack", 'rails_on_rack.html') do %>
|
92
|
-
<p>This guide covers Rails integration with Rack and interfacing with other Rack components.</p>
|
93
|
-
<% end %>
|
94
|
-
|
95
91
|
<%= guide("Rails Internationalization API", 'i18n.html') do %>
|
96
92
|
<p>This guide covers how to add internationalization to your applications. Your application will be able to translate content to different languages, change pluralization rules, use correct date formats for each country and so on.</p>
|
97
93
|
<% end %>
|
@@ -116,10 +112,6 @@ Ruby on Rails Guides
|
|
116
112
|
<p>This guide covers the various ways of performance testing a Ruby on Rails application.</p>
|
117
113
|
<% end %>
|
118
114
|
|
119
|
-
<%= guide("The Basics of Creating Rails Plugins", 'plugins.html', :ticket => 32) do %>
|
120
|
-
<p>This guide covers how to build a plugin to extend the functionality of Rails.</p>
|
121
|
-
<% end %>
|
122
|
-
|
123
115
|
<%= guide("Configuring Rails Applications", 'configuring.html') do %>
|
124
116
|
<p>This guide covers the basic configuration settings for a Rails application.</p>
|
125
117
|
<% end %>
|
@@ -137,6 +129,24 @@ Ruby on Rails Guides
|
|
137
129
|
<% end %>
|
138
130
|
</dl>
|
139
131
|
|
132
|
+
<h3>Extending Rails</h3>
|
133
|
+
|
134
|
+
<dl>
|
135
|
+
<%= guide("The Basics of Creating Rails Plugins", 'plugins.html', :ticket => 32) do %>
|
136
|
+
<p>This guide covers how to build a plugin to extend the functionality of Rails.</p>
|
137
|
+
<% end %>
|
138
|
+
|
139
|
+
<%= guide("Rails on Rack", 'rails_on_rack.html') do %>
|
140
|
+
<p>This guide covers Rails integration with Rack and interfacing with other Rack components.</p>
|
141
|
+
<% end %>
|
142
|
+
|
143
|
+
<%= guide("Adding Generators", 'generators.html') do %>
|
144
|
+
<p>This guide covers the process of adding a brand new generator to your extension
|
145
|
+
or providing an alternative to an element of a built-in Rails generator (such as
|
146
|
+
providing alternative test stubs for the scaffold generator).</p>
|
147
|
+
<% end %>
|
148
|
+
</dl>
|
149
|
+
|
140
150
|
<h3>Release Notes</h3>
|
141
151
|
|
142
152
|
<dl>
|
@@ -148,7 +148,7 @@ Here the only two gems we need are +rails+ and +sqlite3-ruby+, so it seems. This
|
|
148
148
|
* mime-types-1.16.gem
|
149
149
|
* polyglot-0.3.1.gem
|
150
150
|
* rack-1.1.0.gem
|
151
|
-
* rack-mount-0.6.
|
151
|
+
* rack-mount-0.6.3.gem
|
152
152
|
* rack-test-0.5.3.gem
|
153
153
|
* rails-3.0.0.beta1.gem
|
154
154
|
* railties-3.0.0.beta1.gem
|
@@ -668,7 +668,6 @@ This file requires _rails/railtie.rb_ which defines +Rails::Railtie+.
|
|
668
668
|
* add_routing_namespaces
|
669
669
|
* add_locales
|
670
670
|
* add_view_paths
|
671
|
-
* add_metals
|
672
671
|
* add_generator_templates
|
673
672
|
* load_application_initializers
|
674
673
|
* load_application_classes
|
@@ -726,7 +725,6 @@ This file is used to set up the +Rails::Paths+ module which is used to set up he
|
|
726
725
|
paths.app.helpers "app/helpers", :eager_load => true
|
727
726
|
paths.app.models "app/models", :eager_load => true
|
728
727
|
paths.app.mailers "app/mailers", :eager_load => true
|
729
|
-
paths.app.metals "app/metal", :eager_load => true
|
730
728
|
paths.app.views "app/views", :eager_load => true
|
731
729
|
paths.lib "lib", :load_path => true
|
732
730
|
paths.lib.tasks "lib/tasks", :glob => "**/*.rake"
|
@@ -825,11 +823,11 @@ Now that we've covered the extensive process of what the first line does in this
|
|
825
823
|
end
|
826
824
|
</ruby>
|
827
825
|
|
828
|
-
As you may be able to tell from the code, this is going through and loading all the Railties for
|
826
|
+
As you may be able to tell from the code, this is going through and loading all the Railties for Active Record, Action Controller, Action Mailer, Active Resource. Two other Railties, one for Active Support and one for Action Dispatch were required earlier, but are still covered in this section for continuity reasons. TODO: link.
|
829
827
|
|
830
828
|
h4. ActiveSupport Railtie
|
831
829
|
|
832
|
-
From
|
830
|
+
From Active Support's README:
|
833
831
|
|
834
832
|
Active Support is a collection of various utility classes and standard library extensions that were found useful for Rails.
|
835
833
|
|
@@ -838,13 +836,13 @@ TODO: Quotify.
|
|
838
836
|
h5. +require 'active_support/railtie'+
|
839
837
|
|
840
838
|
|
841
|
-
h4.
|
839
|
+
h4. Active Record Railtie
|
842
840
|
|
843
|
-
The
|
841
|
+
The Active Record Railtie takes care of hooking Active Record into Rails. This depends on Active Support, Active Model and Arel. From Active Record's readme:
|
844
842
|
|
845
843
|
TODO: Quotify.
|
846
844
|
|
847
|
-
<
|
845
|
+
<plain>
|
848
846
|
Active Record connects business objects and database tables to create a persistable domain model where logic and data are presented in one wrapping. It's an implementation of the object-relational mapping (ORM) pattern by the same name as described by Martin Fowler:
|
849
847
|
|
850
848
|
"An object that wraps a row in a database table or view, encapsulates
|
@@ -854,13 +852,13 @@ TODO: Quotify.
|
|
854
852
|
lack of associations and inheritance. By adding a simple domain language-like set of macros to describe
|
855
853
|
the former and integrating the Single Table Inheritance pattern for the latter, Active Record narrows the
|
856
854
|
gap of functionality between the data mapper and active record approach.
|
857
|
-
</
|
855
|
+
</plain>
|
858
856
|
|
859
857
|
h5. +require "active_record/railtie"+
|
860
858
|
|
861
|
-
The _activerecord/lib/active_record/railtie.rb_ file defines the Railtie for
|
859
|
+
The _activerecord/lib/active_record/railtie.rb_ file defines the Railtie for Active Record.
|
862
860
|
|
863
|
-
This file first requires
|
861
|
+
This file first requires Active Record, the _railties/lib/rails.rb_ file which has already been required and so will be ignored, and the Active Model Railtie:
|
864
862
|
|
865
863
|
<ruby>
|
866
864
|
require "active_record"
|
@@ -868,13 +866,13 @@ This file first requires ActiveRecord, the _railties/lib/rails.rb_ file which ha
|
|
868
866
|
require "active_model/railtie"
|
869
867
|
</ruby>
|
870
868
|
|
871
|
-
|
869
|
+
Active Model's Railtie is covered in the next section. TODO: Section.
|
872
870
|
|
873
871
|
h5. +require "active_record"+
|
874
872
|
|
875
873
|
TODO: Why are +activesupport_path+ and +activemodel_path+ defined here?
|
876
874
|
|
877
|
-
The first three requires require ActiveSupport,
|
875
|
+
The first three requires require ActiveSupport, Active Model and ARel in that order:
|
878
876
|
|
879
877
|
<ruby>
|
880
878
|
require 'active_support'
|
@@ -885,17 +883,17 @@ The first three requires require ActiveSupport, ActiveModel and ARel in that ord
|
|
885
883
|
|
886
884
|
h5. +require "active_support"+
|
887
885
|
|
888
|
-
This was loaded earlier by _railties/lib/rails.rb_. This line is here as a safeguard for when
|
886
|
+
This was loaded earlier by _railties/lib/rails.rb_. This line is here as a safeguard for when Active Record is loaded outside the scope of Rails.
|
889
887
|
|
890
888
|
h5. +require "active_model"+
|
891
889
|
|
892
890
|
TODO: Again with the +activesupport_path+!
|
893
891
|
|
894
|
-
Here we see another +require "active_support"+ this is again, a safeguard for when
|
892
|
+
Here we see another +require "active_support"+ this is again, a safeguard for when Active Model is loaded outside the scope of Rails.
|
895
893
|
|
896
|
-
This file defines a few +autoload+'d modules for
|
894
|
+
This file defines a few +autoload+'d modules for Active Model, requires +active_support/i18n+ and adds the default translation file for Active Model to +I18n.load_path+.
|
897
895
|
|
898
|
-
The +require 'active_support/i18n'+ just loads I18n and adds
|
896
|
+
The +require 'active_support/i18n'+ just loads I18n and adds Active Support's default translations file to +I18n.load_path+ too:
|
899
897
|
|
900
898
|
<ruby>
|
901
899
|
require 'i18n'
|
@@ -905,7 +903,7 @@ The +require 'active_support/i18n'+ just loads I18n and adds ActiveSupport's def
|
|
905
903
|
|
906
904
|
h5. +require "arel"+
|
907
905
|
|
908
|
-
This file in _arel/lib/arel.rb_ loads a couple of
|
906
|
+
This file in _arel/lib/arel.rb_ loads a couple of Active Support things first:
|
909
907
|
|
910
908
|
<ruby>
|
911
909
|
require 'active_support/inflector'
|
@@ -917,7 +915,7 @@ These files are explained in the "Common Includes" section.
|
|
917
915
|
|
918
916
|
h5. +require 'arel'+
|
919
917
|
|
920
|
-
Back in _arel/lib/arel.rb_, the next two lines require
|
918
|
+
Back in _arel/lib/arel.rb_, the next two lines require Active Record parts:
|
921
919
|
|
922
920
|
<ruby>
|
923
921
|
require 'active_record'
|
@@ -928,7 +926,7 @@ Because we're currently loading _active_record.rb_, it skips right over it.
|
|
928
926
|
|
929
927
|
h5. +require 'active_record/connection_adapters/abstract/quoting'+
|
930
928
|
|
931
|
-
_activerecord/lib/active_record/connection_adapters/abstract/quoting.rb_ defines methods used for quoting fields and table names in
|
929
|
+
_activerecord/lib/active_record/connection_adapters/abstract/quoting.rb_ defines methods used for quoting fields and table names in Active Record.
|
932
930
|
|
933
931
|
TODO: Explain why this is loaded especially.
|
934
932
|
|
@@ -936,11 +934,11 @@ h5. +require 'active_record'+
|
|
936
934
|
|
937
935
|
Back the initial require from the _railtie.rb_.
|
938
936
|
|
939
|
-
The _active_support_ and _active_model_ requires are again just an insurance for if we're loading
|
937
|
+
The _active_support_ and _active_model_ requires are again just an insurance for if we're loading Active Record outside of the scope of Rails. In _active_record.rb_ the ActiveRecord +Module+ is initialized and in it there is defined a couple of +autoloads+ and +eager_autoloads+.
|
940
938
|
|
941
939
|
There's a new method here called +autoload_under+ which is defined in +ActiveSupport::Autoload+. This sets the autoload path to temporarily be the specified path, in this case +relation+ for the +autoload+'d classes inside the block.
|
942
940
|
|
943
|
-
Inside this file the +AttributeMethods+, +Locking+ and +ConnectionAdapter+ modules are defined inside the +ActiveRecord+ module. The second to last line tells Arel what SQL engine we want to use. In this case it's +ActiveRecord::Base+. The final line adds in the translations for
|
941
|
+
Inside this file the +AttributeMethods+, +Locking+ and +ConnectionAdapter+ modules are defined inside the +ActiveRecord+ module. The second to last line tells Arel what SQL engine we want to use. In this case it's +ActiveRecord::Base+. The final line adds in the translations for Active Record which are only for if a record is invalid or non-unique.
|
944
942
|
|
945
943
|
h5. +require 'rails'+
|
946
944
|
|
@@ -948,15 +946,15 @@ As mentioned previously this is skipped over as it has been already loaded. If y
|
|
948
946
|
|
949
947
|
h5. +require 'active_model/railtie'+
|
950
948
|
|
951
|
-
This is covered in the
|
949
|
+
This is covered in the Active Model Railtie section. TODO: link there.
|
952
950
|
|
953
951
|
h5. +require 'action_controller/railtie'+
|
954
952
|
|
955
|
-
This is covered in the
|
953
|
+
This is covered in the Action Controller Railtie section. TODO: link there.
|
956
954
|
|
957
|
-
h5. The
|
955
|
+
h5. The Active Record Railtie
|
958
956
|
|
959
|
-
Inside the
|
957
|
+
Inside the Active Record Railtie the +ActiveRecord::Railtie+ class is defined:
|
960
958
|
|
961
959
|
<ruby>
|
962
960
|
module ActiveRecord
|
@@ -983,19 +981,19 @@ By doing this the +ActiveRecord::Railtie+ class gains access to the methods cont
|
|
983
981
|
As with the engine initializers, these are explained later.
|
984
982
|
|
985
983
|
|
986
|
-
h4.
|
984
|
+
h4. Active Model Railtie
|
987
985
|
|
988
|
-
This Railtie is +require+'d by
|
986
|
+
This Railtie is +require+'d by Active Record's Railtie.
|
989
987
|
|
990
|
-
From the
|
988
|
+
From the Active Model readme:
|
991
989
|
|
992
|
-
<
|
990
|
+
<plain>
|
993
991
|
Prior to Rails 3.0, if a plugin or gem developer wanted to be able to have an object interact with Action Pack helpers, it was required to either copy chunks of code from Rails, or monkey patch entire helpers to make them handle objects that did not look like Active Record. This generated code duplication and fragile applications that broke on upgrades.
|
994
992
|
|
995
993
|
Active Model is a solution for this problem.
|
996
994
|
|
997
995
|
Active Model provides a known set of interfaces that your objects can implement to then present a common interface to the Action Pack helpers.
|
998
|
-
</
|
996
|
+
</plain>
|
999
997
|
|
1000
998
|
|
1001
999
|
h5. +require "active_model/railtie"+
|
@@ -1009,11 +1007,11 @@ This Railtie file, _activemodel/lib/active_model/railtie.rb_ is quite small and
|
|
1009
1007
|
|
1010
1008
|
h5. +require "active_model"+
|
1011
1009
|
|
1012
|
-
|
1010
|
+
Active Model depends on Active Support and ensures it is required by making a +require 'active_support'+ call. It has already been loaded from _railties/lib/rails.rb_ so will not be reloaded for us here. The file goes on to define the +ActiveModel+ module and all of its autoloaded classes. This file also defines the english translations for some of the validation messages provided by Active Model, such as "is not included in the list" and "is reserved".
|
1013
1011
|
|
1014
1012
|
h4. Action Controller Railtie
|
1015
1013
|
|
1016
|
-
The
|
1014
|
+
The Action Controller Railtie takes care of all the behind-the-scenes code for your controllers; it puts the C into MVC; and does so by implementing the +ActionController::Base+ class which you may recall is where your +ApplicationController+ class descends from.
|
1017
1015
|
|
1018
1016
|
h5. +require 'action_controller/railtie'+
|
1019
1017
|
|
@@ -1025,17 +1023,17 @@ This first makes a couple of requires:
|
|
1025
1023
|
require "action_view/railtie"
|
1026
1024
|
</ruby>
|
1027
1025
|
|
1028
|
-
The _action_controller_ file is explained in the very next section. The require to _rails_ is requiring the already-required _railties/lib/rails.rb_. If you wish to know about the require to _action_view/railtie_ this is explained in the
|
1026
|
+
The _action_controller_ file is explained in the very next section. The require to _rails_ is requiring the already-required _railties/lib/rails.rb_. If you wish to know about the require to _action_view/railtie_ this is explained in the Action View Railtie section.
|
1029
1027
|
|
1030
1028
|
h5. +require 'action_controller+
|
1031
1029
|
|
1032
|
-
This file, _actionpack/lib/action_controller.rb_, defines the
|
1030
|
+
This file, _actionpack/lib/action_controller.rb_, defines the Action Controller module and its relative autoloads. Before it does any of that it makes two requires: one to _abstract_controller_, explored next, and the other to _action_dispatch_, explored directly after that.
|
1033
1031
|
|
1034
1032
|
h5. +require 'abstract_controller'+
|
1035
1033
|
|
1036
1034
|
+AbstractController+ provides the functionality of TODO.
|
1037
1035
|
|
1038
|
-
This file is in _actionpack/lib/abstract_controller.rb_ and begins by attempting to add the path to
|
1036
|
+
This file is in _actionpack/lib/abstract_controller.rb_ and begins by attempting to add the path to Active Support to the load path, which it would succeed in if it wasn't already set by anything loaded before it. In this case, it's not going to be set due to Arel already loading it in (TODO: right?).
|
1039
1037
|
|
1040
1038
|
The next thing in this file four +require+ calls:
|
1041
1039
|
|
@@ -1059,7 +1057,7 @@ This file was loaded upon the first require of +active_support+ and is not inclu
|
|
1059
1057
|
|
1060
1058
|
h5. +require 'active_support/core_ext/module/attr_internal'+
|
1061
1059
|
|
1062
|
-
This file is explained in the "Common Includes" section as it is required again later on. See the TODO: section. I also think this may be explained in the
|
1060
|
+
This file is explained in the "Common Includes" section as it is required again later on. See the TODO: section. I also think this may be explained in the Active Support Core Extensions guide.
|
1063
1061
|
|
1064
1062
|
h5. +require 'active_support/core_ext/module/delegation'+
|
1065
1063
|
|
@@ -1073,7 +1071,7 @@ After the initial call to +require 'abstract_controller'+, this calls +require '
|
|
1073
1071
|
|
1074
1072
|
This file defines the +ActionController+ module and its autoloaded classes.
|
1075
1073
|
|
1076
|
-
Here we have a new method called +autoload_under+. This was covered in the
|
1074
|
+
Here we have a new method called +autoload_under+. This was covered in the Active Record Railtie but it is covered here also just in case you missed or skimmed over it. The +autoload_under+ method is defined in +ActiveSupport::Autoload+ and it sets the autoload path to temporarily be the specified path, in this case by specifying _metal_ it will load the specified +autoload+'d classes from _lib/action_controller/metal_ inside the block.
|
1077
1075
|
|
1078
1076
|
Another new method we have here is called +autoload_at+:
|
1079
1077
|
|
@@ -1092,7 +1090,7 @@ Another new method we have here is called +autoload_at+:
|
|
1092
1090
|
end
|
1093
1091
|
</ruby>
|
1094
1092
|
|
1095
|
-
This defines the path of which to find these classes defined at and is most useful for if you have multiple classes defined in a single file, as is the case for this block; all of those classes are defined inside _action_controller/metal/exceptions.rb_ and when
|
1093
|
+
This defines the path of which to find these classes defined at and is most useful for if you have multiple classes defined in a single file, as is the case for this block; all of those classes are defined inside _action_controller/metal/exceptions.rb_ and when Active Support goes looking for them it will look in that file.
|
1096
1094
|
|
1097
1095
|
At the end of this file there are a couple more requires:
|
1098
1096
|
|
@@ -1101,7 +1099,7 @@ At the end of this file there are a couple more requires:
|
|
1101
1099
|
require 'action_view'
|
1102
1100
|
require 'action_controller/vendor/html-scanner'
|
1103
1101
|
|
1104
|
-
# Common
|
1102
|
+
# Common Active Support usage in ActionController
|
1105
1103
|
require 'active_support/concern'
|
1106
1104
|
require 'active_support/core_ext/class/attribute_accessors'
|
1107
1105
|
require 'active_support/core_ext/load_error'
|
@@ -1113,7 +1111,7 @@ At the end of this file there are a couple more requires:
|
|
1113
1111
|
|
1114
1112
|
h5. +require 'action_view'+
|
1115
1113
|
|
1116
|
-
This is best covered in the
|
1114
|
+
This is best covered in the Action View Railtie section, so skip there by TODO: Link / page?
|
1117
1115
|
|
1118
1116
|
h5. +require 'action_controller/vendor/html-scanner'+
|
1119
1117
|
|
@@ -1129,7 +1127,7 @@ This file defines, as the path implies, attribute accessors for class. These are
|
|
1129
1127
|
|
1130
1128
|
h5. +require 'active_support/core_ext/load_error'+
|
1131
1129
|
|
1132
|
-
The
|
1130
|
+
The Active Support Core Extensions (TODO: LINK!) guide has a great coverage of what this file precisely provides.
|
1133
1131
|
|
1134
1132
|
h5. +require 'active_support/core_ext/module/attr_internal'+
|
1135
1133
|
|
@@ -1145,7 +1143,7 @@ This file was required earlier by Arel and so is not required again.
|
|
1145
1143
|
|
1146
1144
|
h5. +require 'active_support/core_ext/name_error'+
|
1147
1145
|
|
1148
|
-
This file includes extensions to the +NameError+ class, providing the +missing_name+ and +missing_name?+ methods. For more information see the
|
1146
|
+
This file includes extensions to the +NameError+ class, providing the +missing_name+ and +missing_name?+ methods. For more information see the Active Support Core Extensions guide.
|
1149
1147
|
|
1150
1148
|
h5. +require 'active_support/inflector'+
|
1151
1149
|
|
@@ -1153,9 +1151,9 @@ This file is explained in the "Common Includes" section.
|
|
1153
1151
|
|
1154
1152
|
This file was earlier required by Arel and so is not required again.
|
1155
1153
|
|
1156
|
-
h5.
|
1154
|
+
h5. Action Controller Railtie
|
1157
1155
|
|
1158
|
-
So now we come back to the
|
1156
|
+
So now we come back to the Action Controller Railtie with a couple more requires to go before +ActionController::Railtie+ is defined:
|
1159
1157
|
|
1160
1158
|
<ruby>
|
1161
1159
|
require "action_view/railtie"
|
@@ -1164,17 +1162,17 @@ So now we come back to the ActionController Railtie with a couple more requires
|
|
1164
1162
|
require "active_support/deprecation"
|
1165
1163
|
</ruby>
|
1166
1164
|
|
1167
|
-
As explained previously the +action_view/railtie+ file will be explained in the
|
1165
|
+
As explained previously the +action_view/railtie+ file will be explained in the Action View Railtie section. TODO: link to it.
|
1168
1166
|
|
1169
1167
|
h5. +require 'active_support/core_ext/class/subclasses'+
|
1170
1168
|
|
1171
|
-
For an explanation of this file _activesupport/lib/active_support/core_ext/class/subclasses_, see the
|
1169
|
+
For an explanation of this file _activesupport/lib/active_support/core_ext/class/subclasses_, see the Active Support Core Extension guide.
|
1172
1170
|
|
1173
1171
|
h5. +require 'active_support/deprecation/proxy_wrappers'+
|
1174
1172
|
|
1175
1173
|
This file, _activesupport/lib/active_support/deprecation/proxy_wrappers.rb_, defines a couple of deprecation classes, which are +DeprecationProxy+, +DeprecationObjectProxy+, +DeprecationInstanceVariableProxy+, +DeprecationConstantProxy+ which are all namespaced into +ActiveSupport::Deprecation+. These last three are all subclasses of +DeprecationProxy+.
|
1176
1174
|
|
1177
|
-
Why do we mention them here? Beside the obvious-by-now fact that we're covering just about everything about the initialization process in this guide, if you're deprecating something in your library and you use
|
1175
|
+
Why do we mention them here? Beside the obvious-by-now fact that we're covering just about everything about the initialization process in this guide, if you're deprecating something in your library and you use Active Support, you too can use the +DeprecationProxy+ class (and it's subclasses) too.
|
1178
1176
|
|
1179
1177
|
|
1180
1178
|
h6. +DeprecationProxy+
|
@@ -1234,7 +1232,7 @@ This makes more sense in the wider scope of the initializer:
|
|
1234
1232
|
|
1235
1233
|
h6. +DeprecatedInstanceVariableProxy+
|
1236
1234
|
|
1237
|
-
This isn't actually used anywhere in Rails anymore. It was used previously for when +@request+ and +@params+ were deprecated in Rails 2. It has been kept around as it could be useful for the same purposes in libraries that use
|
1235
|
+
This isn't actually used anywhere in Rails anymore. It was used previously for when +@request+ and +@params+ were deprecated in Rails 2. It has been kept around as it could be useful for the same purposes in libraries that use Active Support.
|
1238
1236
|
|
1239
1237
|
h6. +DeprecatedConstantProxy+
|
1240
1238
|
|
@@ -1249,9 +1247,9 @@ In _encoding.rb_ it's used to define a constant that's now been deprecated:
|
|
1249
1247
|
|
1250
1248
|
Now when you reference +ActiveSupport::JSON::CircularReferenceError+ you'll receive a warning:
|
1251
1249
|
|
1252
|
-
<
|
1250
|
+
<plain>
|
1253
1251
|
ActiveSupport::JSON::CircularReferenceError is deprecated! Use Encoding::CircularReferenceError instead.
|
1254
|
-
</
|
1252
|
+
</plain>
|
1255
1253
|
|
1256
1254
|
h5. +require "active_support/deprecation"+
|
1257
1255
|
|
@@ -1307,11 +1305,11 @@ This sets up some default behavior for the warnings raised by +ActiveSupport::De
|
|
1307
1305
|
}
|
1308
1306
|
</ruby>
|
1309
1307
|
|
1310
|
-
In the _test_ environment, we will see the deprecation errors displayed in +$stderr+ and in _development_ mode, these are sent to +Rails.logger+ if it exists, otherwise it is output to +$stderr+ in a very similar fashion to the _test_ environment. These are both defined as procs, so
|
1308
|
+
In the _test_ environment, we will see the deprecation errors displayed in +$stderr+ and in _development_ mode, these are sent to +Rails.logger+ if it exists, otherwise it is output to +$stderr+ in a very similar fashion to the _test_ environment. These are both defined as procs, so Active Support can pass arguments to the +call+ method we call on it when Active Support +warn+.
|
1311
1309
|
|
1312
1310
|
h5. +require 'active_support/deprecation/reporting'+
|
1313
1311
|
|
1314
|
-
This file defines further extensions to the +ActiveSupport::Deprecation+ module, including the +warn+ method which is used from
|
1312
|
+
This file defines further extensions to the +ActiveSupport::Deprecation+ module, including the +warn+ method which is used from Active Support's +DeprecationProxy+ class and an +attr_accessor+ on the class called +silenced+. This checks that we have a behavior defined, which we do in the _test_ and _development_ environments, and that we're not +silenced+ before warning about deprecations by +call+'ing the +Proc+ time.
|
1315
1313
|
|
1316
1314
|
This file also defines a +silence+ method on the module also which you can pass a block to temporarily silence errors:
|
1317
1315
|
|
@@ -1357,9 +1355,9 @@ h5. +require 'action_controller/railties/url_helpers'+
|
|
1357
1355
|
|
1358
1356
|
This file defines a +with+ method on +ActionController::Railtie::UrlHelpers+ which is later used in the +action_controller.url_helpers+ initializer. For more information see the +action_controller.url_helpers+ initializer section.
|
1359
1357
|
|
1360
|
-
h5.
|
1358
|
+
h5. Action Controller Railtie
|
1361
1359
|
|
1362
|
-
After these requires it deprecates a couple of ex-
|
1360
|
+
After these requires it deprecates a couple of ex-Action Controller methods and points whomever references them to their ActionDispatch equivalents. These methods are +session+, +session=+, +session_store+ and +session_store=+.
|
1363
1361
|
|
1364
1362
|
After the deprecations, Rails defines the +log_subscriber+ to be a new instance of +ActionController::Railties::LogSubscriber+ and then go about defining the following initializers, keeping in mind that these are added to the list of initializers defined before hand:
|
1365
1363
|
|
@@ -1369,9 +1367,9 @@ After the deprecations, Rails defines the +log_subscriber+ to be a new instance
|
|
1369
1367
|
* action_controller.set_helpers_path
|
1370
1368
|
* action_controller.url_helpers
|
1371
1369
|
|
1372
|
-
h4.
|
1370
|
+
h4. Action View Railtie
|
1373
1371
|
|
1374
|
-
The
|
1372
|
+
The Action View Railtie provides the backend code for your views and it puts the C into MVC. This implements the +ActionView::Base+ of which all views and partials are objects of.
|
1375
1373
|
|
1376
1374
|
h5. +require 'action_view/railtie'+
|
1377
1375
|
|
@@ -1379,7 +1377,7 @@ The Railtie is defined in a file called _actionpack/lib/action_view/railtie.rb_
|
|
1379
1377
|
|
1380
1378
|
h5. +require 'action_view'+
|
1381
1379
|
|
1382
|
-
Here again we have the addition of the path to
|
1380
|
+
Here again we have the addition of the path to Active Support to the load path attempted, but because it's already in the load path it will not be added. Similarly, we have two requires:
|
1383
1381
|
|
1384
1382
|
<ruby>
|
1385
1383
|
require 'active_support/ruby/shim'
|
@@ -1489,7 +1487,7 @@ h5. +ActionView::Context+
|
|
1489
1487
|
|
1490
1488
|
TODO: Not entirely sure what this is all about. Something about the context of view rendering... can't work it out.
|
1491
1489
|
|
1492
|
-
h5.
|
1490
|
+
h5. Action View Railtie
|
1493
1491
|
|
1494
1492
|
Now that _actionpack/lib/action_view.rb_ has been required, the next step is to +require 'rails'+, but this will be skipped as the file was required by _railties/lib/rails/all.rb_ way back in the beginnings of the initialization process.
|
1495
1493
|
|
@@ -1519,9 +1517,9 @@ The +ActionView::LogSubscriber+ sets up a method called +render_template+ which
|
|
1519
1517
|
|
1520
1518
|
The sole initializer defined here, _action_view.cache_asset_timestamps_ is responsible for caching the timestamps on the ends of your assets. If you've ever seen a link generated by +image_tag+ or +stylesheet_link_tag+ you would know that I mean that this timestamp is the number after the _?_ in this example: _/javascripts/prototype.js?1265442620_. This initializer will do nothing if +cache_classes+ is set to false in any of your application's configuration. TODO: Elaborate.
|
1521
1519
|
|
1522
|
-
h4.
|
1520
|
+
h4. Action Mailer Railtie
|
1523
1521
|
|
1524
|
-
The
|
1522
|
+
The Action Mailer Railtie is responsible for including all the emailing functionality into Rails by way of the Action Mailer gem itself. Action Mailer is:
|
1525
1523
|
|
1526
1524
|
Action Mailer is a framework for designing email-service layers. These layers
|
1527
1525
|
are used to consolidate code for sending out forgotten passwords, welcome
|
@@ -1549,7 +1547,7 @@ The requires in +action_mailer+ are already loaded or are core extensions:
|
|
1549
1547
|
require 'abstract_controller'
|
1550
1548
|
require 'action_view'
|
1551
1549
|
|
1552
|
-
# Common
|
1550
|
+
# Common Active Support usage in Action Mailer
|
1553
1551
|
require 'active_support/core_ext/class'
|
1554
1552
|
require 'active_support/core_ext/object/blank'
|
1555
1553
|
require 'active_support/core_ext/array/uniq_by'
|
@@ -1559,8 +1557,8 @@ The requires in +action_mailer+ are already loaded or are core extensions:
|
|
1559
1557
|
require 'active_support/lazy_load_hooks'
|
1560
1558
|
</ruby>
|
1561
1559
|
|
1562
|
-
_abstract_controller_ is covered in the "
|
1563
|
-
_action_view_ was required by the
|
1560
|
+
_abstract_controller_ is covered in the "Action Controller Railtie" section. TODO: Cover AbstractController there and link to it.
|
1561
|
+
_action_view_ was required by the Action View Railtie and will not be required again.
|
1564
1562
|
|
1565
1563
|
For the core extensions you may reference the "Core Extensions" guide. TODO: Link to guide.
|
1566
1564
|
|
@@ -1615,7 +1613,7 @@ which is used by the +ActionMailer::MailerHelper+ method +block_format+:
|
|
1615
1613
|
end
|
1616
1614
|
</ruby>
|
1617
1615
|
|
1618
|
-
h5.
|
1616
|
+
h5. Action Mailer Railtie
|
1619
1617
|
|
1620
1618
|
The Railtie defines the +log_subscriber+ as +ActionMailer::Railties::LogSubscriber.new+, with this class having two logging methods: one for delivery called +deliver+ and one for receipt called +receive+.
|
1621
1619
|
|
@@ -1627,13 +1625,13 @@ The initializers defined in this Railtie are:
|
|
1627
1625
|
|
1628
1626
|
These are covered later on the Initialization section. TODO: first write then link to Initialization section.
|
1629
1627
|
|
1630
|
-
h4.
|
1628
|
+
h4. Active Resource Railtie
|
1631
1629
|
|
1632
|
-
The
|
1630
|
+
The Active Resource Railtie is responsible for creating an interface into remote sites that offer a REST API. The Active Resource Railtie depends on Active Support and Active Model.
|
1633
1631
|
|
1634
1632
|
h5. +require 'active_resource/railtie'+
|
1635
1633
|
|
1636
|
-
This file defines the
|
1634
|
+
This file defines the Active Resource Railtie:
|
1637
1635
|
|
1638
1636
|
<ruby>
|
1639
1637
|
require "active_resource"
|
@@ -1659,7 +1657,7 @@ The +require 'rails'+ has already been done back in TODO: link to section.
|
|
1659
1657
|
|
1660
1658
|
h5. +require 'active_resource'+
|
1661
1659
|
|
1662
|
-
This file, _activeresource/lib/active_resource.rb_, defines the +ActiveResource+ module, first off this will add the path to
|
1660
|
+
This file, _activeresource/lib/active_resource.rb_, defines the +ActiveResource+ module, first off this will add the path to Active Support and Active Model to the load path if it's not already there, then require both +active_support+ (_activesupport/lib/active_support.rb_) and +active_model+ (_activemodel/lib/active_model.rb_)
|
1663
1661
|
|
1664
1662
|
<ruby>
|
1665
1663
|
activesupport_path = File.expand_path('../../../activesupport/lib', __FILE__)
|
@@ -1685,9 +1683,9 @@ This file, _activeresource/lib/active_resource.rb_, defines the +ActiveResource+
|
|
1685
1683
|
end
|
1686
1684
|
</ruby>
|
1687
1685
|
|
1688
|
-
h5.
|
1686
|
+
h5. Active Resource Railtie
|
1689
1687
|
|
1690
|
-
The Railtie itself is fairly short as
|
1688
|
+
The Railtie itself is fairly short as Active Resource is the smallest component of Rails.
|
1691
1689
|
|
1692
1690
|
<ruby>
|
1693
1691
|
module ActiveResource
|
@@ -1713,11 +1711,11 @@ There is only one initializer defined here: +set_configs+. This is covered later
|
|
1713
1711
|
|
1714
1712
|
h4. ActionDispatch Railtie
|
1715
1713
|
|
1716
|
-
ActionDispatch handles all dispatch work for Rails. It interfaces with
|
1714
|
+
ActionDispatch handles all dispatch work for Rails. It interfaces with Action Controller to determine what action to undertake when a request comes in. TODO: I would quote the README but it is strangely absent. Flyin' blind here!
|
1717
1715
|
|
1718
1716
|
The ActionDispatch Railtie was previously required when we called +require 'rails'+, but we will cover the Railtie here too.
|
1719
1717
|
|
1720
|
-
ActionDispatch depends on
|
1718
|
+
ActionDispatch depends on Active Support.
|
1721
1719
|
|
1722
1720
|
h5. +require 'action_dispatch/railtie'+
|
1723
1721
|
|
@@ -1755,7 +1753,7 @@ This file was already loaded earlier in the initialization process. TODO: link t
|
|
1755
1753
|
|
1756
1754
|
h5. ActionDispatch Railtie
|
1757
1755
|
|
1758
|
-
The ActionDispatch Railtie is almost as short as the
|
1756
|
+
The ActionDispatch Railtie is almost as short as the Active Resource Railtie:
|
1759
1757
|
|
1760
1758
|
<ruby>
|
1761
1759
|
require "action_dispatch"
|
@@ -1792,481 +1790,113 @@ Now that Rails has finished loading all the Railties by way of +require 'rails/a
|
|
1792
1790
|
|
1793
1791
|
NOTE: It is worth mentioning here that you are not tied to using Bundler with Rails 3, but it is (of course) advised that you do. To "turn off" Bundler, comment out or remove the corresponding lines in _config/application.rb_ and _config/boot.rb_.
|
1794
1792
|
|
1795
|
-
Bundler was +require+'d back in _config/boot.rb_ and
|
1793
|
+
Bundler was +require+'d back in _config/boot.rb_, and so that is what makes it available here. This guide does not dive into the internals of Bundler; it's really it's own separate guide.
|
1796
1794
|
|
1797
|
-
|
1795
|
+
The +Bundler.require+ method adds all the gems not specified inside a +group+ in the +Gemfile+ and the ones specified in groups for the +Rails.env+ (in this case, _development_), to the load path. This is how an application is able to find them.
|
1798
1796
|
|
1799
|
-
|
1797
|
+
The rest of this file is spent defining your application's main class. This is it without the comments:
|
1800
1798
|
|
1801
1799
|
<ruby>
|
1802
|
-
|
1803
|
-
|
1804
|
-
|
1805
|
-
|
1806
|
-
</ruby>
|
1807
|
-
|
1808
|
-
The +groups+ variable here would be a two-element array of the arguments passed to +Bundler.require+. In this case we're going to assume, +Rails.env+ is +"development"+.
|
1809
|
-
|
1810
|
-
h4. Locating the Gemfile
|
1811
|
-
|
1812
|
-
+default_gemfile+ is defined in _lib/bundler.rb_ and makes a call out to the +SharedHelpers+ module:
|
1813
|
-
|
1814
|
-
<ruby>
|
1815
|
-
def default_gemfile
|
1816
|
-
SharedHelpers.default_gemfile
|
1817
|
-
end
|
1818
|
-
</ruby>
|
1819
|
-
|
1820
|
-
+SharedHelpers+ defines +default_gemfile+ like this:
|
1821
|
-
|
1822
|
-
<ruby>
|
1823
|
-
def default_gemfile
|
1824
|
-
gemfile = find_gemfile
|
1825
|
-
gemfile or raise GemfileNotFound, "The default Gemfile was not found"
|
1826
|
-
Pathname.new(gemfile)
|
1827
|
-
end
|
1828
|
-
</ruby>
|
1829
|
-
|
1830
|
-
+find_gemfile+ is defined like this:
|
1831
|
-
|
1832
|
-
<ruby>
|
1833
|
-
def find_gemfile
|
1834
|
-
return ENV['BUNDLE_GEMFILE'] if ENV['BUNDLE_GEMFILE']
|
1835
|
-
|
1836
|
-
previous = nil
|
1837
|
-
current = File.expand_path(Dir.pwd)
|
1838
|
-
|
1839
|
-
until !File.directory?(current) || current == previous
|
1840
|
-
filename = File.join(current, 'Gemfile')
|
1841
|
-
return filename if File.file?(filename)
|
1842
|
-
current, previous = File.expand_path("..", current), current
|
1843
|
-
end
|
1844
|
-
end
|
1845
|
-
</ruby>
|
1846
|
-
|
1847
|
-
The first line of course means if you define the environment variable +BUNDLE_GEMFILE+ this is the name of the file that will be used and returned. If not, then Bundler will look for a file called _Gemfile_ in the current directory and if it can find it then it will return the filename. If it cannot, it will recurse up the directory structure until it does. Once the file is found a +Pathname+ is made from the expanded path to _Gemfile_.
|
1848
|
-
|
1849
|
-
If the file cannot be found at all then +GemfileNotFound+ will be raised back in +default_gemfile+.
|
1850
|
-
|
1851
|
-
h4. Loading the Gemfile
|
1852
|
-
|
1853
|
-
Now that Bundler has determined what the _Gemfile_ is, it goes about loading it:
|
1854
|
-
|
1855
|
-
<ruby>
|
1856
|
-
def require(*groups)
|
1857
|
-
gemfile = default_gemfile
|
1858
|
-
load(gemfile).require(*groups)
|
1859
|
-
end
|
1860
|
-
</ruby>
|
1861
|
-
|
1862
|
-
+load+ is defined like this in _lib/bundler.rb_:
|
1863
|
-
|
1864
|
-
<ruby>
|
1865
|
-
def load(gemfile = default_gemfile)
|
1866
|
-
root = Pathname.new(gemfile).dirname
|
1867
|
-
Runtime.new root, definition(gemfile)
|
1868
|
-
end
|
1869
|
-
</ruby>
|
1870
|
-
|
1871
|
-
The next method to be called here would be +definition+ and it is defined like this:
|
1872
|
-
|
1873
|
-
<ruby>
|
1874
|
-
def definition(gemfile = default_gemfile)
|
1875
|
-
configure
|
1876
|
-
root = Pathname.new(gemfile).dirname
|
1877
|
-
lockfile = root.join("Gemfile.lock")
|
1878
|
-
if lockfile.exist?
|
1879
|
-
Definition.from_lock(lockfile)
|
1880
|
-
else
|
1881
|
-
Definition.from_gemfile(gemfile)
|
1882
|
-
end
|
1883
|
-
end
|
1884
|
-
</ruby>
|
1885
|
-
|
1886
|
-
+configure+ is responsible for setting up the path to gem home and gem path:
|
1887
|
-
|
1888
|
-
<ruby>
|
1889
|
-
def configure
|
1890
|
-
@configured ||= begin
|
1891
|
-
configure_gem_home_and_path
|
1892
|
-
true
|
1893
|
-
end
|
1894
|
-
end
|
1895
|
-
</ruby>
|
1896
|
-
|
1897
|
-
+configure_gem_home_and_path+ defined like this:
|
1898
|
-
|
1899
|
-
<ruby>
|
1900
|
-
def configure_gem_home_and_path
|
1901
|
-
if settings[:disable_shared_gems]
|
1902
|
-
ENV['GEM_HOME'] = File.expand_path(bundle_path, root)
|
1903
|
-
ENV['GEM_PATH'] = ''
|
1904
|
-
else
|
1905
|
-
gem_home, gem_path = Gem.dir, Gem.path
|
1906
|
-
ENV["GEM_PATH"] = [gem_home, gem_path].flatten.compact.join(File::PATH_SEPARATOR)
|
1907
|
-
ENV["GEM_HOME"] = bundle_path.to_s
|
1908
|
-
end
|
1909
|
-
|
1910
|
-
Gem.clear_paths
|
1911
|
-
end
|
1912
|
-
</ruby>
|
1913
|
-
|
1914
|
-
We do not have +settings[:disabled_shared_gems]+ set to true so this will execute the code under the +else+. The +ENV["GEM_PATH"]+ will resemble +/usr/local/lib/ruby/gems/1.9.1:/home/you/.gem/ruby/1.9.1+
|
1915
|
-
|
1916
|
-
And +ENV["GEM_HOME"]+ will be the path to the gems installed into your home directory by Bundler, something resembling +/home/you/.bundle/ruby/1.9.1+.
|
1917
|
-
|
1918
|
-
After +configure_gem_home_and_path+ is done the +definition+ method goes about creating a +Definition+ from either +Gemfile.lock+ if it exists, or the +gemfile+ previously located. +Gemfile.lock+ only exists if +bundle lock+ has been ran and so far it has not.
|
1919
|
-
|
1920
|
-
+Definition.from_gemfile+ is defined in _lib/bundler/definition.rb_:
|
1921
|
-
|
1922
|
-
<ruby>
|
1923
|
-
def self.from_gemfile(gemfile)
|
1924
|
-
gemfile = Pathname.new(gemfile).expand_path
|
1925
|
-
|
1926
|
-
unless gemfile.file?
|
1927
|
-
raise GemfileNotFound, "#{gemfile} not found"
|
1928
|
-
end
|
1929
|
-
|
1930
|
-
Dsl.evaluate(gemfile)
|
1931
|
-
end
|
1932
|
-
</ruby>
|
1933
|
-
|
1934
|
-
Now that the +gemfile+ is located +Dsl.evaluate+ goes about loading it. The code for this can be found in _lib/bundler/dsl.rb_:
|
1935
|
-
|
1936
|
-
<ruby>
|
1937
|
-
def self.evaluate(gemfile)
|
1938
|
-
builder = new
|
1939
|
-
builder.instance_eval(File.read(gemfile.to_s), gemfile.to_s, 1)
|
1940
|
-
builder.to_definition
|
1941
|
-
end
|
1942
|
-
</ruby>
|
1943
|
-
|
1944
|
-
+new+ here will, of course, call +initialize+ which sets up a couple of variables:
|
1945
|
-
|
1946
|
-
<ruby>
|
1947
|
-
def initialize
|
1948
|
-
@source = nil
|
1949
|
-
@sources = []
|
1950
|
-
@dependencies = []
|
1951
|
-
@group = nil
|
1952
|
-
end
|
1953
|
-
</ruby>
|
1954
|
-
|
1955
|
-
When Bundler calls +instance_eval+ on the new +Bundler::Dsl+ object it evaluates the content of the +gemfile+ file within the context of this instance. The Gemfile for a default Rails 3 project with all the comments stripped out looks like this:
|
1956
|
-
|
1957
|
-
<ruby>
|
1958
|
-
source 'http://rubygems.org'
|
1959
|
-
|
1960
|
-
gem 'rails', '3.0.0.beta1'
|
1961
|
-
|
1962
|
-
# Bundle edge Rails instead:
|
1963
|
-
# gem 'rails', :git => 'git://github.com/rails/rails.git'
|
1964
|
-
|
1965
|
-
gem 'sqlite3-ruby', :require => 'sqlite3'
|
1966
|
-
</ruby>
|
1967
|
-
|
1968
|
-
When Bundler loads this file it firstly calls the +source+ method on the +Bundler::Dsl+ object:
|
1969
|
-
|
1970
|
-
<ruby>
|
1971
|
-
def source(source, options = {})
|
1972
|
-
@source = case source
|
1973
|
-
when :gemcutter, :rubygems, :rubyforge then Source::Rubygems.new("uri" => "http://gemcutter.org")
|
1974
|
-
when String then Source::Rubygems.new("uri" => source)
|
1975
|
-
else source
|
1800
|
+
module YourApp
|
1801
|
+
class Application < Rails::Application
|
1802
|
+
config.encoding = "utf-8"
|
1803
|
+
config.filter_parameters += [:password]
|
1976
1804
|
end
|
1977
|
-
|
1978
|
-
options[:prepend] ? @sources.unshift(@source) : @sources << @source
|
1979
|
-
|
1980
|
-
yield if block_given?
|
1981
|
-
@source
|
1982
|
-
ensure
|
1983
|
-
@source = nil
|
1984
1805
|
end
|
1985
1806
|
</ruby>
|
1986
1807
|
|
1987
|
-
|
1808
|
+
h3. Return to Rails
|
1988
1809
|
|
1989
|
-
|
1810
|
+
On the surface, this looks like a simple class inheritance. There's more underneath though. back in +Rails::Application+, the +inherited+ method is defined:
|
1990
1811
|
|
1991
1812
|
<ruby>
|
1992
|
-
|
1993
|
-
|
1813
|
+
def inherited(base)
|
1814
|
+
raise "You cannot have more than one Rails::Application" if Rails.application
|
1815
|
+
super
|
1816
|
+
Rails.application = base.instance
|
1994
1817
|
end
|
1995
1818
|
</ruby>
|
1996
1819
|
|
1997
|
-
|
1998
|
-
|
1999
|
-
In this instance however a block is not specified so this sets up the +@source+ instance variable to be +'http://rubygems.org'+.
|
2000
|
-
|
2001
|
-
The next method that is called is +gem+:
|
1820
|
+
We do not already have a +Rails.application+, so instead this resorts to calling +super+. +Rails::Application+ descends from +Rails::Engine+ and so will call the +inherited+ method in +Rails::Engine+ (in _railties/lib/rails/engine.rb_), but before that it's important to note that +called_from+ is defined an +attr_accessor+ on +Rails::Engine+ and that +YourApp::Application+ is not an +abstract_railtie+:
|
2002
1821
|
|
2003
1822
|
<ruby>
|
2004
|
-
def
|
2005
|
-
|
2006
|
-
|
2007
|
-
|
2008
|
-
|
1823
|
+
def inherited(base)
|
1824
|
+
unless base.abstract_railtie?
|
1825
|
+
base.called_from = begin
|
1826
|
+
# Remove the line number from backtraces making sure we don't leave anything behind
|
1827
|
+
call_stack = caller.map { |p| p.split(':')[0..-2].join(':') }
|
1828
|
+
File.dirname(call_stack.detect { |p| p !~ %r[railties[\w\-\.]*/lib/rails|rack[\w\-\.]*/lib/rack] })
|
1829
|
+
end
|
2009
1830
|
end
|
2010
1831
|
|
2011
|
-
|
2012
|
-
_normalize_options(name, version, options)
|
2013
|
-
|
2014
|
-
@dependencies << Dependency.new(name, version, options)
|
1832
|
+
super
|
2015
1833
|
end
|
2016
1834
|
</ruby>
|
2017
1835
|
|
2018
|
-
This
|
1836
|
+
This +called_from+ setting looks a little overwhelming to begin with, but the short end of it is that it returns the route to your application's config directory, something like: _/home/you/yourapp/config_. After +called_from+ has been set, +super+ is again called and this means the +Rails::Railtie#inherited+ method (in _railties/lib/rails/railtie.rb_):
|
2019
1837
|
|
2020
1838
|
<ruby>
|
2021
|
-
|
2022
|
-
|
2023
|
-
|
2024
|
-
|
2025
|
-
|
2026
|
-
In the Gemfile for a default Rails project, the first +gem+ line is:
|
2027
|
-
|
2028
|
-
<ruby>
|
2029
|
-
gem 'rails', '3.0.0.beta2'
|
2030
|
-
</ruby>
|
2031
|
-
|
2032
|
-
TODO: change version number.
|
2033
|
-
|
2034
|
-
This line will check that +options+ contains no deprecated options by using the +_deprecated_options+ method, but the +options+ hash is empty. This is of course until +_normalize_options+ has its way:
|
2035
|
-
|
2036
|
-
<ruby>
|
2037
|
-
def _normalize_options(name, version, opts)
|
2038
|
-
_normalize_hash(opts)
|
2039
|
-
|
2040
|
-
group = opts.delete("group") || @group
|
2041
|
-
|
2042
|
-
# Normalize git and path options
|
2043
|
-
["git", "path"].each do |type|
|
2044
|
-
if param = opts[type]
|
2045
|
-
options = _version?(version) ? opts.merge("name" => name, "version" => version) : opts.dup
|
2046
|
-
source = send(type, param, options, :prepend => true)
|
2047
|
-
opts["source"] = source
|
2048
|
-
end
|
1839
|
+
def inherited(base)
|
1840
|
+
unless base.abstract_railtie?
|
1841
|
+
base.send(:include, self::Configurable)
|
1842
|
+
subclasses << base
|
2049
1843
|
end
|
2050
|
-
|
2051
|
-
opts["source"] ||= @source
|
2052
|
-
|
2053
|
-
opts["group"] = group
|
2054
|
-
end
|
1844
|
+
end
|
2055
1845
|
</ruby>
|
2056
1846
|
|
2057
|
-
+
|
2058
|
-
|
2059
|
-
TODO: Maybe it is best to cover what would happen in the case these lines did exist?
|
2060
|
-
|
2061
|
-
The next line goes about defining a dependency for this gem:
|
1847
|
+
Again, +YourApp::Application+ will return false for +abstract_railtie+ and so the code inside the +unless+ will be ran. The first line:
|
2062
1848
|
|
2063
1849
|
<ruby>
|
2064
|
-
|
1850
|
+
base.send(:include, self::Configurable)
|
2065
1851
|
</ruby>
|
2066
1852
|
|
2067
|
-
|
1853
|
+
includes the +self::Configurable+ module, with self being +Rails::Application+ in this context:
|
2068
1854
|
|
2069
1855
|
<ruby>
|
2070
|
-
module
|
2071
|
-
class
|
2072
|
-
|
2073
|
-
|
2074
|
-
|
2075
|
-
|
2076
|
-
super(name, version)
|
1856
|
+
module Rails
|
1857
|
+
class Application
|
1858
|
+
module Configurable
|
1859
|
+
def self.included(base)
|
1860
|
+
base.extend ClassMethods
|
1861
|
+
end
|
2077
1862
|
|
2078
|
-
|
2079
|
-
|
2080
|
-
|
1863
|
+
module ClassMethods
|
1864
|
+
def inherited(base)
|
1865
|
+
raise "You cannot inherit from a Rails::Application child"
|
1866
|
+
end
|
1867
|
+
end
|
2081
1868
|
|
2082
|
-
|
2083
|
-
@
|
1869
|
+
def config
|
1870
|
+
@config ||= Application::Configuration.new(self.class.find_root_with_flag("config.ru", Dir.pwd))
|
2084
1871
|
end
|
2085
1872
|
end
|
2086
1873
|
end
|
2087
1874
|
end
|
2088
1875
|
</ruby>
|
2089
1876
|
|
2090
|
-
The +
|
1877
|
+
The inclusion of the +Rails::Application::Configurable+ module triggers the +included+ method in here which extends +YourApp::Application+ with the +Rails::Application::Configurable::ClassMethods+.
|
2091
1878
|
|
2092
|
-
|
2093
|
-
def initialize(name, version_requirements, type=:runtime)
|
2094
|
-
@name = name
|
2095
|
-
unless TYPES.include? type
|
2096
|
-
raise ArgumentError, "Valid types are #{TYPES.inspect}, not #{@type.inspect}"
|
2097
|
-
end
|
2098
|
-
@type = type
|
2099
|
-
@version_requirements = Gem::Requirement.create version_requirements
|
2100
|
-
@version_requirement = nil # Avoid warnings.
|
2101
|
-
end
|
2102
|
-
</ruby>
|
2103
|
-
|
2104
|
-
The +version_requirements+ that was passed in here will be inspected by +Gem::Requirement.create+ and return, for our +3.0.0beta2+ version string a +Gem::Requirement+ object:
|
2105
|
-
|
2106
|
-
<ruby>
|
2107
|
-
#<Gem::Requirement:0x101dd8c20 @requirements=[["=", #<Gem::Version "3.0.0beta2">]]>
|
2108
|
-
</ruby>
|
2109
|
-
|
2110
|
-
Going back to +Bundler::Dependency+, the next line simply sets +@autorequire+ to +nil+ and the next line is a little more interesting:
|
1879
|
+
Now that the chain of +super+ calls is done, we'll go back to the original +inherited+ method in +Rails::Application+ and the final line in this method:
|
2111
1880
|
|
2112
1881
|
<ruby>
|
2113
|
-
|
2114
|
-
@groups = Array(options["group"] || :default).map { |g| g.to_sym }
|
2115
|
-
</ruby>
|
2116
|
-
|
2117
|
-
Here, bundler sets the +groups+ variable to be whatever +group+ we've set for this gem and also demonstrates through code that the +group+ option allows for multiple groups, so in the _Gemfile_ we can specify the same gem for multiple groups:
|
2118
|
-
|
2119
|
-
<ruby>
|
2120
|
-
group :test, :cucumber do
|
2121
|
-
gem 'faker'
|
2122
|
-
end
|
2123
|
-
</ruby>
|
2124
|
-
|
2125
|
-
The final lines in +initialize+ work on the +require+ option which is not passed:
|
2126
|
-
|
2127
|
-
<ruby>
|
2128
|
-
if options.key?('require')
|
2129
|
-
@autorequire = Array(options['require'] || [])
|
2130
|
-
end
|
1882
|
+
Rails.application = base.instance
|
2131
1883
|
</ruby>
|
2132
1884
|
|
2133
|
-
|
1885
|
+
+base+ in this case is +YourApp::Application+ and calling +instance+ on this will return an instance of +YourApp::Application+ through the +instance+ method defined here:
|
2134
1886
|
|
2135
1887
|
<ruby>
|
2136
|
-
|
2137
|
-
|
2138
|
-
|
2139
|
-
|
2140
|
-
|
2141
|
-
h3. Bring forth the gems
|
2142
|
-
|
2143
|
-
Now that the _Gemfile_ has finished being parsed, the next line is:
|
2144
|
-
|
2145
|
-
<ruby>
|
2146
|
-
builder.to_definition
|
2147
|
-
</ruby>
|
2148
|
-
|
2149
|
-
This method is defined in _lib/bundler/dsl.rb_ and does this:
|
2150
|
-
|
2151
|
-
<ruby>
|
2152
|
-
def to_definition
|
2153
|
-
Definition.new(@dependencies, @sources)
|
2154
|
-
end
|
2155
|
-
</ruby>
|
2156
|
-
|
2157
|
-
The +Bundler::Definition#initialize+ method is this:
|
2158
|
-
|
2159
|
-
<ruby>
|
2160
|
-
def initialize(dependencies, sources)
|
2161
|
-
@dependencies = dependencies
|
2162
|
-
@sources = sources
|
2163
|
-
end
|
2164
|
-
</ruby>
|
2165
|
-
|
2166
|
-
Now Bundler has a +Bundler::Definition+ object to be passed back to the +load+ method from _lib/bundler.rb_:
|
2167
|
-
|
2168
|
-
<ruby>
|
2169
|
-
def load(gemfile = default_gemfile)
|
2170
|
-
root = Pathname.new(gemfile).dirname
|
2171
|
-
Runtime.new root, definition(gemfile)
|
2172
|
-
end
|
2173
|
-
</ruby>
|
2174
|
-
|
2175
|
-
The +Bundler::Runtime+ class inherits from +Bundler::Environment+ and the reason this is pointed out is because +super+ is used in the +initialize+ method in +Bundler::Runtime+:
|
2176
|
-
|
2177
|
-
<ruby>
|
2178
|
-
super
|
2179
|
-
if locked?
|
2180
|
-
write_rb_lock
|
2181
|
-
end
|
2182
|
-
</ruby>
|
2183
|
-
|
2184
|
-
Thankfully, the +Bundler::Environment#initialize+ method is nothing too complex:
|
2185
|
-
|
2186
|
-
<ruby>
|
2187
|
-
def initialize(root, definition)
|
2188
|
-
@root = root
|
2189
|
-
@definition = definition
|
2190
|
-
end
|
2191
|
-
</ruby>
|
2192
|
-
|
2193
|
-
The +locked?+ method checks if the _Gemfile.lock_ or _.bundler/environment.rb_ files exist:
|
2194
|
-
|
2195
|
-
<ruby>
|
2196
|
-
def locked?
|
2197
|
-
File.exist?("#{root}/Gemfile.lock") || File.exist?("#{root}/.bundle/environment.rb")
|
2198
|
-
end
|
2199
|
-
</ruby>
|
2200
|
-
|
2201
|
-
And if they do will call +write_rb_lock+:
|
2202
|
-
|
2203
|
-
<ruby>
|
2204
|
-
def write_rb_lock
|
2205
|
-
shared_helpers = File.read(File.expand_path("../shared_helpers.rb", __FILE__))
|
2206
|
-
template = File.read(File.expand_path("../templates/environment.erb", __FILE__))
|
2207
|
-
erb = ERB.new(template, nil, '-')
|
2208
|
-
FileUtils.mkdir_p(rb_lock_file.dirname)
|
2209
|
-
File.open(rb_lock_file, 'w') do |f|
|
2210
|
-
f.puts erb.result(binding)
|
2211
|
-
end
|
2212
|
-
end
|
2213
|
-
</ruby>
|
2214
|
-
|
2215
|
-
This will write out to _.bundler/environment.rb_ the state of the current environment.
|
2216
|
-
|
2217
|
-
Now a quick refresher. Bundler is still evaulating the code for the +require+ in _lib/bundler.rb_, and the +groups+ variable here is an +Array+ containing two elements: +:default+ and the current Rails environment: +development+:
|
2218
|
-
|
2219
|
-
<ruby>
|
2220
|
-
def require(*groups)
|
2221
|
-
gemfile = default_gemfile
|
2222
|
-
load(gemfile).require(*groups)
|
2223
|
-
end
|
2224
|
-
</ruby>
|
2225
|
-
|
2226
|
-
The second +require+ method here:
|
2227
|
-
|
2228
|
-
<ruby>
|
2229
|
-
load(gemfile).require(*groups)
|
2230
|
-
</ruby>
|
2231
|
-
|
2232
|
-
Is defined on _bundler/runtime.rb_:
|
2233
|
-
|
2234
|
-
<ruby>
|
2235
|
-
def require(*groups)
|
2236
|
-
groups.map! { |g| g.to_sym }
|
2237
|
-
groups = [:default] if groups.empty?
|
2238
|
-
autorequires = autorequires_for_groups(*groups)
|
2239
|
-
|
2240
|
-
groups.each do |group|
|
2241
|
-
(autorequires[group] || [[]]).each do |path, explicit|
|
2242
|
-
if explicit
|
2243
|
-
Kernel.require(path)
|
2244
|
-
else
|
2245
|
-
begin
|
2246
|
-
Kernel.require(path)
|
2247
|
-
rescue LoadError
|
2248
|
-
end
|
2249
|
-
end
|
2250
|
-
end
|
1888
|
+
def instance
|
1889
|
+
if self == Rails::Application
|
1890
|
+
Rails.application
|
1891
|
+
else
|
1892
|
+
@@instance ||= new
|
2251
1893
|
end
|
2252
1894
|
end
|
2253
1895
|
</ruby>
|
2254
1896
|
|
2255
|
-
|
1897
|
+
+self+ in this case is +YourApp::Application+, so it won't match to +Rails::Application+ so instead the +new+ method is called which calls the +initialize+ method.
|
2256
1898
|
|
2257
|
-
The first method to be called here is +autorequires_for_groups+:
|
2258
1899
|
|
2259
|
-
<ruby>
|
2260
|
-
def autorequires_for_groups(*groups)
|
2261
|
-
groups.map! { |g| g.to_sym }
|
2262
|
-
autorequires = Hash.new { |h,k| h[k] = [] }
|
2263
|
-
|
2264
|
-
ordered_deps = []
|
2265
|
-
specs_for(*groups).each do |g|
|
2266
|
-
dep = @definition.dependencies.find{|d| d.name == g.name }
|
2267
|
-
ordered_deps << dep if dep && !ordered_deps.include?(dep)
|
2268
|
-
end
|
2269
|
-
</ruby>
|
2270
1900
|
|
2271
1901
|
|
2272
1902
|
h3. Firing it up!
|
@@ -2807,7 +2437,6 @@ Now that we've referenced that class, it will be required for us. You'll notice
|
|
2807
2437
|
* initialize_subscriber
|
2808
2438
|
* set_clear_dependencies_hook
|
2809
2439
|
* initialize_dependency_mechanism
|
2810
|
-
* bootstrap_load_path
|
2811
2440
|
|
2812
2441
|
These are all defined using the +initializer+ method:
|
2813
2442
|
|
@@ -3331,7 +2960,7 @@ If you don't want this to happen you can specify the +config.active_support.bare
|
|
3331
2960
|
|
3332
2961
|
h4. +preload_frameworks+
|
3333
2962
|
|
3334
|
-
Remember earlier how we had all that stuff +eager_autoload+'d for
|
2963
|
+
Remember earlier how we had all that stuff +eager_autoload+'d for Active Support?
|
3335
2964
|
|
3336
2965
|
<ruby>
|
3337
2966
|
initializer :preload_frameworks do
|
@@ -3358,13 +2987,12 @@ With +@@autoloads+ being
|
|
3358
2987
|
* initialize_subscriber
|
3359
2988
|
* set_clear_dependencies_hook
|
3360
2989
|
* initialize_dependency_mechanism
|
3361
|
-
* bootstrap_load_path
|
3362
2990
|
|
3363
|
-
h4.
|
2991
|
+
h4. Active Support Initializers
|
3364
2992
|
|
3365
|
-
|
2993
|
+
Active Support
|
3366
2994
|
|
3367
|
-
**
|
2995
|
+
**Active Support Initializers**
|
3368
2996
|
|
3369
2997
|
* active_support.initialize_whiny_nils
|
3370
2998
|
* active_support.initialize_time_zone
|
@@ -3375,18 +3003,18 @@ ActiveSupport
|
|
3375
3003
|
|
3376
3004
|
The +I18n::Railtie+ also defines an +after_initialize+ which we will return to later when discussing the initializers in detail.
|
3377
3005
|
|
3378
|
-
**
|
3006
|
+
**Action Dispatch Initializers**
|
3379
3007
|
|
3380
3008
|
* action_dispatch.prepare_dispatcher
|
3381
3009
|
|
3382
|
-
**
|
3010
|
+
**Action Controller Initializers**
|
3383
3011
|
|
3384
3012
|
* action_controller.logger
|
3385
3013
|
* action_controller.set_configs
|
3386
3014
|
* action_controller.initialize_framework_caches
|
3387
3015
|
* action_controller.set_helpers_path
|
3388
3016
|
|
3389
|
-
**
|
3017
|
+
**Active Record Initializers**
|
3390
3018
|
|
3391
3019
|
* active_record.initialize_time_zone
|
3392
3020
|
* active_record.logger
|
@@ -3396,17 +3024,17 @@ The +I18n::Railtie+ also defines an +after_initialize+ which we will return to l
|
|
3396
3024
|
* active_record.load_observers
|
3397
3025
|
* active_record.set_dispatch_hooks
|
3398
3026
|
|
3399
|
-
**
|
3027
|
+
**Action View Initializers **
|
3400
3028
|
|
3401
3029
|
* action_view.cache_asset_timestamps
|
3402
3030
|
|
3403
|
-
**
|
3031
|
+
**Action Mailer Initializers **
|
3404
3032
|
|
3405
3033
|
* action_mailer.logger
|
3406
3034
|
* action_mailer.set_configs
|
3407
3035
|
* action_mailer.url_for
|
3408
3036
|
|
3409
|
-
**
|
3037
|
+
**Active Resource Initializers**
|
3410
3038
|
|
3411
3039
|
* active_resource.set_configs
|
3412
3040
|
|
@@ -3524,7 +3152,6 @@ This method is defined like this:
|
|
3524
3152
|
middleware.use('ActionDispatch::Cookies')
|
3525
3153
|
middleware.use(lambda { ActionController::Base.session_store }, lambda { ActionController::Base.session_options })
|
3526
3154
|
middleware.use('ActionDispatch::Flash', :if => lambda { ActionController::Base.session_store })
|
3527
|
-
middleware.use(lambda { Rails::Rack::Metal.new(Rails.application.config.paths.app.metals.to_a, Rails.application.config.metals) })
|
3528
3155
|
middleware.use('ActionDispatch::ParamsParser')
|
3529
3156
|
middleware.use('::Rack::MethodOverride')
|
3530
3157
|
middleware.use('::ActionDispatch::Head')
|
@@ -3658,7 +3285,7 @@ Finally, a +Rails::Application::Configuration+ object will be returned. On this
|
|
3658
3285
|
<ruby>
|
3659
3286
|
attr_accessor :after_initialize_blocks, :cache_classes, :colorize_logging,
|
3660
3287
|
:consider_all_requests_local, :dependency_loading,
|
3661
|
-
:load_once_paths, :logger, :
|
3288
|
+
:load_once_paths, :logger, :plugins,
|
3662
3289
|
:preload_frameworks, :reload_plugins, :serve_static_assets,
|
3663
3290
|
:time_zone, :whiny_nils
|
3664
3291
|
|
@@ -3944,7 +3571,6 @@ The +super+ method it references comes from +Rails::Engine::Configuration+ which
|
|
3944
3571
|
paths.app.controllers "app/controllers", :eager_load => true
|
3945
3572
|
paths.app.helpers "app/helpers", :eager_load => true
|
3946
3573
|
paths.app.models "app/models", :eager_load => true
|
3947
|
-
paths.app.metals "app/metal"
|
3948
3574
|
paths.app.views "app/views"
|
3949
3575
|
paths.lib "lib", :load_path => true
|
3950
3576
|
paths.lib.tasks "lib/tasks", :glob => "**/*.rake"
|
@@ -4079,7 +3705,7 @@ This file is _activesupport/lib/active_support/inflector.rb_ and makes a couple
|
|
4079
3705
|
require 'active_support/core_ext/string/inflections'
|
4080
3706
|
</ruby>
|
4081
3707
|
|
4082
|
-
The files included here define methods for modifying strings, such as +transliterate+ which will convert a Unicode string to its ASCII version, +parameterize+ for making strings into url-safe versions, +camelize+ for camel-casing a string such as +string_other+ into +StringOther+ and +ordinalize+ converting a string such as +101+ into +101st+. More information about these methods can be found in the
|
3708
|
+
The files included here define methods for modifying strings, such as +transliterate+ which will convert a Unicode string to its ASCII version, +parameterize+ for making strings into url-safe versions, +camelize+ for camel-casing a string such as +string_other+ into +StringOther+ and +ordinalize+ converting a string such as +101+ into +101st+. More information about these methods can be found in the Active Support Core Extensions Guide. TODO: Link to AS Guide.
|
4083
3709
|
|
4084
3710
|
h4. +require 'active_support/core_ext/module/delegation'+
|
4085
3711
|
|
@@ -4133,6 +3759,6 @@ The _activesupport/lib/active_support/ruby/shim.rb_ file requires methods that h
|
|
4133
3759
|
* +Time.to_time+
|
4134
3760
|
* +Time.to_datetime+
|
4135
3761
|
|
4136
|
-
For more information see the
|
3762
|
+
For more information see the Active Support Core Extensions guide TODO: link to relevant sections for each method.
|
4137
3763
|
|
4138
|
-
And "the REXML security fix detailed here":[http://weblog.rubyonrails.org/2008/8/23/dos-vulnerabilities-in-rexml]
|
3764
|
+
And "the REXML security fix detailed here":[http://weblog.rubyonrails.org/2008/8/23/dos-vulnerabilities-in-rexml]
|