From 14b5c8b98515d9cc13fbdefb02800ad42f1070f5 Mon Sep 17 00:00:00 2001 From: Paul Odeon Date: Sat, 11 Dec 2010 14:30:12 +0000 Subject: Updated generator guide for rails commit 7891de893951c780a1732747d430c33e998dd573 --- railties/guides/source/generators.textile | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'railties/guides/source') diff --git a/railties/guides/source/generators.textile b/railties/guides/source/generators.textile index ee3891c43b..6945f6f9bb 100644 --- a/railties/guides/source/generators.textile +++ b/railties/guides/source/generators.textile @@ -208,16 +208,16 @@ end If we generate another resource with the scaffold generator, we can see that neither stylesheets nor fixtures are created anymore. If you want to customize it further, for example to use DataMapper and RSpec instead of Active Record and TestUnit, it's just a matter of adding their gems to your application and configuring your generators. -To demonstrate this, we are going to create a new helper generator that simply adds some instance variable readers. First, we create a generator: +To demonstrate this, we are going to create a new helper generator that simply adds some instance variable readers. First, we create a generator within the rails namespace, as this is where rails searches for generators used as hooks: -$ rails generate generator my_helper +$ rails generate generator rails/my_helper After that, we can delete both the +templates+ directory and the +source_root+ class method from our new generators, because we are not going to need them. So our new generator looks like the following: -class MyHelperGenerator < Rails::Generators::NamedBase +class Rails::MyHelperGenerator < Rails::Generators::NamedBase def create_helper_file create_file "app/helpers/#{file_name}_helper.rb", <<-FILE module #{class_name}Helper @@ -270,7 +270,7 @@ Since Rails 3.0, this is easy to do due to the hooks concept. Our new helper doe To do that, we can change the generator this way: -class MyHelperGenerator < Rails::Generators::NamedBase +class Rails::MyHelperGenerator < Rails::Generators::NamedBase def create_helper_file create_file "app/helpers/#{file_name}_helper.rb", <<-FILE module #{class_name}Helper @@ -283,7 +283,7 @@ end end -Now, when the helper generator is invoked and TestUnit is configured as the test framework, it will try to invoke both +MyHelper::Generators::TestUnitGenerator+ and +TestUnit::Generators::MyHelperGenerator+. Since none of those are defined, we can tell our generator to invoke +TestUnit::Generators::HelperGenerator+ instead, which is defined since it's a Rails generator. To do that, we just need to add: +Now, when the helper generator is invoked and TestUnit is configured as the test framework, it will try to invoke both +Rails::TestUnitGenerator+ and +TestUnit::MyHelperGenerator+. Since none of those are defined, we can tell our generator to invoke +TestUnit::Generators::HelperGenerator+ instead, which is defined since it's a Rails generator. To do that, we just need to add: # Search for :helper instead of :my_helper -- cgit v1.2.3 From 3efe1b738686482730e05ad50e8d0e667686d2e8 Mon Sep 17 00:00:00 2001 From: vijay Date: Sat, 11 Dec 2010 23:06:54 +0530 Subject: fixed typos and rephrased a few sentences; also removed reference to status codes being located in action_controller/status_codes.rb --- .../guides/source/layouts_and_rendering.textile | 24 +++++++++------------- 1 file changed, 10 insertions(+), 14 deletions(-) (limited to 'railties/guides/source') diff --git a/railties/guides/source/layouts_and_rendering.textile b/railties/guides/source/layouts_and_rendering.textile index 80a1fdd38d..4cdd4f2709 100644 --- a/railties/guides/source/layouts_and_rendering.textile +++ b/railties/guides/source/layouts_and_rendering.textile @@ -106,7 +106,7 @@ Perhaps the simplest thing you can do with +render+ is to render nothing at all: render :nothing => true -If you look at the response for this using Curl you will see the following: +If you look at the response for this using cURL, you will see the following: $ curl -i 127.0.0.1:3000/books @@ -123,7 +123,7 @@ Cache-Control: no-cache $ -We see there is an empty response (no data after the +Cache-Control+ line), but the request was successful because Rails has set the response to 200 OK. You can set the +:status+ options on render to change this response. Rendering nothing can be useful for AJAX requests where all you want to send back to the browser is an acknowledgement that the request was completed. +We see there is an empty response (no data after the +Cache-Control+ line), but the request was successful because Rails has set the response to 200 OK. You can set the +:status+ option on render to change this response. Rendering nothing can be useful for AJAX requests where all you want to send back to the browser is an acknowledgement that the request was completed. TIP: You should probably be using the +head+ method, discussed later in this guide, instead of +render :nothing+. This provides additional flexibility and makes it explicit that you're only generating HTTP headers. @@ -346,7 +346,7 @@ render :status => 500 render :status => :forbidden -Rails understands either numeric status codes or symbols for status codes. You can find its list of status codes in +actionpack/lib/action_controller/status_codes.rb+. You can also see there how Rails maps symbols to status codes. +Rails understands both numeric status codes and symbols for status codes. h6. The +:location+ Option @@ -604,7 +604,7 @@ Which would detect that there are no books, populate the +@books+ instance varia h4. Using +head+ To Build Header-Only Responses -The +head+ method exists to let you send back responses to the browser that have only headers. It provides a more obvious alternative to calling +render :nothing+. The +head+ method takes one response, which is interpreted as a hash of header names and values. For example, you can return only an error header: +The +head+ method can be used to send responses with only headers to the browser. It provides a more obvious alternative to calling +render :nothing+. The +head+ method takes one parameter, which is interpreted as a hash of header names and values. For example, you can return only an error header: head :bad_request @@ -651,11 +651,9 @@ When Rails renders a view as a response, it does so by combining the view with t * +yield+ and +content_for+ * Partials -I'll discuss each of these in turn. - h4. Asset Tags -Asset tags provide methods for generating HTML that links views to assets like images, videos, audio, JavaScript, stylesheets, and feeds. There are six types of include tag: +Asset tags provide methods for generating HTML that links views to feeds, JavaScript, stylesheets, images, videos and audios. These are the six asset tags available in Rails: * +auto_discovery_link_tag+ * +javascript_include_tag+ @@ -680,7 +678,7 @@ The +auto_discovery_link_tag+ helper builds HTML that most browsers and newsread There are three tag options available for +auto_discovery_link_tag+: * +:rel+ specifies the +rel+ value in the link (defaults to "alternate") -* +:type+ specifies an explicit MIME type. Rails will generate an appropriate MIME type automatically +* +:type+ specifies an explicit MIME type. Rails will generate an appropriate MIME type automatically. * +:title+ specifies the title of the link h5. Linking to Javascript Files with +javascript_include_tag+ @@ -829,7 +827,7 @@ You can also supply an alternate image to show on mouseover: <%= image_tag "home.gif", :onmouseover => "menu/home_highlight.gif" %> -Or alternate text if the user has rendering images turned off in their browser, if you do not specify an explicit alt tag, it defaults to the file name of the file, capitalized and with no extension, for example, these two image tags would return the same code: +You can supply alternate text for the image which will be used if the user has images turned off in their browser. If you do not specify an alt text explicitly, it defaults to the file name of the file, capitalized and with no extension. For example, these two image tags would return the same code: <%= image_tag "home.gif" %> @@ -939,7 +937,7 @@ The main body of the view will always render into the unnamed +yield+. To render h4. Using +content_for+ -The +content_for+ method allows you to insert content into a +yield+ block in your layout. You only use +content_for+ to insert content in named yields. For example, this view would work with the layout that you just saw: +The +content_for+ method allows you to insert content into a named +yield+ block in your layout. For example, this view would work with the layout that you just saw: <% content_for :head do %> @@ -966,7 +964,7 @@ The +content_for+ method is very helpful when your layout contains distinct regi h4. Using Partials -Partial templates - usually just called "partials" - are another device for breaking apart the rendering process into more manageable chunks. With a partial, you can move the code for rendering a particular piece of a response to its own file. +Partial templates - usually just called "partials" - are another device for breaking the rendering process into more manageable chunks. With a partial, you can move the code for rendering a particular piece of a response to its own file. h5. Naming Partials @@ -1086,15 +1084,13 @@ Partials are very useful in rendering collections. When you pass a collection to When a partial is called with a pluralized collection, then the individual instances of the partial have access to the member of the collection being rendered via a variable named after the partial. In this case, the partial is +_product+, and within the +_product+ partial, you can refer to +product+ to get the instance that is being rendered. -In Rails 3.0, there is also a shorthand for this. Assuming +@products+ is a collection of +product+ instances, you can simply write this in the +index.html.erb+: +In Rails 3.0, there is also a shorthand for this. Assuming +@products+ is a collection of +product+ instances, you can simply write this in the +index.html.erb+ to produce the same result:

Products

<%= render @products %>
-To produce the same result. - Rails determines the name of the partial to use by looking at the model name in the collection. In fact, you can even create a heterogeneous collection and render it this way, and Rails will choose the proper partial for each member of the collection: * +index.html.erb+ -- cgit v1.2.3 From a6faeffe59ce4160ddd10fd8ec8dca8d88c3a35d Mon Sep 17 00:00:00 2001 From: Vijay Dev Date: Sun, 12 Dec 2010 21:10:03 +0530 Subject: fixed typos in mailer --- railties/guides/source/action_mailer_basics.textile | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) (limited to 'railties/guides/source') diff --git a/railties/guides/source/action_mailer_basics.textile b/railties/guides/source/action_mailer_basics.textile index b75c528a33..b77a0be37b 100644 --- a/railties/guides/source/action_mailer_basics.textile +++ b/railties/guides/source/action_mailer_basics.textile @@ -144,7 +144,7 @@ This provides a much simpler implementation that does not require the registerin The method +welcome_email+ returns a Mail::Message object which can then just be told +deliver+ to send itself out. -NOTE: In previous versions of Rails, you would call +deliver_welcome_email+ or +create_welcome_email+ however in Rails 3.0 this has been deprecated in favour of just calling the method name itself. +NOTE: In previous versions of Rails, you would call +deliver_welcome_email+ or +create_welcome_email+. This has been deprecated in Rails 3.0 in favour of just calling the method name itself. WARNING: Sending out one email should only take a fraction of a second, if you are planning on sending out many emails, or you have a slow domain resolution service, you might want to investigate using a background process like delayed job. @@ -154,7 +154,7 @@ Action Mailer now handles the auto encoding of multibyte characters inside of he If you are using UTF-8 as your character set, you do not have to do anything special, just go ahead and send in UTF-8 data to the address fields, subject, keywords, filenames or body of the email and ActionMailer will auto encode it into quoted printable for you in the case of a header field or Base64 encode any body parts that are non US-ASCII. -For more complex examples, such as defining alternate character sets or self encoding text first, please refer to the Mail library. +For more complex examples such as defining alternate character sets or self encoding text first, please refer to the Mail library. h4. Complete List of Action Mailer Methods @@ -213,9 +213,7 @@ NOTE: If you specify an encoding, Mail will assume that your content is already h5. Making Inline Attachments -Inline attachments are now possible in ActionMailer. While previously in the pre 3.0 version of Rails, you could do inline attachments, it involved a lot of hacking and determination to pull it off. - -ActionMailer now makes inline attachments as trivial as they should be. +ActionMailer 3.0 makes inline attachments, which involved a lot of hacking in pre 3.0 versions, much simpler and trivial as they should be. * Firstly, to tell Mail to turn an attachment into an inline attachment, you just call #inline on the attachments method within your Mailer: @@ -274,7 +272,7 @@ to format the email address in the format "Name <email>". h4. Mailer Views -Mailer views are located in the +app/views/name_of_mailer_class+ directory. The specific mailer view is known to the class because it's name is the same as the mailer method. So for example, in our example from above, our mailer view for the +welcome_email+ method will be in +app/views/user_mailer/welcome_email.html.erb+ for the HTML version and +welcome_email.text.erb+ for the plain text version. +Mailer views are located in the +app/views/name_of_mailer_class+ directory. The specific mailer view is known to the class because its name is the same as the mailer method. In our example from above, our mailer view for the +welcome_email+ method will be in +app/views/user_mailer/welcome_email.html.erb+ for the HTML version and +welcome_email.text.erb+ for the plain text version. To change the default mailer view for your action you do something like: @@ -441,7 +439,7 @@ h3. Action Mailer Configuration The following configuration options are best made in one of the environment files (environment.rb, production.rb, etc...) |template_root|Determines the base from which template references will be made.| -|logger|The logger is used for generating information on the mailing run if available. Can be set to nil for no logging. Compatible with both Ruby's own Logger and Log4r loggers.| +|logger|Generates information on the mailing run if available. Can be set to nil for no logging. Compatible with both Ruby's own Logger and Log4r loggers.| |smtp_settings|Allows detailed configuration for :smtp delivery method:
  • :address - Allows you to use a remote mail server. Just change it from its default "localhost" setting.
  • :port - On the off chance that your mail server doesn't run on port 25, you can change it.
  • :domain - If you need to specify a HELO domain, you can do it here.
  • :user_name - If your mail server requires authentication, set the username in this setting.
  • :password - If your mail server requires authentication, set the password in this setting.
  • :authentication - If your mail server requires authentication, you need to specify the authentication type here. This is a symbol and one of :plain, :login, :cram_md5.
| |sendmail_settings|Allows you to override options for the :sendmail delivery method.
  • :location - The location of the sendmail executable. Defaults to /usr/sbin/sendmail.
  • :arguments - The command line arguments to be passed to sendmail. Defaults to -i -t.
| |raise_delivery_errors|Whether or not errors should be raised if the email fails to be delivered.| @@ -504,7 +502,7 @@ class UserMailerTest < ActionMailer::TestCase end
-In the test we send the email and store the returned object in the +email+ variable. We then ensure that it was sent (the first assert), then, in the second batch of assertions, we ensure that the email does indeed contain the what we expect. +In the test we send the email and store the returned object in the +email+ variable. We then ensure that it was sent (the first assert), then, in the second batch of assertions, we ensure that the email does indeed contain what we expect. h3. Changelog -- cgit v1.2.3 From 0b5671ccca4a9f55379c913a211d669e241ad20c Mon Sep 17 00:00:00 2001 From: Umar Sheikh Date: Mon, 13 Dec 2010 11:18:49 +0500 Subject: for the root route to work, we need to delete the public/index.html.erb file as well --- railties/guides/source/routing.textile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'railties/guides/source') diff --git a/railties/guides/source/routing.textile b/railties/guides/source/routing.textile index bc38e4a6e5..74dee60c32 100644 --- a/railties/guides/source/routing.textile +++ b/railties/guides/source/routing.textile @@ -595,7 +595,7 @@ You can specify what Rails should route +"/"+ to with the +root+ method: root :to => 'pages#main' -You should put the +root+ route at the end of the file. +You should put the +root+ route at the end of the file. You also need to delete the public/index.html.erb file for the root route to take effect. h3. Customizing Resourceful Routes -- cgit v1.2.3 From de4f9acad8b7014b29352a747926ee2db6f71643 Mon Sep 17 00:00:00 2001 From: Elben Shira Date: Tue, 14 Dec 2010 20:35:08 -0600 Subject: It should be ActiveModel::Validator, not ActiveRecord::Validator. --- railties/guides/source/active_record_validations_callbacks.textile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'railties/guides/source') diff --git a/railties/guides/source/active_record_validations_callbacks.textile b/railties/guides/source/active_record_validations_callbacks.textile index 0824ba450c..a15571fe58 100644 --- a/railties/guides/source/active_record_validations_callbacks.textile +++ b/railties/guides/source/active_record_validations_callbacks.textile @@ -414,7 +414,7 @@ class Person < ActiveRecord::Base validates_with GoodnessValidator end -class GoodnessValidator < ActiveRecord::Validator +class GoodnessValidator < ActiveModel::Validator def validate if record.first_name == "Evil" record.errors[:base] << "This person is evil" -- cgit v1.2.3 From 003fce430ab3991ef19cba5eef902510968b2ebd Mon Sep 17 00:00:00 2001 From: Ryan Bigg Date: Wed, 15 Dec 2010 14:08:08 +1000 Subject: WIP: Reviewing the initialization guide for Rails 3.1 --- railties/guides/source/initialization.textile | 514 ++++++++++++++++++++------ 1 file changed, 393 insertions(+), 121 deletions(-) (limited to 'railties/guides/source') diff --git a/railties/guides/source/initialization.textile b/railties/guides/source/initialization.textile index 4cc5f3843f..72e10191f9 100644 --- a/railties/guides/source/initialization.textile +++ b/railties/guides/source/initialization.textile @@ -1,79 +1,140 @@ h2. The Rails Initialization Process -This guide explains how the initialization process in Rails works as of Rails 3. +This guide explains the internals of the initialization process in Rails works as of Rails 3.1. It is an extremely in-depth guide and recommended for advanced Rails developers. * Using +rails server+ * Using Passenger endprologue. -This guide first describes the process of +rails server+ then explains the Passenger + Rack method, before delving into the common initialize pattern these two go through. +This guide goes through every single file, class and method call that is required to boot up the Ruby on Rails stack for a default Rails 3.1 application, explaining each part in detail a long the way. For this guide, we will be focusing on how the two most common methods (+rails server+ and Passenger) boot a Rails application. + +NOTE: Paths in this guide are relative to Rails or a Rails application unless otherwise specified. h3. Launch! As of Rails 3, +script/server+ has become +rails server+. This was done to centralize all rails related commands to one common file. -The actual +rails+ command is kept in _railties/bin/rails_ and goes like this: +h4. +bin/rails+ + +The actual +rails+ command is kept in _bin/rails_ at the and goes like this: - require 'rbconfig' + #!/usr/bin/env ruby - module Rails - module ScriptRailsLoader - RUBY = File.join(*RbConfig::CONFIG.values_at("bindir", "ruby_install_name")) + RbConfig::CONFIG["EXEEXT"] - SCRIPT_RAILS = File.join('script', 'rails') - - def self.exec_script_rails! - cwd = Dir.pwd - exec RUBY, SCRIPT_RAILS, *ARGV if File.exists?(SCRIPT_RAILS) - Dir.chdir("..") do - # Recurse in a chdir block: if the search fails we want to be sure - # the application is generated in the original working directory. - exec_script_rails! unless cwd == Dir.pwd - end - rescue SystemCallError - # could not chdir, no problem just return - end - end + begin + require "rails/cli" + rescue LoadError + railties_path = File.expand_path('../../railties/lib', __FILE__) + $:.unshift(railties_path) + require "rails/cli" end + - Rails::ScriptRailsLoader.exec_script_rails! +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. - railties_path = File.expand_path('../../lib', __FILE__) - $:.unshift(railties_path) if File.directory?(railties_path) && !$:.include?(railties_path) +h4. +railites/lib/rails/cli.rb+ + +This file looks like this: + + + require 'rbconfig' + require 'rails/script_rails_loader' + + # If we are inside a Rails application this method performs an exec and thus + # the rest of this script is not run. + Rails::ScriptRailsLoader.exec_script_rails! require 'rails/ruby_version_check' Signal.trap("INT") { puts; exit } - require 'rails/commands/application' + if ARGV.first == 'plugin' + ARGV.shift + require 'rails/commands/plugin_new' + else + require 'rails/commands/application' + end -The +Rails::ScriptRailsLoader+ module here defines two constants: +RUBY+ and +SCRIPT_RAILS+. +RUBY+ is the full path to your ruby executable, on a Snow Leopard system it's _/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/ruby_. +SCRIPT_RAILS+ is simply _script/rails_. When +exec_script_rails+ is invoked, this will attempt to +exec+ the _rails_ file in the _script_ directory using the path to your Ruby executable, +RUBY+. If +exec+ is invoked, the program will stop at this point. If the _script/rails_ file doesn't exist in the current directory, Rails will recurse upwards until it finds it by calling +exec_script_rails+ from inside the +Dir.chdir("..")+. This is handy if you're currently in one of the sub-directories of the rails application and wish to launch a server or a console. +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+. + + +require 'pathname' + +module Rails + module ScriptRailsLoader + RUBY = File.join(*RbConfig::CONFIG.values_at("bindir", "ruby_install_name")) + RbConfig::CONFIG["EXEEXT"] + SCRIPT_RAILS = File.join('script', 'rails') + ... -If Rails cannot execute _script/rails_ then it will fall back to the standard +rails+ command task of generating an application. + end +end + + +The +rails/script_rails_loader+ file uses +RbConfig::Config+ to gather up the +bin_dir+ and +ruby_install_name+ values for the configuration which will result in a path such as +/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/ruby+, which is the default path on Mac OS X. If you're running Windows the path may be something such as +C:/Ruby192/bin/ruby+. Anyway, the path on your system may be different, but the point of this is that it will point at the known ruby executable location for your install. The +RbConfig::CONFIG["EXEEXT"]+ will suffix this path with ".exe" if the script is running on Windows. This constant is used later on in +exec_script_rails!+. As for the +SCRIPT_RAILS+ console, we'll see that when we get to the +in_rails_application?+ method. -In +script/rails+ we see the following: +Back in +rails/cli+, the next line is this: - #!/usr/bin/env ruby - # This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application. + Rails::ScriptRailsLoader.exec_script_rails! + - APP_PATH = File.expand_path('../../config/application', __FILE__) - require File.expand_path('../../config/boot', __FILE__) - require 'rails/commands' +This method is defined in +rails/script_rails_loader+ like this: + + + def self.exec_script_rails! + cwd = Dir.pwd + return unless in_rails_application? || in_rails_application_subdirectory? + exec RUBY, SCRIPT_RAILS, *ARGV if in_rails_application? + Dir.chdir("..") do + # Recurse in a chdir block: if the search fails we want to be sure + # the application is generated in the original working directory. + exec_script_rails! unless cwd == Dir.pwd + end + rescue SystemCallError + # could not chdir, no problem just return + end -This obviously defines a couple of constants to some pretty important files, _config/environment.rb_, _config/boot.rb_ and _config/application.rb_ all within the context of +__FILE__+ which is of course +script/rails+ in the root of your application. Then it goes on to +require BOOT_PATH+ which leads us onto _config/boot.rb_. +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: -h3. Passenger + + def self.in_rails_application? + File.exists?(SCRIPT_RAILS) + end + -Before we dive into what _config/boot.rb_ encompasses, we'll just glimpse at what Passenger does enough to get an understanding of how it requires a Rails application. +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: + + + def self.in_rails_application_subdirectory?(path = Pathname.new(Dir.pwd)) + File.exists?(File.join(path, SCRIPT_RAILS)) || !path.root? && in_rails_application_subdirectory?(path.parent) + end + + +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: + + + exec RUBY, SCRIPT_RAILS, *ARGV if in_rails_application? + + +This is effectively the same as doing +ruby script/rails [arguments]+. Where +[arguments]+ at this point in time is simply "server". + +h4. +script/rails+ + +This file looks like this: + + + APP_PATH = File.expand_path('../../config/application', __FILE__) + require File.expand_path('../../config/boot', __FILE__) + require 'rails/commands' + -Passenger will require _config/environment.rb_ by way of its +PhusionPassenger::Railz::ApplicationSpawner#preload_application+ method. _config/environment.rb_ requires _config/application.rb_ which requires _config/boot.rb_. That's how the Rails boot process begins with Passenger in a nutshell. +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. -h3. _config/boot.rb_ +h4. +config/boot.rb+ -_config/boot.rb_ is the first stop for everything for initializing your application. This boot process does quite a bit of work for you and so this section attempts to go in-depth enough to explain what each of the pieces does. ++config/boot.rb+ contains this: require 'rubygems' @@ -91,134 +152,345 @@ _config/boot.rb_ is the first stop for everything for initializing your applicat end if File.exist?(gemfile) -h3. Bundled Rails (3.x) +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: + +* abstract (1.0.0) +* actionmailer (3.1.0.beta) +* actionpack (3.1.0.beta) +* activemodel (3.1.0.beta) +* activerecord (3.1.0.beta) +* activeresource (3.1.0.beta) +* activesupport (3.1.0.beta) +* arel (2.0.7) +* builder (3.0.0) +* bundler (1.0.6) +* erubis (2.6.6) +* i18n (0.5.0) +* mail (2.2.12) +* mime-types (1.16) +* polyglot (0.3.1) +* rack (1.2.1) +* rack-cache (0.5.3) +* rack-mount (0.6.13) +* rack-test (0.5.6) +* rails (3.1.0.beta) +* railties (3.1.0.beta) +* rake (0.8.7) +* sqlite3-ruby (1.3.2) +* thor (0.14.6) +* treetop (1.4.9) +* tzinfo (0.3.23) + +h4. +rails/commands.rb+ + +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: + + + aliases = { + "g" => "generate", + "c" => "console", + "s" => "server", + "db" => "dbconsole" + } + + command = ARGV.shift + command = aliases[command] || command + + +If we used s 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: + + + when 'server' + # Change to the application's path if there is no config.ru file in current dir. + # This allows us to run script/rails server from other directories, but still get + # the main config.ru and properly set the tmp directory. + Dir.chdir(File.expand_path('../../', APP_PATH)) unless File.exists?(File.expand_path("config.ru")) + + require 'rails/commands/server' + Rails::Server.new.tap { |server| + # We need to require application after the server sets environment, + # otherwise the --environment option given to the server won't propagate. + require APP_PATH + Dir.chdir(Rails.application.root) + server.start + } + + +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. + +h4. +actionpack/lib/action_dispatch.rb+ + +Action Dispatch is the routing component of the Rails framework. It depends on Active Support, +actionpack/lib/action_pack.rb+ and +Rack+ being available. The first thing required here is +active_support+. + +h4. +active_support/lib/active_support.rb+ + +This file begins with requiring +active_support/lib/active_support/dependencies/autoload.rb+ which redefines Ruby's +autoload+ method to have a little more extra behaviour especially in regards to eager autoloading. Eager autoloading is the loading of all required classes and will happen when the +config.cache_classes+ setting is +true+. +The +active_support/lib/active_support/version.rb+ that is also required here simply defines an +ActiveSupport::VERSION+ constant which defines a couple of constants inside this module, the main constant of this is +ActiveSupport::VERSION::STRING+ which returns the current version of ActiveSupport. -Rails 3 now uses Bundler and the README for the project explains it better than I could: +The +active_support/lib/active_support.rb+ file simply defines the +ActiveSupport+ module and some autoloads (eager and of the normal variety) for it. -> "Bundler is a tool that manages gem dependencies for your ruby application. It takes a gem manifest file and is able to fetch, download, and install the gems and all child dependencies specified in this manifest. It can manage any update to the gem manifest file and update the bundle's gems accordingly. It also lets you run any ruby code in context of the bundle's gem environment." +h4. +actionpack/lib/action_dispatch.rb+ cont'd. -Now with Rails 3 we have a Gemfile which defines the basics our application needs to get going: +Now back to +action_pack/lib/action_dispatch.rb+. The next +require+ in this file is one for +action_pack+, which simply calls +action_pack/version.rb+ which defines +ActionPack::VERSION+ and the constants, much like +ActiveSpport+ does. + +After this line, there's a require to +active_model+ which simply defines autoloads for the +ActiveModel+ part of Rails and sets up the +ActiveModel+ module which is used later on. + +The last of the requires is to +rack+, which like the +active_model+ and +active_support+ requires before it, sets up the +Rack+ module as well as the autoloads for constants within it. + +Finally in +action_dispatch.rb+ the +ActionDispatch+ module and *its* autoloads are declared. + +h4. +rails/commands/server.rb+ + +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+: - source 'http://rubygems.org' + def initialize(*) + super + set_environment + end + - gem 'rails', '3.0.0' +Firstly, +super+ is called which calls the +initialize+ method on +Rack::Server+. - # Bundle edge Rails instead: - # gem 'rails', :git => 'git://github.com/rails/rails.git' +h4. Rack: +lib/rack/server.rb+ - gem 'sqlite3-ruby', :require => 'sqlite3' ++Rack::Server+ is responsible for providing a common server interface for all Rack-based applications, which Rails is now a part of. - # Use unicorn as the web server - # gem 'unicorn' +The +initialize+ method in +Rack::Server+ simply sets a couple of variables: - # Deploy with Capistrano - # gem 'capistrano' + + def initialize(options = nil) + @options = options + @app = options[:app] if options && options[:app] + end + - # Bundle the extra gems: - # gem 'bj' - # gem 'nokogiri' - # gem 'sqlite3-ruby', :require => 'sqlite3' - # gem 'aws-s3', :require => 'aws/s3' +In this case, +options+ will be +nil+ so nothing happens in this method. - # Bundle gems for certain environments: - # gem 'rspec', :group => :test - # group :test do - # gem 'webrat' - # end +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: + + def set_environment + ENV["RAILS_ENV"] ||= options[:environment] + end -Here the only two gems we need are +rails+ and +sqlite3-ruby+, so it seems. This is until you run +bundle pack+. This command freezes all the gems required by your application into _vendor/cache_. The gems installed by default are: +In fact, the +options+ method here does quite a lot. This method is defined in +Rack::Server+ like this: -* abstract-1.0.0.gem -* actionmailer-3.0.0.gem -* actionpack-3.0.0.gem -* activemodel-3.0.0.gem -* activerecord-3.0.0.gem -* activeresource-3.0.0.gem -* activesupport-3.0.0.gem -* arel-0.4.0.gem -* builder-2.1.2.gem -* bundler-1.0.3.gem -* erubis-2.6.6.gem -* i18n-0.4.1.gem -* mail-2.2.5.gem -* memcache-client-1.8.5.gem -* mime-types-1.16.gem -* nokogiri-1.4.3.1.gem -* polyglot-0.3.1.gem -* rack-1.2.1.gem -* rack-mount-0.6.12.gem -* rack-test-0.5.4.gem -* rails-3.0.0.gem -* railties-3.0.0.gem -* rake-0.8.7.gem -* sqlite3-ruby-1.3.1.gem -* text-format-1.0.0.gem -* text-hyphen-1.0.0.gem -* thor-0.13.7.gem -* treetop-1.4.8.gem -* tzinfo-0.3.23.gem + + def options + @options ||= parse_options(ARGV) + end + -TODO: Prettify when it becomes more stable. +Then +parse_options+ is defined like this: -I won't go into what each of these gems are, as that is really something that needs covering on a case-by-case basis. We will however just dig a little under the surface of Bundler. + + def parse_options(args) + options = default_options -Back in _config/boot.rb_, we call +Bundler.setup+ which will load and parse the +Gemfile+ and add the _lib_ directory of the gems mentioned **and** their dependencies (**and** their dependencies' dependencies, and so on) to the +$LOAD_PATH+. + # Don't evaluate CGI ISINDEX parameters. + # http://hoohoo.ncsa.uiuc.edu/cgi/cl.html + args.clear if ENV.include?("REQUEST_METHOD") -h3. Requiring Rails + options.merge! opt_parser.parse! args + options[:config] = ::File.expand_path(options[:config]) + ENV["RACK_ENV"] = options[:environment] + options + end + -After _config/boot.rb_ is loaded, there's this +require+: +With the +default_options+ set to this: - require 'rails/commands' + def default_options + { + :environment => ENV['RACK_ENV'] || "development", + :pid => nil, + :Port => 9292, + :Host => "0.0.0.0", + :AccessLog => [], + :config => "config.ru" + } + end -In this file, _railties/lib/rails/commands.rb_, there is a case statement for +ARGV.shift+: +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+ - case ARGV.shift - ... - when 's', 'server' - require 'rails/commands/server' - # Initialize the server first, so environment options are set - server = Rails::Server.new - require APP_PATH + def opt_parser + Options.new + end + + +The class *is* defined in +Rack::Server+, but is overwritten in +Rails::Server+ to take different arguments. Its +parse!+ method begins like this: + + + def parse!(args) + args, options = args.dup, {} + + opt_parser = OptionParser.new do |opts| + opts.banner = "Usage: rails server [mongrel, thin, etc] [options]" + opts.on("-p", "--port=port", Integer, + "Runs Rails on the specified port.", "Default: 3000") { |v| options[:Port] = v } ... + + +This method will set up keys for the +options+ which Rails will then be able to use to determine how its server should run. After +initialize+ has finished, then the +start+ method will launch the server. + +h4. +Rails::Server#start+ + +This method is defined like this: + + + def start + puts "=> Booting #{ActiveSupport::Inflector.demodulize(server)}" + puts "=> Rails #{Rails.version} application starting in #{Rails.env} on http://#{options[:Host]}:#{options[:Port]}" + puts "=> Call with -d to detach" unless options[:daemonize] + trap(:INT) { exit } + puts "=> Ctrl-C to shutdown server" unless options[:daemonize] + + #Create required tmp directories if not found + %w(cache pids sessions sockets).each do |dir_to_make| + FileUtils.mkdir_p(Rails.root.join('tmp', dir_to_make)) + end + + super + ensure + # The '-h' option calls exit before @options is set. + # If we call 'options' with it unset, we get double help banners. + puts 'Exiting' unless @options && options[:daemonize] end -We're running +rails server+ and this means it will make a require out to _rails/commands/server_ (_railties/lib/rails/commands/server.rb_). Firstly, this file makes a couple of requires of its own: +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: + + + def start + if options[:warn] + $-w = true + end + + if includes = options[:include] + $LOAD_PATH.unshift(*includes) + end + + if library = options[:require] + require library + end + + if options[:debug] + $DEBUG = true + require 'pp' + p options[:server] + pp wrapped_app + pp app + end + + +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: - require 'fileutils' - require 'optparse' - require 'action_dispatch' + wrapped_app -The first two are Ruby core and this guide does not cover what they do, but _action_dispatch_ (_actionpack/lib/action_dispatch.rb_) is important. This file firstly make a require to _active_support_ (_activesupport/lib/active_support.rb_) which defines the +ActiveSupport+ module. +This method calls another method: -h4. +require 'active_support'+ + + @wrapped_app ||= build_app app + -_activesupport/lib/active_support.rb_ sets up +module ActiveSupport+: +Then the +app+ method here is defined like so: - module ActiveSupport - class << self - attr_accessor :load_all_hooks - def on_load_all(&hook) load_all_hooks << hook end - def load_all!; load_all_hooks.each { |hook| hook.call } end + def app + @app ||= begin + if !::File.exist? options[:config] + abort "configuration #{options[:config]} not found" + end + + app, options = Rack::Builder.parse_file(self.options[:config], opt_parser) + self.options.merge! options + app end - self.load_all_hooks = [] + end + + +The +options[:config]+ value defaults to +config.ru+ which contains this: + + + # This file is used by Rack-based servers to start the application. + + require ::File.expand_path('../config/environment', __FILE__) + run YourApp::Application + + + +The +Rack::Builder.parse_file+ method here takes the content from this +config.ru+ file and parses it using this code: + + + app = eval "Rack::Builder.new {( " + cfgfile + "\n )}.to_app", + TOPLEVEL_BINDING, config + + +The initialize 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: + + + require ::File.expand_path('../config/environment', __FILE__) + + +h4. +config/environment.rb+ + +This file is the common file required by +config.ru+ (+rails server+) and Passenger. This is where these two ways to run the server meet; everything before this point has been Rack and Rails setup. + +This file begins with requiring +config/application.rb+. + +h4. +config/application.rb+ + +This file requires +config/boot.rb+, but only if it hasn't been required before, which would be the case in +rails server+ but *wouldn't* be the case with Passenger. + +Then the fun begins! The next line is: - on_load_all do - [Dependencies, Deprecation, Gzip, MessageVerifier, Multibyte, SecureRandom] + + require 'rails/all' + + +h4 +railties/lib/rails/all.rb+ + + +This file is responsible for requiring all the individual parts of Rails like so: + + + require "rails" + + %w( + active_record + action_controller + action_mailer + active_resource + rails/test_unit + ).each do |framework| + begin + require "#{framework}/railtie" + rescue LoadError end end +First off the line is the +rails+ require itself. + +h4. +railties/lib/rails.rb+ + +This file is responsible for the initial definition of the +Rails+ module and, rather than defining the autoloads like +ActiveSupport+, +ActionDispatch+ and so on, it actually defines other functionality. Such as the +root+, +env+ and +application+ methods which are extremely useful in Rails 3 applications. + +However, before all that takes place the +rails/ruby_version_check+ file is required first. + + + + +**** REVIEW IS HERE **** + This defines two methods on the module itself by using the familiar +class << self+ syntax. This allows you to call them as if they were class methods: +ActiveSupport.on_load_all+ and +ActiveSupport.load_all!+ respectively. The first method simply adds loading hooks to save them up for loading later on when +load_all!+ is called. By +call+'ing the block, the classes will be loaded. (NOTE: kind of guessing, I feel 55% about this). The +on_load_all+ method is called later with the +Dependencies+, +Deprecation+, +Gzip+, +MessageVerifier+, +Multibyte+ and +SecureRandom+. What each of these modules do will be covered later. -- cgit v1.2.3 From a7791c375228472f2d51705bcee01eced982df3a Mon Sep 17 00:00:00 2001 From: Ryan Bigg Date: Wed, 15 Dec 2010 16:17:55 +1000 Subject: Active Support coreext guide: Logger core extension documentation --- .../source/active_support_core_extensions.textile | 43 ++++++++++++++++++++++ 1 file changed, 43 insertions(+) (limited to 'railties/guides/source') diff --git a/railties/guides/source/active_support_core_extensions.textile b/railties/guides/source/active_support_core_extensions.textile index 7333a81cf9..2e295aec3d 100644 --- a/railties/guides/source/active_support_core_extensions.textile +++ b/railties/guides/source/active_support_core_extensions.textile @@ -3359,6 +3359,49 @@ The auxiliary file is written in a standard directory for temporary files, but y NOTE: Defined in +active_support/core_ext/file/atomic.rb+. +h3. Extensions to +Logger+ + +h4. +around_[level]+ + +Takes two arguments, a +before_message+ and +after_message+ and calls the current level method on the +Logger+ instance, passing in the +before_message+, then the specified message, then the +after_message+: + + + logger = Logger.new("log/development.log") + logger.around_info("before", "after") { |logger| logger.info("during") } + + +h4. +silence+ + +Silences every log level lesser to the specified one for the duration of the given block. Log level orders are: debug, info, error and fatal. + + + logger = Logger.new("log/development.log") + logger.silence(Logger::INFO) do + logger.debug("In space, no one can hear you scream.") + logger.info("Scream all you want, small mailman!") + end + + +h4. +datetime_format=+ + +Modifies the datetime format output by the formatter class associated with this logger. If the formatter class does not have a +datetime_format+ method then this is ignored. + + + class Logger::FormatWithTime < Logger::Formatter + cattr_accessor(:datetime_format) { "%Y%m%d%H%m%S" } + + def self.call(severity, timestamp, progname, msg) + "#{timestamp.strftime(datetime_format)} -- #{String === msg ? msg : msg.inspect}\n" + end + end + + logger = Logger.new("log/development.log") + logger.formatter = Logger::FormatWithTime + logger.info("<- is the current time") + + +NOTE: Defined in +active_support/core_ext/logger.rb+. + h3. Extensions to +NameError+ Active Support adds +missing_name?+ to +NameError+, which tests whether the exception was raised because of the name passed as argument. -- cgit v1.2.3 From e15a55c862c98d05ff95e7fa3162ed1298ba8be7 Mon Sep 17 00:00:00 2001 From: Vijay Dev Date: Wed, 15 Dec 2010 22:35:09 +0530 Subject: filter_parameter_logging is deprecated in Rails 3. Changed it to config.filter_parameters --- railties/guides/source/security.textile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'railties/guides/source') diff --git a/railties/guides/source/security.textile b/railties/guides/source/security.textile index 528c8861d4..9963106ff3 100644 --- a/railties/guides/source/security.textile +++ b/railties/guides/source/security.textile @@ -524,10 +524,10 @@ h4. Logging -- _Tell Rails not to put passwords in the log files._ -By default, Rails logs all requests being made to the web application. But log files can be a huge security issue, as they may contain login credentials, credit card numbers et cetera. When designing a web application security concept, you should also think about what will happen if an attacker got (full) access to the web server. Encrypting secrets and passwords in the database will be quite useless, if the log files list them in clear text. You can _(highlight)filter certain request parameters from your log files_ by the filter_parameter_logging method in a controller. These parameters will be marked [FILTERED] in the log. +By default, Rails logs all requests being made to the web application. But log files can be a huge security issue, as they may contain login credentials, credit card numbers et cetera. When designing a web application security concept, you should also think about what will happen if an attacker got (full) access to the web server. Encrypting secrets and passwords in the database will be quite useless, if the log files list them in clear text. You can _(highlight)filter certain request parameters from your log files_ by appending them to config.filter_parameters in the application configuration. These parameters will be marked [FILTERED] in the log. -filter_parameter_logging :password +config.filter_parameters << :password h4. Good Passwords -- cgit v1.2.3 From 7a028eae7914f8099b4369b51c2d06a47ecdab9e Mon Sep 17 00:00:00 2001 From: Vijay Dev Date: Wed, 15 Dec 2010 23:13:22 +0530 Subject: fixed font --- railties/guides/source/security.textile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'railties/guides/source') diff --git a/railties/guides/source/security.textile b/railties/guides/source/security.textile index 9963106ff3..fbafc40d93 100644 --- a/railties/guides/source/security.textile +++ b/railties/guides/source/security.textile @@ -524,7 +524,7 @@ h4. Logging -- _Tell Rails not to put passwords in the log files._ -By default, Rails logs all requests being made to the web application. But log files can be a huge security issue, as they may contain login credentials, credit card numbers et cetera. When designing a web application security concept, you should also think about what will happen if an attacker got (full) access to the web server. Encrypting secrets and passwords in the database will be quite useless, if the log files list them in clear text. You can _(highlight)filter certain request parameters from your log files_ by appending them to config.filter_parameters in the application configuration. These parameters will be marked [FILTERED] in the log. +By default, Rails logs all requests being made to the web application. But log files can be a huge security issue, as they may contain login credentials, credit card numbers et cetera. When designing a web application security concept, you should also think about what will happen if an attacker got (full) access to the web server. Encrypting secrets and passwords in the database will be quite useless, if the log files list them in clear text. You can _(highlight)filter certain request parameters from your log files_ by appending them to config.filter_parameters in the application configuration. These parameters will be marked [FILTERED] in the log. config.filter_parameters << :password -- cgit v1.2.3 From 80382c7465af27194dc9644b8ba4c4ad458b7ef7 Mon Sep 17 00:00:00 2001 From: Vijay Dev Date: Thu, 16 Dec 2010 00:16:28 +0530 Subject: fixed link to ruby-prof --- railties/guides/source/performance_testing.textile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'railties/guides/source') diff --git a/railties/guides/source/performance_testing.textile b/railties/guides/source/performance_testing.textile index 41bdd27e9b..b9401f3559 100644 --- a/railties/guides/source/performance_testing.textile +++ b/railties/guides/source/performance_testing.textile @@ -398,7 +398,7 @@ $ rails benchmarker 'Item.first' 'Item.last' h4. +profiler+ -+profiler+ is a wrapper around http://ruby-prof.rubyforge.org/[ruby-prof] gem. ++profiler+ is a wrapper around the "ruby-prof":http://ruby-prof.rubyforge.org gem. Usage: -- cgit v1.2.3