diff options
52 files changed, 669 insertions, 254 deletions
diff --git a/actionpack/lib/action_controller.rb b/actionpack/lib/action_controller.rb index 39083a84e9..098dfcf5a2 100644 --- a/actionpack/lib/action_controller.rb +++ b/actionpack/lib/action_controller.rb @@ -29,7 +29,7 @@ require File.join(File.dirname(__FILE__), "action_pack") module ActionController # TODO: Review explicit to see if they will automatically be handled by - # the initilizer if they are really needed. + # the initializer if they are really needed. def self.load_all! [Base, Request, Response, UrlRewriter, UrlWriter] [ActionDispatch::Http::Headers] diff --git a/actionpack/lib/action_controller/base/base.rb b/actionpack/lib/action_controller/base/base.rb index 2813e71d12..0993b311cd 100644 --- a/actionpack/lib/action_controller/base/base.rb +++ b/actionpack/lib/action_controller/base/base.rb @@ -328,7 +328,7 @@ module ActionController #:nodoc: cattr_accessor :use_accept_header self.use_accept_header = true - # Controls whether request forgergy protection is turned on or not. Turned off by default only in test mode. + # Controls whether request forgery protection is turned on or not. Turned off by default only in test mode. class_inheritable_accessor :allow_forgery_protection self.allow_forgery_protection = true diff --git a/actionpack/lib/action_controller/base/http_authentication.rb b/actionpack/lib/action_controller/base/http_authentication.rb index fa8ecea408..0be53cb02d 100644 --- a/actionpack/lib/action_controller/base/http_authentication.rb +++ b/actionpack/lib/action_controller/base/http_authentication.rb @@ -273,7 +273,7 @@ module ActionController # # The nonce is opaque to the client. Composed of Time, and hash of Time with secret # key from the Rails session secret generated upon creation of project. Ensures - # the time cannot be modifed by client. + # the time cannot be modified by client. def nonce(time = Time.now) t = time.to_i hashed = [t, secret_key] diff --git a/actionpack/lib/action_controller/base/mime_responds.rb b/actionpack/lib/action_controller/base/mime_responds.rb index 1003e61a0b..9ec8883f8e 100644 --- a/actionpack/lib/action_controller/base/mime_responds.rb +++ b/actionpack/lib/action_controller/base/mime_responds.rb @@ -94,6 +94,18 @@ module ActionController #:nodoc: # Note that you can define your own XML parameter parser which would allow you to describe multiple entities # in a single request (i.e., by wrapping them all in a single root node), but if you just go with the flow # and accept Rails' defaults, life will be much easier. + # + # Further more, you may call the #any method on the block's object in order to run the same code for different responses. + # def index + # + # respond_to do |format| + # format.html { @people = People.all(:limit => 10) } + # format.any(:xml, :atom) { @people = People.all } + # end + # end + # + # This will limit the @people variable to 10 people records if we're requesting HTML, but will list all the + # people for any xml or atom request. # # If you need to use a MIME type which isn't supported by default, you can register your own handlers in # environment.rb as follows. diff --git a/actionpack/lib/action_controller/base/request_forgery_protection.rb b/actionpack/lib/action_controller/base/request_forgery_protection.rb index 3067122ceb..df91dc1006 100644 --- a/actionpack/lib/action_controller/base/request_forgery_protection.rb +++ b/actionpack/lib/action_controller/base/request_forgery_protection.rb @@ -96,8 +96,7 @@ module ActionController #:nodoc: !request.content_type.nil? && request.content_type.verify_request? end - # Sets the token value for the current session. Pass a <tt>:secret</tt> option - # in +protect_from_forgery+ to add a custom salt to the hash. + # Sets the token value for the current session. def form_authenticity_token session[:_csrf_token] ||= ActiveSupport::SecureRandom.base64(32) end diff --git a/actionpack/lib/action_controller/routing.rb b/actionpack/lib/action_controller/routing.rb index ce59866531..5b9ded83dd 100644 --- a/actionpack/lib/action_controller/routing.rb +++ b/actionpack/lib/action_controller/routing.rb @@ -139,7 +139,7 @@ module ActionController # # In routes.rb # map.with_options :controller => 'blog' do |blog| # blog.show '', :action => 'list' - # blog.delete 'delete/:id', :action => 'delete', + # blog.delete 'delete/:id', :action => 'delete' # blog.edit 'edit/:id', :action => 'edit' # end # diff --git a/actionpack/lib/action_controller/routing/generation/url_rewriter.rb b/actionpack/lib/action_controller/routing/generation/url_rewriter.rb index 16720b915b..9717582b5e 100644 --- a/actionpack/lib/action_controller/routing/generation/url_rewriter.rb +++ b/actionpack/lib/action_controller/routing/generation/url_rewriter.rb @@ -93,7 +93,7 @@ module ActionController # # * <tt>:only_path</tt> - If true, the relative url is returned. Defaults to +false+. # * <tt>:protocol</tt> - The protocol to connect to. Defaults to 'http'. - # * <tt>:host</tt> - Specifies the host the link should be targetted at. + # * <tt>:host</tt> - Specifies the host the link should be targeted at. # If <tt>:only_path</tt> is false, this option must be # provided either explicitly, or via +default_url_options+. # * <tt>:port</tt> - Optionally specify the port to connect to. diff --git a/actionpack/lib/action_controller/routing/route_set.rb b/actionpack/lib/action_controller/routing/route_set.rb index 45ad8a3a3b..fb344f6c6b 100644 --- a/actionpack/lib/action_controller/routing/route_set.rb +++ b/actionpack/lib/action_controller/routing/route_set.rb @@ -155,7 +155,7 @@ module ActionController def define_url_helper(route, name, kind, options) selector = url_helper_name(name, kind) - # The segment keys used for positional paramters + # The segment keys used for positional parameters hash_access_method = hash_access_name(name, kind) diff --git a/actionpack/lib/action_controller/testing/test_case.rb b/actionpack/lib/action_controller/testing/test_case.rb index 7b4eda58e5..a11755b517 100644 --- a/actionpack/lib/action_controller/testing/test_case.rb +++ b/actionpack/lib/action_controller/testing/test_case.rb @@ -56,7 +56,7 @@ module ActionController # # ActionController::TestCase will automatically infer the controller under test # from the test class name. If the controller cannot be inferred from the test - # class name, you can explicity set it with +tests+. + # class name, you can explicitly set it with +tests+. # # class SpecialEdgeCaseWidgetsControllerTest < ActionController::TestCase # tests WidgetController @@ -182,7 +182,7 @@ module ActionController @controller.send(:initialize_current_url) end end - + # Cause the action to be rescued according to the regular rules for rescue_action when the visitor is not local def rescue_action_in_public! @request.remote_addr = '208.77.188.166' # example.com diff --git a/actionpack/lib/action_view/helpers/asset_tag_helper.rb b/actionpack/lib/action_view/helpers/asset_tag_helper.rb index a32beb6100..bfda866a55 100644 --- a/actionpack/lib/action_view/helpers/asset_tag_helper.rb +++ b/actionpack/lib/action_view/helpers/asset_tag_helper.rb @@ -169,15 +169,16 @@ module ActionView ) end - # Computes the path to a javascript asset in the public javascripts directory. - # If the +source+ filename has no extension, .js will be appended. - # Full paths from the document root will be passed through. - # Used internally by javascript_include_tag to build the script path. + # Computes the path to a JavaScript asset in the public javascripts directory. + # If the +source+ filename has no extension, <tt>.js</tt> will be appended. + # Full paths from the document root are passed through, URLs remain + # untouched. Local files get a timestamp appended as query string. + # Used internally by <tt>javascript_include_tag</tt> to build the script path. # # ==== Examples - # javascript_path "xmlhr" # => /javascripts/xmlhr.js - # javascript_path "dir/xmlhr.js" # => /javascripts/dir/xmlhr.js - # javascript_path "/dir/xmlhr" # => /dir/xmlhr.js + # javascript_path "xmlhr" # => /javascripts/xmlhr.js?1240848408 + # javascript_path "dir/xmlhr.js" # => /javascripts/dir/xmlhr.js?1239899358 + # javascript_path "/dir/xmlhr" # => /dir/xmlhr.js?1240300432 # javascript_path "http://www.railsapplication.com/js/xmlhr" # => http://www.railsapplication.com/js/xmlhr.js # javascript_path "http://www.railsapplication.com/js/xmlhr.js" # => http://www.railsapplication.com/js/xmlhr.js def javascript_path(source) @@ -197,14 +198,14 @@ module ActionView # # ==== Examples # javascript_include_tag "xmlhr" # => - # <script type="text/javascript" src="/javascripts/xmlhr.js"></script> + # <script type="text/javascript" src="/javascripts/xmlhr.js?1240848408"></script> # # javascript_include_tag "xmlhr.js" # => - # <script type="text/javascript" src="/javascripts/xmlhr.js"></script> + # <script type="text/javascript" src="/javascripts/xmlhr.js?1240848408"></script> # # javascript_include_tag "common.javascript", "/elsewhere/cools" # => - # <script type="text/javascript" src="/javascripts/common.javascript"></script> - # <script type="text/javascript" src="/elsewhere/cools.js"></script> + # <script type="text/javascript" src="/javascripts/common.javascript?1239899358"></script> + # <script type="text/javascript" src="/elsewhere/cools.js?1240300432"></script> # # javascript_include_tag "http://www.railsapplication.com/xmlhr" # => # <script type="text/javascript" src="http://www.railsapplication.com/xmlhr.js"></script> @@ -213,25 +214,25 @@ module ActionView # <script type="text/javascript" src="http://www.railsapplication.com/xmlhr.js"></script> # # javascript_include_tag :defaults # => - # <script type="text/javascript" src="/javascripts/prototype.js"></script> - # <script type="text/javascript" src="/javascripts/effects.js"></script> + # <script type="text/javascript" src="/javascripts/prototype.js?1240300432"></script> + # <script type="text/javascript" src="/javascripts/effects.js?1240300432"></script> # ... - # <script type="text/javascript" src="/javascripts/application.js"></script> + # <script type="text/javascript" src="/javascripts/application.js?1240300432"></script> # # * = The application.js file is only referenced if it exists # # Though it's not really recommended practice, if you need to extend the default JavaScript set for any reason - # (e.g., you're going to be using a certain .js file in every action), then take a look at the register_javascript_include_default method. + # (e.g., you're going to be using a certain .js file in every action), then take a look at the <tt>register_javascript_include_default</tt> method. # # You can also include all javascripts in the javascripts directory using <tt>:all</tt> as the source: # # javascript_include_tag :all # => - # <script type="text/javascript" src="/javascripts/prototype.js"></script> - # <script type="text/javascript" src="/javascripts/effects.js"></script> + # <script type="text/javascript" src="/javascripts/prototype.js?1240300432"></script> + # <script type="text/javascript" src="/javascripts/effects.js?1240300432"></script> # ... - # <script type="text/javascript" src="/javascripts/application.js"></script> - # <script type="text/javascript" src="/javascripts/shop.js"></script> - # <script type="text/javascript" src="/javascripts/checkout.js"></script> + # <script type="text/javascript" src="/javascripts/application.js?1240300432"></script> + # <script type="text/javascript" src="/javascripts/shop.js?1240848408"></script> + # <script type="text/javascript" src="/javascripts/checkout.js?1239899358"></script> # # Note that the default javascript files will be included first. So Prototype and Scriptaculous are available to # all subsequently included files. @@ -249,23 +250,23 @@ module ActionView # # ==== Examples # javascript_include_tag :all, :cache => true # when ActionController::Base.perform_caching is false => - # <script type="text/javascript" src="/javascripts/prototype.js"></script> - # <script type="text/javascript" src="/javascripts/effects.js"></script> + # <script type="text/javascript" src="/javascripts/prototype.js?1240848408"></script> + # <script type="text/javascript" src="/javascripts/effects.js?1239899358"></script> # ... - # <script type="text/javascript" src="/javascripts/application.js"></script> - # <script type="text/javascript" src="/javascripts/shop.js"></script> - # <script type="text/javascript" src="/javascripts/checkout.js"></script> + # <script type="text/javascript" src="/javascripts/application.js?1240300432"></script> + # <script type="text/javascript" src="/javascripts/shop.js?1239622973"></script> + # <script type="text/javascript" src="/javascripts/checkout.js?1240310204"></script> # # javascript_include_tag :all, :cache => true # when ActionController::Base.perform_caching is true => - # <script type="text/javascript" src="/javascripts/all.js"></script> + # <script type="text/javascript" src="/javascripts/all.js?1240848852"></script> # # javascript_include_tag "prototype", "cart", "checkout", :cache => "shop" # when ActionController::Base.perform_caching is false => - # <script type="text/javascript" src="/javascripts/prototype.js"></script> - # <script type="text/javascript" src="/javascripts/cart.js"></script> - # <script type="text/javascript" src="/javascripts/checkout.js"></script> + # <script type="text/javascript" src="/javascripts/prototype.js?1240848408"></script> + # <script type="text/javascript" src="/javascripts/cart.js?1240848852"></script> + # <script type="text/javascript" src="/javascripts/checkout.js?1240310204"></script> # # javascript_include_tag "prototype", "cart", "checkout", :cache => "shop" # when ActionController::Base.perform_caching is true => - # <script type="text/javascript" src="/javascripts/shop.js"></script> + # <script type="text/javascript" src="/javascripts/shop.js?1240845632"></script> # # The <tt>:recursive</tt> option is also available for caching: # @@ -296,9 +297,9 @@ module ActionView # ActionView::Helpers::AssetTagHelper.register_javascript_expansion :monkey => ["head", "body", "tail"] # # javascript_include_tag :monkey # => - # <script type="text/javascript" src="/javascripts/head.js"></script> - # <script type="text/javascript" src="/javascripts/body.js"></script> - # <script type="text/javascript" src="/javascripts/tail.js"></script> + # <script type="text/javascript" src="/javascripts/head.js?1240848852"></script> + # <script type="text/javascript" src="/javascripts/body.js?1240845632"></script> + # <script type="text/javascript" src="/javascripts/tail.js?1240300432"></script> def self.register_javascript_expansion(expansions) @@javascript_expansions.merge!(expansions) end @@ -313,9 +314,9 @@ module ActionView # ActionView::Helpers::AssetTagHelper.register_stylesheet_expansion :monkey => ["head", "body", "tail"] # # stylesheet_link_tag :monkey # => - # <link href="/stylesheets/head.css" media="screen" rel="stylesheet" type="text/css" /> - # <link href="/stylesheets/body.css" media="screen" rel="stylesheet" type="text/css" /> - # <link href="/stylesheets/tail.css" media="screen" rel="stylesheet" type="text/css" /> + # <link href="/stylesheets/head.css?1240376589" media="screen" rel="stylesheet" type="text/css" /> + # <link href="/stylesheets/body.css?1245476314" media="screen" rel="stylesheet" type="text/css" /> + # <link href="/stylesheets/tail.css?1245586314" media="screen" rel="stylesheet" type="text/css" /> def self.register_stylesheet_expansion(expansions) @@stylesheet_expansions.merge!(expansions) end @@ -334,13 +335,14 @@ module ActionView # Computes the path to a stylesheet asset in the public stylesheets directory. # If the +source+ filename has no extension, <tt>.css</tt> will be appended. - # Full paths from the document root will be passed through. + # Full paths from the document root are passed through, URLs remain + # untouched. Local files get a timestamp appended as query string. # Used internally by +stylesheet_link_tag+ to build the stylesheet path. # # ==== Examples - # stylesheet_path "style" # => /stylesheets/style.css - # stylesheet_path "dir/style.css" # => /stylesheets/dir/style.css - # stylesheet_path "/dir/style.css" # => /dir/style.css + # stylesheet_path "style" # => /stylesheets/style.css?1239622973 + # stylesheet_path "dir/style.css" # => /stylesheets/dir/style.css?1245586314 + # stylesheet_path "/dir/style.css" # => /dir/style.css?1240376589 # stylesheet_path "http://www.railsapplication.com/css/style" # => http://www.railsapplication.com/css/style.css # stylesheet_path "http://www.railsapplication.com/css/style.js" # => http://www.railsapplication.com/css/style.css def stylesheet_path(source) @@ -354,30 +356,30 @@ module ActionView # # ==== Examples # stylesheet_link_tag "style" # => - # <link href="/stylesheets/style.css" media="screen" rel="stylesheet" type="text/css" /> + # <link href="/stylesheets/style.css?1239622973" media="screen" rel="stylesheet" type="text/css" /> # # stylesheet_link_tag "style.css" # => - # <link href="/stylesheets/style.css" media="screen" rel="stylesheet" type="text/css" /> + # <link href="/stylesheets/style.css?1239622973" media="screen" rel="stylesheet" type="text/css" /> # # stylesheet_link_tag "http://www.railsapplication.com/style.css" # => # <link href="http://www.railsapplication.com/style.css" media="screen" rel="stylesheet" type="text/css" /> # # stylesheet_link_tag "style", :media => "all" # => - # <link href="/stylesheets/style.css" media="all" rel="stylesheet" type="text/css" /> + # <link href="/stylesheets/style.css?1239622973" media="all" rel="stylesheet" type="text/css" /> # # stylesheet_link_tag "style", :media => "print" # => - # <link href="/stylesheets/style.css" media="print" rel="stylesheet" type="text/css" /> + # <link href="/stylesheets/style.css?1239622973" media="print" rel="stylesheet" type="text/css" /> # # stylesheet_link_tag "random.styles", "/css/stylish" # => - # <link href="/stylesheets/random.styles" media="screen" rel="stylesheet" type="text/css" /> - # <link href="/css/stylish.css" media="screen" rel="stylesheet" type="text/css" /> + # <link href="/stylesheets/random.styles?1239667843" media="screen" rel="stylesheet" type="text/css" /> + # <link href="/css/stylish.css?1239667973" media="screen" rel="stylesheet" type="text/css" /> # # You can also include all styles in the stylesheets directory using <tt>:all</tt> as the source: # # stylesheet_link_tag :all # => - # <link href="/stylesheets/style1.css" media="screen" rel="stylesheet" type="text/css" /> - # <link href="/stylesheets/styleB.css" media="screen" rel="stylesheet" type="text/css" /> - # <link href="/stylesheets/styleX2.css" media="screen" rel="stylesheet" type="text/css" /> + # <link href="/stylesheets/style1.css?1239622973" media="screen" rel="stylesheet" type="text/css" /> + # <link href="/stylesheets/styleB.css?1239622973" media="screen" rel="stylesheet" type="text/css" /> + # <link href="/stylesheets/styleX2.css?1239667843" media="screen" rel="stylesheet" type="text/css" /> # # If you want Rails to search in all the subdirectories under stylesheets, you should explicitly set <tt>:recursive</tt>: # @@ -392,20 +394,20 @@ module ActionView # # ==== Examples # stylesheet_link_tag :all, :cache => true # when ActionController::Base.perform_caching is false => - # <link href="/stylesheets/style1.css" media="screen" rel="stylesheet" type="text/css" /> - # <link href="/stylesheets/styleB.css" media="screen" rel="stylesheet" type="text/css" /> - # <link href="/stylesheets/styleX2.css" media="screen" rel="stylesheet" type="text/css" /> + # <link href="/stylesheets/style1.css?1239622973" media="screen" rel="stylesheet" type="text/css" /> + # <link href="/stylesheets/styleB.css?1239622973" media="screen" rel="stylesheet" type="text/css" /> + # <link href="/stylesheets/styleX2.css?1239667843" media="screen" rel="stylesheet" type="text/css" /> # # stylesheet_link_tag :all, :cache => true # when ActionController::Base.perform_caching is true => - # <link href="/stylesheets/all.css" media="screen" rel="stylesheet" type="text/css" /> + # <link href="/stylesheets/all.css?1245327490" media="screen" rel="stylesheet" type="text/css" /> # # stylesheet_link_tag "shop", "cart", "checkout", :cache => "payment" # when ActionController::Base.perform_caching is false => - # <link href="/stylesheets/shop.css" media="screen" rel="stylesheet" type="text/css" /> - # <link href="/stylesheets/cart.css" media="screen" rel="stylesheet" type="text/css" /> - # <link href="/stylesheets/checkout.css" media="screen" rel="stylesheet" type="text/css" /> + # <link href="/stylesheets/shop.css?1239622973" media="screen" rel="stylesheet" type="text/css" /> + # <link href="/stylesheets/cart.css?1239622973" media="screen" rel="stylesheet" type="text/css" /> + # <link href="/stylesheets/checkout.css?1239667843" media="screen" rel="stylesheet" type="text/css" /> # # stylesheet_link_tag "shop", "cart", "checkout", :cache => "payment" # when ActionController::Base.perform_caching is true => - # <link href="/stylesheets/payment.css" media="screen" rel="stylesheet" type="text/css" /> + # <link href="/stylesheets/payment.css?1245327490" media="screen" rel="stylesheet" type="text/css" /> # # The <tt>:recursive</tt> option is also available for caching: # @@ -427,14 +429,15 @@ module ActionView end # Computes the path to an image asset in the public images directory. - # Full paths from the document root will be passed through. + # Full paths from the document root are passed through, URLs remain + # untouched. Local files get a timestamp appended as query string. # Used internally by +image_tag+ to build the image path. # # ==== Examples - # image_path("edit") # => /images/edit - # image_path("edit.png") # => /images/edit.png - # image_path("icons/edit.png") # => /images/icons/edit.png - # image_path("/icons/edit.png") # => /icons/edit.png + # image_path("edit") # => /images/edit?1245327490 + # image_path("edit.png") # => /images/edit.png?1239622973 + # image_path("icons/edit.png") # => /images/icons/edit.png?1239667843 + # image_path("/icons/edit.png") # => /icons/edit.png?1240376589 # image_path("http://www.railsapplication.com/img/edit.png") # => http://www.railsapplication.com/img/edit.png def image_path(source) compute_public_path(source, 'images') @@ -459,21 +462,21 @@ module ActionView # # ==== Examples # image_tag("icon") # => - # <img src="/images/icon" alt="Icon" /> + # <img src="/images/icon?1240376589" alt="Icon" /> # image_tag("icon.png") # => # <img src="/images/icon.png" alt="Icon" /> # image_tag("icon.png", :size => "16x10", :alt => "Edit Entry") # => - # <img src="/images/icon.png" width="16" height="10" alt="Edit Entry" /> + # <img src="/images/icon.png?1239667843" width="16" height="10" alt="Edit Entry" /> # image_tag("/icons/icon.gif", :size => "16x16") # => - # <img src="/icons/icon.gif" width="16" height="16" alt="Icon" /> + # <img src="/icons/icon.gif?1239622973" width="16" height="16" alt="Icon" /> # image_tag("/icons/icon.gif", :height => '32', :width => '32') # => - # <img alt="Icon" height="32" src="/icons/icon.gif" width="32" /> + # <img alt="Icon" height="32" src="/icons/icon.gif?1245327490" width="32" /> # image_tag("/icons/icon.gif", :class => "menu_icon") # => - # <img alt="Icon" class="menu_icon" src="/icons/icon.gif" /> + # <img alt="Icon" class="menu_icon" src="/icons/icon.gif?1239667831" /> # image_tag("mouse.png", :mouseover => "/images/mouse_over.png") # => - # <img src="/images/mouse.png" onmouseover="this.src='/images/mouse_over.png'" onmouseout="this.src='/images/mouse.png'" alt="Mouse" /> + # <img src="/images/mouse.png?1245320089" onmouseover="this.src='/images/mouse_over.png'" onmouseout="this.src='/images/mouse.png'" alt="Mouse" /> # image_tag("mouse.png", :mouseover => image_path("mouse_over.png")) # => - # <img src="/images/mouse.png" onmouseover="this.src='/images/mouse_over.png'" onmouseout="this.src='/images/mouse.png'" alt="Mouse" /> + # <img src="/images/mouse.png?1245322298" onmouseover="this.src='/images/mouse_over.png'" onmouseout="this.src='/images/mouse.png'" alt="Mouse" /> def image_tag(source, options = {}) options.symbolize_keys! diff --git a/actionpack/lib/action_view/helpers/form_options_helper.rb b/actionpack/lib/action_view/helpers/form_options_helper.rb index 6adbab175f..8cb5882aab 100644 --- a/actionpack/lib/action_view/helpers/form_options_helper.rb +++ b/actionpack/lib/action_view/helpers/form_options_helper.rb @@ -167,31 +167,31 @@ module ActionView # # In addition to the <tt>:include_blank</tt> option documented above, # this method also supports a <tt>:model</tt> option, which defaults - # to TimeZone. This may be used by users to specify a different time - # zone model object. (See +time_zone_options_for_select+ for more - # information.) + # to ActiveSupport::TimeZone. This may be used by users to specify a + # different time zone model object. (See +time_zone_options_for_select+ + # for more information.) # - # You can also supply an array of TimeZone objects + # You can also supply an array of ActiveSupport::TimeZone objects # as +priority_zones+, so that they will be listed above the rest of the - # (long) list. (You can use TimeZone.us_zones as a convenience for - # obtaining a list of the US time zones, or a Regexp to select the zones + # (long) list. (You can use ActiveSupport::TimeZone.us_zones as a convenience + # for obtaining a list of the US time zones, or a Regexp to select the zones # of your choice) # # Finally, this method supports a <tt>:default</tt> option, which selects - # a default TimeZone if the object's time zone is +nil+. + # a default ActiveSupport::TimeZone if the object's time zone is +nil+. # # Examples: # time_zone_select( "user", "time_zone", nil, :include_blank => true) # # time_zone_select( "user", "time_zone", nil, :default => "Pacific Time (US & Canada)" ) # - # time_zone_select( "user", 'time_zone', TimeZone.us_zones, :default => "Pacific Time (US & Canada)") + # time_zone_select( "user", 'time_zone', ActiveSupport::TimeZone.us_zones, :default => "Pacific Time (US & Canada)") # - # time_zone_select( "user", 'time_zone', [ TimeZone['Alaska'], TimeZone['Hawaii'] ]) + # time_zone_select( "user", 'time_zone', [ ActiveSupport::TimeZone['Alaska'], ActiveSupport::TimeZone['Hawaii'] ]) # # time_zone_select( "user", 'time_zone', /Australia/) # - # time_zone_select( "user", "time_zone", TZInfo::Timezone.all.sort, :model => TZInfo::Timezone) + # time_zone_select( "user", "time_zone", ActiveSupport::Timezone.all.sort, :model => ActiveSupport::Timezone) def time_zone_select(object, method, priority_zones = nil, options = {}, html_options = {}) InstanceTag.new(object, method, self, options.delete(:object)).to_time_zone_select_tag(priority_zones, options, html_options) end @@ -393,20 +393,20 @@ module ActionView end # Returns a string of option tags for pretty much any time zone in the - # world. Supply a TimeZone name as +selected+ to have it marked as the - # selected option tag. You can also supply an array of TimeZone objects - # as +priority_zones+, so that they will be listed above the rest of the - # (long) list. (You can use TimeZone.us_zones as a convenience for - # obtaining a list of the US time zones, or a Regexp to select the zones - # of your choice) + # world. Supply a ActiveSupport::TimeZone name as +selected+ to have it + # marked as the selected option tag. You can also supply an array of + # ActiveSupport::TimeZone objects as +priority_zones+, so that they will + # be listed above the rest of the (long) list. (You can use + # ActiveSupport::TimeZone.us_zones as a convenience for obtaining a list + # of the US time zones, or a Regexp to select the zones of your choice) # # The +selected+ parameter must be either +nil+, or a string that names - # a TimeZone. + # a ActiveSupport::TimeZone. # - # By default, +model+ is the TimeZone constant (which can be obtained - # in Active Record as a value object). The only requirement is that the - # +model+ parameter be an object that responds to +all+, and returns - # an array of objects that represent time zones. + # By default, +model+ is the ActiveSupport::TimeZone constant (which can + # be obtained in Active Record as a value object). The only requirement + # is that the +model+ parameter be an object that responds to +all+, and + # returns an array of objects that represent time zones. # # NOTE: Only the option tags are returned, you have to wrap this call in # a regular HTML select tag. diff --git a/actionpack/lib/action_view/helpers/text_helper.rb b/actionpack/lib/action_view/helpers/text_helper.rb index 573b99b96e..f16e311d6c 100644 --- a/actionpack/lib/action_view/helpers/text_helper.rb +++ b/actionpack/lib/action_view/helpers/text_helper.rb @@ -431,7 +431,7 @@ module ActionView end # Returns the current cycle string after a cycle has been started. Useful - # for complex table highlighing or any other design need which requires + # for complex table highlighting or any other design need which requires # the current cycle string in more than one place. # # ==== Example @@ -539,7 +539,7 @@ module ActionView left, right = $`, $' # detect already linked URLs and URLs in the middle of a tag if left =~ /<[^>]+$/ && right =~ /^[^>]*>/ - # do not change string; URL is alreay linked + # do not change string; URL is already linked href else # don't include trailing punctuation character as part of the URL diff --git a/actionpack/lib/action_view/helpers/url_helper.rb b/actionpack/lib/action_view/helpers/url_helper.rb index 36e0a78e93..2309ff962d 100644 --- a/actionpack/lib/action_view/helpers/url_helper.rb +++ b/actionpack/lib/action_view/helpers/url_helper.rb @@ -116,7 +116,7 @@ module ActionView # * <tt>:popup => true || array of window options</tt> - This will force the # link to open in a popup window. By passing true, a default browser window # will be opened with the URL. You can also specify an array of options - # that are passed-thru to JavaScripts window.open method. + # that are passed through to JavaScripts window.open method. # * <tt>:method => symbol of HTTP verb</tt> - This modifier will dynamically # create an HTML form and immediately submit the form for processing using # the HTTP verb specified. Useful for having links perform a POST operation diff --git a/actionpack/lib/action_view/template/path.rb b/actionpack/lib/action_view/template/path.rb index 478bf96c9a..6f8d7a9c74 100644 --- a/actionpack/lib/action_view/template/path.rb +++ b/actionpack/lib/action_view/template/path.rb @@ -23,7 +23,7 @@ module ActionView private # This is what child classes implement. No defaults are needed - # because Path guarentees that the arguments are present and + # because Path guarantees that the arguments are present and # normalized. def find_templates(name, details, prefix, partial) raise NotImplementedError @@ -149,4 +149,4 @@ module ActionView end end -end
\ No newline at end of file +end diff --git a/activerecord/lib/active_record.rb b/activerecord/lib/active_record.rb index 2d98239052..4d501d319f 100644 --- a/activerecord/lib/active_record.rb +++ b/activerecord/lib/active_record.rb @@ -26,7 +26,7 @@ $:.unshift(activesupport_path) if File.directory?(activesupport_path) require 'active_support' module ActiveRecord - # TODO: Review explicit loads to see if they will automatically be handled by the initilizer. + # TODO: Review explicit loads to see if they will automatically be handled by the initializer. def self.load_all! [Base, DynamicFinderMatch, ConnectionAdapters::AbstractAdapter] end diff --git a/activerecord/lib/active_record/association_preload.rb b/activerecord/lib/active_record/association_preload.rb index 5df76bb183..41158a66bc 100644 --- a/activerecord/lib/active_record/association_preload.rb +++ b/activerecord/lib/active_record/association_preload.rb @@ -28,7 +28,7 @@ module ActiveRecord # 'books' table is useful; the joined 'authors' data is just redundant, and # processing this redundant data takes memory and CPU time. The problem # quickly becomes worse and worse as the level of eager loading increases - # (i.e. if ActiveRecord is to eager load the associations' assocations as + # (i.e. if ActiveRecord is to eager load the associations' associations as # well). # # The second strategy is to use multiple database queries, one for each @@ -58,7 +58,7 @@ module ActiveRecord # +associations+ specifies one or more associations that you want to # preload. It may be: # - a Symbol or a String which specifies a single association name. For - # example, specifiying +:books+ allows this method to preload all books + # example, specifying +:books+ allows this method to preload all books # for an Author. # - an Array which specifies multiple association names. This array # is processed recursively. For example, specifying <tt>[:avatar, :books]</tt> diff --git a/activerecord/lib/active_record/associations.rb b/activerecord/lib/active_record/associations.rb index c5e4df4950..41c0394763 100755 --- a/activerecord/lib/active_record/associations.rb +++ b/activerecord/lib/active_record/associations.rb @@ -1198,7 +1198,7 @@ module ActiveRecord private # Generates a join table name from two provided table names. - # The names in the join table namesme end up in lexicographic order. + # The names in the join table names end up in lexicographic order. # # join_table_name("members", "clubs") # => "clubs_members" # join_table_name("members", "special_clubs") # => "members_special_clubs" diff --git a/activerecord/lib/active_record/associations/association_collection.rb b/activerecord/lib/active_record/associations/association_collection.rb index 26987dde97..1e2313ab62 100644 --- a/activerecord/lib/active_record/associations/association_collection.rb +++ b/activerecord/lib/active_record/associations/association_collection.rb @@ -11,7 +11,7 @@ module ActiveRecord # ones created with +build+ are added to the target. So, the target may be # non-empty and still lack children waiting to be read from the database. # If you look directly to the database you cannot assume that's the entire - # collection because new records may have beed added to the target, etc. + # collection because new records may have been added to the target, etc. # # If you need to work on all current children, new and existing records, # +load_target+ and the +loaded+ flag are your friends. @@ -228,7 +228,7 @@ module ActiveRecord self end - # Destory all the records from this association. + # Destroy all the records from this association. # # See destroy for more info. def destroy_all diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb index ca4f4fa6b6..9014bfdfa6 100755 --- a/activerecord/lib/active_record/base.rb +++ b/activerecord/lib/active_record/base.rb @@ -833,7 +833,7 @@ module ActiveRecord #:nodoc: # Book.update_all "author = 'David'", "title LIKE '%Rails%'" # # # Update all avatars migrated more than a week ago - # Avatar.update_all ['migrated_at = ?, Time.now.utc], ['migrated_at > ?', 1.week.ago] + # Avatar.update_all ['migrated_at = ?', Time.now.utc], ['migrated_at > ?', 1.week.ago] # # # Update all books that match our conditions, but limit it to 5 ordered by date # Book.update_all "author = 'David'", "title LIKE '%Rails%'", :order => 'created_at', :limit => 5 @@ -1361,14 +1361,14 @@ module ActiveRecord #:nodoc: classes rescue # OPTIMIZE this rescue is to fix this test: ./test/cases/reflection_test.rb:56:in `test_human_name_for_column' - # Appearantly the method base_class causes some trouble. + # Apparently the method base_class causes some trouble. # It now works for sure. [self] end # Transforms attribute key names into a more humane format, such as "First name" instead of "first_name". Example: # Person.human_attribute_name("first_name") # => "First name" - # This used to be depricated in favor of humanize, but is now preferred, because it automatically uses the I18n + # This used to be deprecated in favor of humanize, but is now preferred, because it automatically uses the I18n # module now. # Specify +options+ with additional translating options. def human_attribute_name(attribute_key_name, options = {}) diff --git a/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb b/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb index 500dafdc2e..12253eac3f 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb @@ -362,7 +362,7 @@ module ActiveRecord def call(env) @app.call(env) ensure - # Don't return connection (and peform implicit rollback) if + # Don't return connection (and perform implicit rollback) if # this request is a part of integration test unless env.key?("rack.test") ActiveRecord::Base.clear_active_connections! diff --git a/activerecord/lib/active_record/fixtures.rb b/activerecord/lib/active_record/fixtures.rb index e30fcf9a4f..cc3c4ece47 100644 --- a/activerecord/lib/active_record/fixtures.rb +++ b/activerecord/lib/active_record/fixtures.rb @@ -408,7 +408,7 @@ end # subdomain: $LABEL # # Also, sometimes (like when porting older join table fixtures) you'll need -# to be able to get ahold of the identifier for a given label. ERB +# to be able to get a hold of the identifier for a given label. ERB # to the rescue: # # george_reginald: diff --git a/activerecord/lib/active_record/nested_attributes.rb b/activerecord/lib/active_record/nested_attributes.rb index c532d3dfa3..500b9b8ae0 100644 --- a/activerecord/lib/active_record/nested_attributes.rb +++ b/activerecord/lib/active_record/nested_attributes.rb @@ -284,7 +284,7 @@ module ActiveRecord # }) # # Will update the name of the Person with ID 1, build a new associated - # person with the name `John', and mark the associatied Person with ID 2 + # person with the name `John', and mark the associated Person with ID 2 # for destruction. # # Also accepts an Array of attribute hashes: diff --git a/activerecord/lib/active_record/validations.rb b/activerecord/lib/active_record/validations.rb index b6e848fa79..236c9f36de 100644 --- a/activerecord/lib/active_record/validations.rb +++ b/activerecord/lib/active_record/validations.rb @@ -73,7 +73,7 @@ module ActiveRecord # default message (e.g. <tt>activerecord.errors.messages.MESSAGE</tt>). The translated model name, # translated attribute name and the value are available for interpolation. # - # When using inheritence in your models, it will check all the inherited models too, but only if the model itself + # When using inheritance in your models, it will check all the inherited models too, but only if the model itself # hasn't been found. Say you have <tt>class Admin < User; end</tt> and you wanted the translation for the <tt>:blank</tt> # error +message+ for the <tt>title</tt> +attribute+, it looks for these translations: # diff --git a/activesupport/lib/active_support/cache/mem_cache_store.rb b/activesupport/lib/active_support/cache/mem_cache_store.rb index 4d8e1fdd67..ab8ab4eb68 100644 --- a/activesupport/lib/active_support/cache/mem_cache_store.rb +++ b/activesupport/lib/active_support/cache/mem_cache_store.rb @@ -12,7 +12,7 @@ module ActiveSupport # and MemCacheStore will load balance between all available servers. If a # server goes down, then MemCacheStore will ignore it until it goes back # online. - # - Time-based expiry support. See #write and the +:expires_in+ option. + # - Time-based expiry support. See #write and the <tt>:expires_in</tt> option. # - Per-request in memory cache for all communication with the MemCache server(s). class MemCacheStore < Store module Response # :nodoc: @@ -54,9 +54,9 @@ module ActiveSupport # Writes a value to the cache. # # Possible options: - # - +:unless_exist+ - set to true if you don't want to update the cache + # - <tt>:unless_exist</tt> - set to true if you don't want to update the cache # if the key is already set. - # - +:expires_in+ - the number of seconds that this value may stay in + # - <tt>:expires_in</tt> - the number of seconds that this value may stay in # the cache. See ActiveSupport::Cache::Store#write for an example. def write(key, value, options = nil) super diff --git a/activesupport/lib/active_support/core_ext/array/conversions.rb b/activesupport/lib/active_support/core_ext/array/conversions.rb index 5f1ce4142f..11846f265c 100644 --- a/activesupport/lib/active_support/core_ext/array/conversions.rb +++ b/activesupport/lib/active_support/core_ext/array/conversions.rb @@ -12,7 +12,7 @@ class Array default_two_words_connector = I18n.translate(:'support.array.two_words_connector', :locale => options[:locale]) default_last_word_connector = I18n.translate(:'support.array.last_word_connector', :locale => options[:locale]) - # Try to emulate to_senteces previous to 2.3 + # Try to emulate to_sentences previous to 2.3 if options.has_key?(:connector) || options.has_key?(:skip_last_comma) ::ActiveSupport::Deprecation.warn(":connector has been deprecated. Use :words_connector instead", caller) if options.has_key? :connector ::ActiveSupport::Deprecation.warn(":skip_last_comma has been deprecated. Use :last_word_connector instead", caller) if options.has_key? :skip_last_comma diff --git a/activesupport/lib/active_support/core_ext/enumerable.rb b/activesupport/lib/active_support/core_ext/enumerable.rb index 8309b617ae..434a32b29b 100644 --- a/activesupport/lib/active_support/core_ext/enumerable.rb +++ b/activesupport/lib/active_support/core_ext/enumerable.rb @@ -42,7 +42,7 @@ module Enumerable # # The latter is a shortcut for: # - # payments.inject { |sum, p| sum + p.price } + # payments.inject(0) { |sum, p| sum + p.price } # # It can also calculate the sum without the use of a block. # diff --git a/activesupport/lib/active_support/core_ext/time/marshal_with_utc_flag.rb b/activesupport/lib/active_support/core_ext/time/marshal_with_utc_flag.rb index a1c8ece1d7..9de8157eb0 100644 --- a/activesupport/lib/active_support/core_ext/time/marshal_with_utc_flag.rb +++ b/activesupport/lib/active_support/core_ext/time/marshal_with_utc_flag.rb @@ -1,5 +1,5 @@ # Pre-1.9 versions of Ruby have a bug with marshaling Time instances, where utc instances are -# unmarshaled in the local zone, instead of utc. We're layering behavior on the _dump and _load +# unmarshalled in the local zone, instead of utc. We're layering behavior on the _dump and _load # methods so that utc instances can be flagged on dump, and coerced back to utc on load. if RUBY_VERSION < '1.9' class Time diff --git a/activesupport/lib/active_support/inflector.rb b/activesupport/lib/active_support/inflector.rb index ff70d6d76e..3c9031c5f3 100644 --- a/activesupport/lib/active_support/inflector.rb +++ b/activesupport/lib/active_support/inflector.rb @@ -155,7 +155,7 @@ module ActiveSupport # Examples: # "posts".singularize # => "post" # "octopi".singularize # => "octopus" - # "sheep".singluarize # => "sheep" + # "sheep".singularize # => "sheep" # "word".singularize # => "word" # "CamelOctopi".singularize # => "CamelOctopus" def singularize(word) @@ -261,9 +261,9 @@ module ActiveSupport # <%= link_to(@person.name, person_path(@person)) %> # # => <a href="/person/1-donald-e-knuth">Donald E. Knuth</a> def parameterize(string, sep = '-') - # replace accented chars with ther ascii equivalents + # replace accented chars with their ascii equivalents parameterized_string = transliterate(string) - # Turn unwanted chars into the seperator + # Turn unwanted chars into the separator parameterized_string.gsub!(/[^a-z0-9\-_\+]+/i, sep) unless sep.blank? re_sep = Regexp.escape(sep) diff --git a/activesupport/lib/active_support/json/encoders/hash.rb b/activesupport/lib/active_support/json/encoders/hash.rb index 4771484843..28dd5b5ebc 100644 --- a/activesupport/lib/active_support/json/encoders/hash.rb +++ b/activesupport/lib/active_support/json/encoders/hash.rb @@ -8,7 +8,7 @@ class Hash # the hash keys. For example: # # { :name => "Konata Izumi", 'age' => 16, 1 => 2 }.to_json - # # => {"name": "Konata Izumi", "1": 2, "age": 16} + # # => {"name":"Konata Izumi", "1":2, "age":16} # # The keys in the JSON string are unordered due to the nature of hashes. # @@ -16,10 +16,10 @@ class Hash # attributes included, and will accept 1 or more hash keys to include/exclude. # # { :name => "Konata Izumi", 'age' => 16, 1 => 2 }.to_json(:only => [:name, 'age']) - # # => {"name": "Konata Izumi", "age": 16} + # # => {"name":"Konata Izumi", "age":16} # # { :name => "Konata Izumi", 'age' => 16, 1 => 2 }.to_json(:except => 1) - # # => {"name": "Konata Izumi", "age": 16} + # # => {"name":"Konata Izumi", "age":16} # # The +options+ also filter down to any hash values. This is particularly # useful for converting hashes containing ActiveRecord objects or any object diff --git a/activesupport/lib/active_support/xml_mini/jdom.rb b/activesupport/lib/active_support/xml_mini/jdom.rb index d795d55690..208e2a8fb6 100644 --- a/activesupport/lib/active_support/xml_mini/jdom.rb +++ b/activesupport/lib/active_support/xml_mini/jdom.rb @@ -74,7 +74,7 @@ module ActiveSupport # Merge all the texts of an element into the hash # # hash:: - # Hash to add the converted emement to. + # Hash to add the converted element to. # element:: # XML element whose texts are to me merged into the hash def merge_texts!(hash, element) diff --git a/activesupport/lib/active_support/xml_mini/nokogiri.rb b/activesupport/lib/active_support/xml_mini/nokogiri.rb index 8f9676e4f6..c71c6badab 100644 --- a/activesupport/lib/active_support/xml_mini/nokogiri.rb +++ b/activesupport/lib/active_support/xml_mini/nokogiri.rb @@ -53,7 +53,7 @@ module ActiveSupport memo[name] = child_hash end - # Recusively walk children + # Recursively walk children child.children.each { |c| callback.call(child_hash, child, c, callback) } diff --git a/activesupport/lib/active_support/xml_mini/rexml.rb b/activesupport/lib/active_support/xml_mini/rexml.rb index 5033210aae..9b3243c0e4 100644 --- a/activesupport/lib/active_support/xml_mini/rexml.rb +++ b/activesupport/lib/active_support/xml_mini/rexml.rb @@ -50,7 +50,7 @@ module ActiveSupport # Merge all the texts of an element into the hash # # hash:: - # Hash to add the converted emement to. + # Hash to add the converted element to. # element:: # XML element whose texts are to me merged into the hash def merge_texts!(hash, element) diff --git a/railties/README b/railties/README index 37ec8ea211..eef062c39a 100644 --- a/railties/README +++ b/railties/README @@ -36,17 +36,22 @@ link:files/vendor/rails/actionpack/README.html. == Web Servers -By default, Rails will try to use Mongrel if it's are installed when started with script/server, otherwise Rails will use WEBrick, the webserver that ships with Ruby. But you can also use Rails -with a variety of other web servers. +By default, Rails will try to use Mongrel if it's installed when started with script/server, otherwise +Rails will use WEBrick, the webserver that ships with Ruby. But you can also use Rails with a variety of +other web servers. Mongrel is a Ruby-based webserver with a C component (which requires compilation) that is suitable for development and deployment of Rails applications. If you have Ruby Gems installed, getting up and running with mongrel is as easy as: <tt>gem install mongrel</tt>. More info at: http://mongrel.rubyforge.org -Say other Ruby web servers like Thin and Ebb or regular web servers like Apache or LiteSpeed or -Lighttpd or IIS. The Ruby web servers are run through Rack and the latter can either be setup to use -FCGI or proxy to a pack of Mongrels/Thin/Ebb servers. +Other ruby web servers exist which can run your rails application, however script/server does +not search for them or start them. These include Thin, Ebb, and Apache with mod_rails. + +For production use, often a web/proxy server such as Apache, LiteSpeed, Lighttpd or IIS is +deployed as the front-end server, with the chosen ruby web server running in the back-end +and receiving the proxied requests via one of several protocols (HTTP, CGI, FCGI). + == Apache .htaccess example for FCGI/CGI diff --git a/railties/guides/source/action_mailer_basics.textile b/railties/guides/source/action_mailer_basics.textile index 9476635ae6..35f9722a98 100644 --- a/railties/guides/source/action_mailer_basics.textile +++ b/railties/guides/source/action_mailer_basics.textile @@ -46,7 +46,7 @@ class UserMailer < ActionMailer::Base from "My Awesome Site Notifications <notifications@example.com>" subject "Welcome to My Awesome Site" sent_on Time.now - body {:user => user, :url => "http://example.com/login"} + body( {:user => user, :url => "http://example.com/login"}) end end </ruby> @@ -137,9 +137,9 @@ Hence, if the method name starts with +deliver_+ followed by any combination of h4. Complete List of Action Mailer User-Settable Attributes -|bcc| The BCC addresses of the email| +|bcc| The BCC addresses of the email, either as a string (for a single address) or an array of strings (for multiple addresses)| |body| The body of the email. This is either a hash (in which case it specifies the variables to pass to the template when it is rendered), or a string, in which case it specifies the actual body of the message| -|cc| The CC addresses for the email| +|cc| The CC addresses for the email, either as a string (for a single address) or an array of strings (for multiple addresses)| |charset| The charset to use for the email. This defaults to the +default_charset+ specified for ActionMailer::Base.| |content_type| The content type for the email. This defaults to "text/plain" but the filename may specify it| |from| The from address of the email| @@ -165,10 +165,11 @@ class UserMailer < ActionMailer::Base from "My Awesome Site Notifications<notifications@example.com>" subject "Welcome to My Awesome Site" sent_on Time.now - body {:user => user, :url => "http://example.com/login"} + body( {:user => user, :url => "http://example.com/login"}) content_type "text/html" # use some_other_template.text.(html|plain).erb instead template "some_other_template" + end end </ruby> @@ -264,9 +265,9 @@ end h4. Sending Multipart Emails with Attachments -Once you use the +attachment+ method, ActionMailer will no longer automagically use the correct template based on the filename. You must declare which template you are using for each content type via the +part+ method. +Once you use the +attachment+ method, ActionMailer will no longer automagically use the correct template based on the filename, nor will it properly order the alternative parts. You must declare which template you are using for each content type via the +part+ method. And you must declare these templates in the proper order. -In the following example, there would be two template files, +welcome_email_html.erb+ and +welcome_email_plain.erb+ in the +app/views/user_mailer+ folder. +In the following example, there would be two template files, +welcome_email_html.erb+ and +welcome_email_plain.erb+ in the +app/views/user_mailer+ folder. The +text/plain+ part must be listed first for full compatibility with email clients. If +text/plain+ is listed after +text/html+, some clients may display both the HTML and plain text versions of the email. The text alternatives alone must be enclosed in a +multipart/alternative+ part. Do not set the entire message's +content_type+ to +multipart/alternative+ or some email clients may ignore the display of attachments such as PDF's. <ruby> class UserMailer < ActionMailer::Base @@ -274,14 +275,15 @@ class UserMailer < ActionMailer::Base recipients user.email_address subject "New account information" from "system@example.com" - content_type "multipart/alternative" - part "text/html" do |p| - p.body = render_message("welcome_email_html", :message => "<h1>HTML content</h1>") - end + part "multipart/alternative" do |pt| + pt.part "text/plain" do |p| + p.body = render_message("welcome_email_plain", :message => "text content") + end - part "text/plain" do |p| - p.body = render_message("welcome_email_plain", :message => "text content") + pt.part "text/html" do |p| + p.body = render_message("welcome_email_html", :message => "<h1>HTML content</h1>") + end end attachment :content_type => "image/jpeg", diff --git a/railties/guides/source/active_record_querying.textile b/railties/guides/source/active_record_querying.textile index b112c4f5fb..3187a82981 100644 --- a/railties/guides/source/active_record_querying.textile +++ b/railties/guides/source/active_record_querying.textile @@ -6,7 +6,6 @@ This guide covers different ways to retrieve data from the database using Active * Specify the order, retrieved attributes, grouping, and other properties of the found records * Use eager loading to reduce the number of database queries needed for data retrieval * Use dynamic finders methods -* Create named scopes to add custom finding behavior to your models * Check for the existence of particular records * Perform various calculations on Active Record models @@ -23,7 +22,6 @@ TIP: All of the following models uses +id+ as the primary key, unless specified <ruby> class Client < ActiveRecord::Base has_one :address - has_one :mailing_address has_many :orders has_and_belongs_to_many :roles end @@ -36,11 +34,6 @@ end </ruby> <ruby> -class MailingAddress < Address -end -</ruby> - -<ruby> class Order < ActiveRecord::Base belongs_to :client, :counter_cache => true end @@ -539,7 +532,7 @@ This will return single order objects for each day, but only for the last month. h4. Readonly Objects -To explicitly disallow modification/destroyal of the matching records returned by +Model.find+, you could specify the +:readonly+ option as +true+ to the find call. +To explicitly disallow modification/destruction of the matching records returned by +Model.find+, you could specify the +:readonly+ option as +true+ to the find call. Any attempt to alter or destroy the readonly records will not succeed, raising an +ActiveRecord::ReadOnlyRecord+ exception. To set this option, specify it like this: diff --git a/railties/guides/source/active_support_overview.textile b/railties/guides/source/active_support_overview.textile new file mode 100644 index 0000000000..2130d18491 --- /dev/null +++ b/railties/guides/source/active_support_overview.textile @@ -0,0 +1,132 @@ +h2. Active Support Overview + +Active Support is the Rails component responsible for providing Ruby language extensions, utilities, and other transversal stuff. It offers a richer bottom-line at the language level, targeted both at the development of Rails applications, and at the development of Rails itself. + +By referring to this guide you will learn: + +* The extensions to the Ruby core modules and classes provided by Rails. +* The rest of fundamental libraries available in Rails. + +endprologue. + +h3. Extensions to +Kernel+ + +... + +h3. Extensions to +Object+ + +... + +h3. Extensions to +Module+ + +... + +h3. Extensions to +Class+ + +... + +h3. Extensions to +NilClass+ + +... + +h3. Extensions to +TrueClass+ + +... + +h3. Extensions to +FalseClass+ + +... + +h3. Extensions to +Symbol+ + +... + +h3. Extensions to +String+ + +... + +h3. Extensions to +Numeric+ + +... + +h3. Extensions to +Integer+ + +... + +h3. Extensions to +Float+ + +... + +h3. Extensions to +BigDecimal+ + +... + +h3. Extensions to +Enumerable+ + +... + +h3. Extensions to +Array+ + +... + +h3. Extensions to +Hash+ + +... + +h3. Extensions to +Range+ + +... + +h3. Extensions to +Proc+ + +... + +h3. Extensions to +Date+ + +... + +h3. Extensions to +DateTime+ + +... + +h3. Extensions to +Time+ + +... + +h3. Extensions to +Process+ + +... + +h3. Extensions to +Pathname+ + +... + +h3. Extensions to +File+ + +... + +h3. Extensions to +Exception+ + +... + +h3. Extensions to +NameError+ + +... + +h3. Extensions to +LoadError+ + +... + +h3. Extensions to +CGI+ + +... + +h3. Extensions to +Benchmark+ + +... + +h3. Changelog + +"Lighthouse ticket":https://rails.lighthouseapp.com/projects/16213/tickets/67 + +* April 18, 2009: Initial version by "Xavier Noria":credits.html#fxn diff --git a/railties/guides/source/activerecord_validations_callbacks.textile b/railties/guides/source/activerecord_validations_callbacks.textile index 5ae4884297..218125e35f 100644 --- a/railties/guides/source/activerecord_validations_callbacks.textile +++ b/railties/guides/source/activerecord_validations_callbacks.textile @@ -530,11 +530,11 @@ class Invoice < ActiveRecord::Base end </ruby> -You can even create your own validation helpers and reuse them in several different models. Here is an example where we create a custom validation helper to validate the format of fields that represent email addresses: +You can even create your own validation helpers and reuse them in several different models. For example, an application that manages surveys may find useful to express that a certain field corresponds to a set of choices: <ruby> ActiveRecord::Base.class_eval do - def self.validates_as_radio(attr_name, n, options={}) + def self.validates_as_choice(attr_name, n, options={}) validates_inclusion_of attr_name, {:in => 1..n}.merge(options) end end @@ -544,7 +544,7 @@ Simply reopen +ActiveRecord::Base+ and define a class method like that. You'd ty <ruby> class Movie < ActiveRecord::Base - validates_as_radio :rating, 5 + validates_as_choice :rating, 5 end </ruby> diff --git a/railties/guides/source/association_basics.textile b/railties/guides/source/association_basics.textile index 03e22bd6fe..aaea83fa32 100644 --- a/railties/guides/source/association_basics.textile +++ b/railties/guides/source/association_basics.textile @@ -600,6 +600,7 @@ The +belongs_to+ association supports these options: * +:polymorphic+ * +:readonly+ * +:select+ +* +:touch+ * +:validate+ h6. +:autosave+ @@ -736,6 +737,28 @@ The +:select+ option lets you override the SQL +SELECT+ clause that is used to r TIP: If you set the +:select+ option on a +belongs_to+ association, you should also set the +foreign_key+ option to guarantee the correct results. +h6. +:touch+ + +If you set the +:touch+ option to +:true+, then the +updated_at+ or +updated_on+ timestamp on the associated object will be set to the current time whenever this object is saved or destroyed: + +<ruby> +class Order < ActiveRecord::Base + belongs_to :customer, :touch => true +end + +class Customer < ActiveRecord::Base + has_many :orders +end +</ruby> + +In this case, saving or destroying an order will update the timestamp on the associated customer. You can also specify a particular timestamp attribute to update: + +<ruby> +class Order < ActiveRecord::Base + belongs_to :customer, :touch => :orders_updated_at +end +</ruby> + h6. +:validate+ If you set the +:validate+ option to +true+, then associated objects will be validated whenever you save this object. By default, this is +false+: associated objects will not be validated when this object is saved. @@ -1196,6 +1219,17 @@ end If you use a hash-style +:conditions+ option, then record creation via this association will be automatically scoped using the hash. In this case, using +@customer.confirmed_orders.create+ or +@customer.confirmed_orders.build+ will create orders where the confirmed column has the value +true+. +If you need to evaluate conditions dynamically at runtime, you could use string interpolation in single quotes: + +<ruby> +class Customer < ActiveRecord::Base + has_many :latest_orders, :class_name => "Order", + :conditions => 'orders.created_at > #{10.hours.ago.to_s(:db).inspect}' +end +</ruby> + +Be sure to use single quotes. + h6. +:counter_sql+ Normally Rails automatically generates the proper SQL to count the association members. With the +:counter_sql+ option, you can specify a complete SQL statement to count them yourself. @@ -1775,6 +1809,7 @@ h3. Changelog "Lighthouse ticket":http://rails.lighthouseapp.com/projects/16213-rails-guides/tickets/11 +* April 19, 2009: Added +:touch+ option to +belongs_to+ associations by "Mike Gunderloy":credits.html#mgunderloy * February 1, 2009: Added +:autosave+ option "Mike Gunderloy":credits.html#mgunderloy * September 28, 2008: Corrected +has_many :through+ diagram, added polymorphic diagram, some reorganization by "Mike Gunderloy":credits.html#mgunderloy . First release version. * September 22, 2008: Added diagrams, misc. cleanup by "Mike Gunderloy":credits.html#mgunderloy (not yet approved for publication) diff --git a/railties/guides/source/caching_with_rails.textile b/railties/guides/source/caching_with_rails.textile index f1ad7b820d..ef2e6fb6eb 100644 --- a/railties/guides/source/caching_with_rails.textile +++ b/railties/guides/source/caching_with_rails.textile @@ -83,7 +83,7 @@ class ProductsController < ActionController end def create - expire_page :action => :index + expire_page :action => :list end end @@ -275,7 +275,7 @@ h4. SQL Caching Query caching is a Rails feature that caches the result set returned by each query so that if Rails encounters the same query again for that request, it -will used the cached result set as opposed to running the query against the +will use the cached result set as opposed to running the query against the database again. For example: @@ -304,19 +304,19 @@ However, it's important to note that query caches are created at the start of an that action and thus persist only for the duration of the action. If you'd like to store query results in a more persistent fashion, you can in Rails by using low level caching. -h4. Cache stores +h3. Cache Stores Rails (as of 2.1) provides different stores for the cached data created by action and fragment caches. Page caches are always stored on disk. Rails 2.1 and above provide +ActiveSupport::Cache::Store+ which can be used to -cache strings. Some cache store implementations, like MemoryStore, are able to +cache strings. Some cache store implementations, like +MemoryStore+, are able to cache arbitrary Ruby objects, but don't count on every cache store to be able to do that. The default cache stores provided with Rails include: -1) ActiveSupport::Cache::MemoryStore: A cache store implementation which stores +1) +ActiveSupport::Cache::MemoryStore+: A cache store implementation which stores everything into memory in the same process. If you're running multiple Ruby on Rails server processes (which is the case if you're using mongrel_cluster or Phusion Passenger), then this means that your Rails server process instances @@ -325,28 +325,26 @@ performs manual cache item expiry (e.g. when you‘re using generational cache keys), then using +MemoryStore+ is ok. Otherwise, consider carefully whether you should be using this cache store. -+MemoryStore+ is not only able to store strings, but also arbitrary Ruby objects. ++MemoryStore+ is not only able to store strings, but also arbitrary Ruby objects. -+MemoryStore+ is not thread-safe. Use +SynchronizedMemoryStore+ instead if you -need thread-safety. ++MemoryStore+ is not thread-safe. Use +SynchronizedMemoryStore+ instead if you need thread-safety. - <ruby> ActionController::Base.cache_store = :memory_store </ruby> -2) ActiveSupport::Cache::FileStore: Cached data is stored on the disk, this is -the default store and the default path for this store is: /tmp/cache. Works +2) +ActiveSupport::Cache::FileStore+: Cached data is stored on the disk, this is +the default store and the default path for this store is +tmp/cache+. Works well for all types of environments and allows all processes running from the -same application directory to access the cached content. If /tmp/cache does not -exist, the default store becomes MemoryStore. +same application directory to access the cached content. If +tmp/cache+ does not +exist, the default store becomes +MemoryStore+. <ruby> ActionController::Base.cache_store = :file_store, "/path/to/cache/directory" </ruby> -3) ActiveSupport::Cache::DRbStore: Cached data is stored in a separate shared +3) +ActiveSupport::Cache::DRbStore+: Cached data is stored in a separate shared DRb process that all servers communicate with. This works for all environments and only keeps one cache around for all processes, but requires that you run and manage a separate DRb process. @@ -356,25 +354,25 @@ and manage a separate DRb process. ActionController::Base.cache_store = :drb_store, "druby://localhost:9192" </ruby> -4) MemCached store: Works like DRbStore, but uses Danga's MemCache instead. -Rails uses the bundled memcached-client gem by default. This is currently the -most popular cache store for production websites. +4) +ActiveSupport::Cache::MemCacheStore+: Works like +DRbStore+, +but uses Danga's +memcached+ instead. Rails uses the bundled +memcached-client+ gem by +default. This is currently the most popular cache store for production websites. Special features: - * Clustering and load balancing. One can specify multiple memcached servers, - and MemCacheStore will load balance between all available servers. If a - server goes down, then MemCacheStore will ignore it until it goes back - online. - * Time-based expiry support. See +write+ and the +:expires_in+ option. - * Per-request in memory cache for all communication with the MemCache server(s). + +* Clustering and load balancing. One can specify multiple memcached servers, and ++MemCacheStore+ will load balance between all available servers. If a server goes +down, then +MemCacheStore+ will ignore it until it goes back online. +* Time-based expiry support. See +write+ and the +:expires_in+ option. +* Per-request in memory cache for all communication with the +memcached+ server(s). It also accepts a hash of additional options: - * +:namespace+- specifies a string that will automatically be prepended to keys when accessing the memcached store. - * +:readonly+- a boolean value that when set to true will make the store read-only, with an error raised on any attempt to write. - * +:multithread+ - a boolean value that adds thread safety to read/write operations - it is unlikely you'll need to use this option as the Rails threadsafe! method offers the same functionality. +* +:namespace+: specifies a string that will automatically be prepended to keys when accessing the memcached store. +* +:readonly+: a boolean value that when set to true will make the store read-only, with an error raised on any attempt to write. +* +:multithread+: a boolean value that adds thread safety to read/write operations - it is unlikely you'll need to use this option as the Rails threadsafe! method offers the same functionality. -The read and write methods of the MemCacheStore accept an options hash too. +The read and write methods of the +MemCacheStore+ accept an options hash too. When reading you can specify +:raw => true+ to prevent the object being marshaled (by default this is false which means the raw value in the cache is passed to +Marshal.load+ before being returned to you.) @@ -393,31 +391,29 @@ for the cached item in seconds. ActionController::Base.cache_store = :mem_cache_store, "localhost" </ruby> -5) ActiveSupport::Cache::SynchronizedMemoryStore: Like ActiveSupport::Cache::MemoryStore but thread-safe. +5) +ActiveSupport::Cache::SynchronizedMemoryStore+: Like +MemoryStore+ but thread-safe. <ruby> ActionController::Base.cache_store = :synchronized_memory_store </ruby> -6) ActiveSupport::Cache::CompressedMemCacheStore: Works just like the regular -MemCacheStore but uses GZip to decompress/compress on read/write. +6) +ActiveSupport::Cache::CompressedMemCacheStore+: Works just like the regular ++MemCacheStore+ but uses GZip to decompress/compress on read/write. <ruby> ActionController::Base.cache_store = :compressed_mem_cache_store, "localhost" </ruby> -7) Custom store: You can define your own cache store (new in Rails 2.1) +7) Custom store: You can define your own cache store (new in Rails 2.1). <ruby> ActionController::Base.cache_store = MyOwnStore.new("parameter") </ruby> -+Note: +config.cache_store+ can be used in place of -+ActionController::Base.cache_store+ in your +Rails::Initializer.run+ block in -+environment.rb+ +NOTE: +config.cache_store+ can be used in place of +ActionController::Base.cache_store+ in your +Rails::Initializer.run+ block in +environment.rb+ In addition to all of this, Rails also adds the +ActiveRecord::Base#cache_key+ method that generates a key using the class name, +id+ and +updated_at+ timestamp (if available). @@ -481,7 +477,7 @@ class ProductsController < ApplicationController def show @product = Product.find(params[:id]) - fresh_when :last_modified => @product.published_at.utc, :etag => @article + fresh_when :last_modified => @product.published_at.utc, :etag => @product end end </ruby> @@ -501,7 +497,7 @@ h3. References * "Scaling Rails Screencasts":http://railslab.newrelic.com/scaling-rails * "RailsEnvy, Rails Caching Tutorial, Part 1":http://www.railsenvy.com/2007/2/28/rails-caching-tutorial -* "RailsEnvy, Rails Caching Tutorial, Part 1":http://www.railsenvy.com/2007/3/20/ruby-on-rails-caching-tutorial-part-2 +* "RailsEnvy, Rails Caching Tutorial, Part 2":http://www.railsenvy.com/2007/3/20/ruby-on-rails-caching-tutorial-part-2 * "ActiveSupport::Cache documentation":http://api.rubyonrails.org/classes/ActiveSupport/Cache.html * "Rails 2.1 integrated caching tutorial":http://thewebfellas.com/blog/2008/6/9/rails-2-1-now-with-better-integrated-caching @@ -509,8 +505,10 @@ h3. References h3. Changelog "Lighthouse ticket":http://rails.lighthouseapp.com/projects/16213-rails-guides/tickets/10-guide-to-caching -April 1, 2009: Made a bunch of small fixes -February 22, 2009: Beefed up the section on cache_stores -December 27, 2008: Typo fixes -November 23, 2008: Incremental updates with various suggested changes and formatting cleanup -September 15, 2008: Initial version by Aditya Chadha +* May 02, 2009: Formatting cleanups +* April 26, 2009: Clean up typos in submitted patch +* April 1, 2009: Made a bunch of small fixes +* February 22, 2009: Beefed up the section on cache_stores +* December 27, 2008: Typo fixes +* November 23, 2008: Incremental updates with various suggested changes and formatting cleanup +* September 15, 2008: Initial version by Aditya Chadha diff --git a/railties/guides/source/contribute.textile b/railties/guides/source/contribute.textile index 650004bd09..5087c2f385 100644 --- a/railties/guides/source/contribute.textile +++ b/railties/guides/source/contribute.textile @@ -40,7 +40,7 @@ For each completed guide, the lead contributor will receive all of the following * $200 from Caboose Rails Documentation Project. * 1 year of GitHub Micro account worth $84. -* 1 year of RPM Basic (Production performance management) for up to 10 hosts worth 12 months x $40 per host x $10 hosts = $4800. And also, savings of $45 per host per month over list price to upgrade to advanced product. +* 1 year of RPM Basic (Production performance management) for up to 10 hosts worth 12 months x $40 per host x 10 hosts = $4800. And also, savings of $45 per host per month over list price to upgrade to advanced product. h3. Rules diff --git a/railties/guides/source/credits.erb.textile b/railties/guides/source/credits.erb.textile index b09a931fd6..512f4b0809 100644 --- a/railties/guides/source/credits.erb.textile +++ b/railties/guides/source/credits.erb.textile @@ -8,7 +8,7 @@ p. We'd like to thank the following people for their tireless contributions to t <h3 class="section">Rails Documentation Team</h3> <% author('Mike Gunderloy', 'mgunderloy') do %> - Mike Gunderloy is a consultant with "ActionRails":http://www.actionrails.com and also a member of the "Rails activism team":http://rubyonrails.org/activists . He brings 25 years of experience in a variety of languages to bear on his current work with Rails. His near-daily links and other blogging can be found at "A Fresh Cup":http://afreshcup.com and he "twitters":http://twitter.com/MikeG1 too much. + Mike Gunderloy is a consultant with "ActionRails":http://www.actionrails.com. He brings 25 years of experience in a variety of languages to bear on his current work with Rails. His near-daily links and other blogging can be found at "A Fresh Cup":http://afreshcup.com and he "twitters":http://twitter.com/MikeG1 too much. <% end %> <% author('Pratik Naik', 'lifo') do %> diff --git a/railties/guides/source/form_helpers.textile b/railties/guides/source/form_helpers.textile index 22d24b0903..8b624241ff 100644 --- a/railties/guides/source/form_helpers.textile +++ b/railties/guides/source/form_helpers.textile @@ -736,7 +736,7 @@ will create inputs like As a general rule the final input name is the concatenation of the name given to +fields_for+/+form_for+, the index value and the name of the attribute. You can also pass an +:index+ option directly to helpers such as +text_field+, but it is usually less repetitive to specify this at the form builder level rather than on individual input controls. -As a shortcut you can append [] to the name and omit the +:index+ option. This is the same as specifing +:index => address+ so +As a shortcut you can append [] to the name and omit the +:index+ option. This is the same as specifying +:index => address+ so <erb> <% fields_for 'person[address][primary][]', address do |address_form| %> diff --git a/railties/guides/source/getting_started.textile b/railties/guides/source/getting_started.textile index 7c029762a3..c15d6aa8ab 100644 --- a/railties/guides/source/getting_started.textile +++ b/railties/guides/source/getting_started.textile @@ -87,7 +87,7 @@ Action Mailer is a framework for building e-mail services. You can use Action Ma h5. Active Resource -Active Resource provides a framework for managing the connection between business objects an RESTful web services. It implements a way to map web-based resources to local objects with CRUD semantics. +Active Resource provides a framework for managing the connection between business objects and RESTful web services. It implements a way to map web-based resources to local objects with CRUD semantics. h5. Railties @@ -154,7 +154,7 @@ And if you’re using PostgreSQL for data storage, run this command: $ rails blog -d postgresql </shell> -TIP. You can see all of the switches that the Rails application builder accepts by running <tt>rails -h</tt>. +TIP: You can see all of the switches that the Rails application builder accepts by running <tt>rails -h</tt>. After you create the blog application, switch to its folder to continue work directly in that application: @@ -259,7 +259,7 @@ One of the traditional places to start with a new language is by getting some te $ script/generate controller home index </shell> -TIP. If you're on Windows, or your Ruby is set up in some non-standard fashion, you may need to explicitly pass Rails +script+ commands to Ruby: +ruby script/generate controller home index+. +TIP: If you're on Windows, or your Ruby is set up in some non-standard fashion, you may need to explicitly pass Rails +script+ commands to Ruby: +ruby script/generate controller home index+. Rails will create several files for you, including +app/views/home/index.html.erb+. This is the template that will be used to display the results of the +index+ action (method) in the +home+ controller. Open this file in your text editor and edit it to contain a single line of code: @@ -279,7 +279,7 @@ This will fire up an instance of the Mongrel web server by default (Rails can al !images/rails_welcome.png(Welcome Aboard screenshot)! -TIP. To stop the web server, hit Ctrl+C in the terminal window where it's running. In development mode, Rails does not generally require you to stop the server; changes you make in files will be automatically picked up by the server. +TIP: To stop the web server, hit Ctrl+C in the terminal window where it's running. In development mode, Rails does not generally require you to stop the server; changes you make in files will be automatically picked up by the server. The "Welcome Aboard" page is the _smoke test_ for a new Rails application: it makes sure that you have your software configured correctly enough to serve a page. To view the page you just created, navigate to +http://localhost:3000/home/index+. @@ -400,7 +400,7 @@ Now you're ready to start working with posts. To do that, navigate to +http://lo This is the result of Rails rendering the +index+ view of your posts. There aren't currently any posts in the database, but if you click the +New Post+ link you can create one. After that, you'll find that you can edit posts, look at their details, or destroy them. All of the logic and HTML to handle this was built by the single +script/generate scaffold+ command. -TIP. In development mode (which is what you're working in by default), Rails reloads your application with every browser request, so there's no need to stop and restart the web server. +TIP: In development mode (which is what you're working in by default), Rails reloads your application with every browser request, so there's no need to stop and restart the web server. Congratulations, you're riding the rails! Now it's time to see how it all works. @@ -461,7 +461,7 @@ The easiest place to start looking at functionality is with the code that lists <ruby> def index - @posts = Post.find(:all) + @posts = Post.all respond_to do |format| format.html # index.html.erb @@ -486,7 +486,7 @@ The +respond_to+ block handles both HTML and XML calls to this action. If you br <th>Content</th> </tr> -<% for post in @posts %> +<% @posts.each do |post| %> <tr> <td><%=h post.name %></td> <td><%=h post.title %></td> @@ -510,7 +510,7 @@ This view iterates over the contents of the +@posts+ array to display content an * +link_to+ builds a hyperlink to a particular destination * +edit_post_path+ is a helper that Rails provides as part of RESTful routing. You’ll see a variety of these helpers for the different actions that the controller includes. -TIP. For more details on the rendering process, see "Layouts and Rendering in Rails":layouts_and_rendering.html. +TIP: For more details on the rendering process, see "Layouts and Rendering in Rails":layouts_and_rendering.html. h4. Customizing the Layout @@ -582,7 +582,7 @@ The +new.html.erb+ view displays this empty Post to the user: <%= link_to 'Back', posts_path %> </erb> -The +form_for+ block is used to create an HTML form. Within this block, you have access to methods to build various controls on the form. For example, +f.text_field :name+ tells Rails to create a text input on the form, and to hook it up to the +name+ attribute of the instance being displayed. You can only use these methods with attributes of the model that the form is based on (in this case +name+, +title+, and +content+). Rails uses +form_for+ in preference to having your write raw HTML because the code is more succinct, and because it explicitly ties the form to a particular model instance. +The +form_for+ block is used to create an HTML form. Within this block, you have access to methods to build various controls on the form. For example, +f.text_field :name+ tells Rails to create a text input on the form, and to hook it up to the +name+ attribute of the instance being displayed. You can only use these methods with attributes of the model that the form is based on (in this case +name+, +title+, and +content+). Rails uses +form_for+ in preference to having you write raw HTML because the code is more succinct, and because it explicitly ties the form to a particular model instance. TIP: If you need to create an HTML form that displays arbitrary fields, not tied to a model, you should use the +form_tag+ method, which provides shortcuts for building forms that are not necessarily tied to a model instance. @@ -609,7 +609,7 @@ end The +create+ action instantiates a new Post object from the data supplied by the user on the form, which Rails makes available in the +params+ hash. After saving the new post, it uses +flash[:notice]+ to create an informational message for the user, and redirects to the show action for the post. If there's any problem, the +create+ action just shows the +new+ view a second time, with any error messages. -Rails provides the +flash+ hash (usually just called the Flash) so that messages can be carried over to another action, providing the user with useful information on the status of their request. In the case of +create+, the user never actually sees any page rendered during the Post creation process, because it immediately redirects to the new Post as soon Rails saves the record. The Flash carries over a message to the next action, so that when the user is redirected back to the +show+ action, they are presented with a message saying "Post was successfully created." +Rails provides the +flash+ hash (usually just called the Flash) so that messages can be carried over to another action, providing the user with useful information on the status of their request. In the case of +create+, the user never actually sees any page rendered during the Post creation process, because it immediately redirects to the new Post as soon Rails saves the record. The Flash carries over a message to the next action, so that when the user is redirected back to the +show+ action, they are presented with a message saying "Post was successfully created." h4. Showing an Individual Post @@ -785,7 +785,7 @@ As you saw earlier, the scaffold-generated views for the +new+ and +edit+ action Now, when Rails renders the +new+ or +edit+ view, it will insert the +_form+ partial at the indicated point. Note the naming convention for partials: if you refer to a partial named +form+ inside of a view, the corresponding file is +_form.html.erb+, with a leading underscore. -For more information on partials, refer to the "Layouts and Rending in Rails":layouts_and_rendering.html guide. +For more information on partials, refer to the "Layouts and Rendering in Rails":layouts_and_rendering.html#using-partials guide. h4. Using Filters to Eliminate Controller Duplication @@ -954,7 +954,7 @@ With the model in hand, you can turn your attention to creating a matching contr $ script/generate controller Comments index show new edit </shell> -This creates seven files: +This creates eight files: * +app/controllers/comments_controller.rb+ - The controller * +app/helpers/comments_helper.rb+ - A view helper file @@ -963,6 +963,7 @@ This creates seven files: * +app/views/comments/new.html.erb+ - The view for the new action * +app/views/comments/edit.html.erb+ - The view for the edit action * +test/functional/comments_controller_test.rb+ - The functional tests for the controller +* +test/unit/helpers/comments_helper_test.rb+ - The unit tests for the helper The controller will be generated with empty methods and views for each action that you specified in the call to +script/generate controller+: @@ -1031,11 +1032,7 @@ class CommentsController < ApplicationController @post = Post.find(params[:post_id]) @comment = Comment.find(params[:id]) @comment.destroy - - respond_to do |format| - format.html { redirect_to post_comments_path(@post) } - format.xml { head :ok } - end + redirect_to post_comments_path(@post) end end @@ -1198,6 +1195,22 @@ As a next step, I'll modify the +views/posts/show.html.erb+ view to show the com Note that each post has its own individual comments collection, accessible as +@post.comments+. That's a consequence of the declarative associations in the models. Path helpers such as +post_comments_path+ come from the nested route declaration in +config/routes.rb+. +h4. Deleting Associated Objects + +If you decide at some point to delete a post, you likely want to delete the comments associated with that post as well. You can do so by taking advantage of the association option +dependent+. All you need to do is modify the +post.rb+ as follows: + +<ruby> +class Post < ActiveRecord::Base + validates_presence_of :name, :title + validates_length_of :title, :minimum => 5 + has_many :comments, :dependent => :destroy + has_many :tags + + accepts_nested_attributes_for :tags, :allow_destroy => :true, + :reject_if => proc { |attrs| attrs.all? { |k, v| v.blank? } } +end +</ruby> + h3. Building a Multi-Model Form Comments and posts are edited on two separate forms - which makes sense, given the flow of this mini-application. But what if you want to edit more than one thing on a single form? Rails 2.3 offers new support for nested forms. Let's add support for giving each post multiple tags, right in the form where you create the post. First, create a new model to hold the tags: @@ -1221,7 +1234,7 @@ class Post < ActiveRecord::Base has_many :comments has_many :tags - accepts_nested_attributes_for :tags, :allow_destroy => :true , + accepts_nested_attributes_for :tags, :allow_destroy => :true, :reject_if => proc { |attrs| attrs.all? { |k, v| v.blank? } } end </ruby> @@ -1240,7 +1253,7 @@ You'll also need to modify +views/posts/_form.html.erb+ to include the tags: <%= post_form.text_field :name %> </p> <p> - <%= post_form.label :title, "title" %><br /> + <%= post_form.label :title, "Title" %><br /> <%= post_form.text_field :title %> </p> <p> @@ -1278,6 +1291,7 @@ Now that you've seen your first Rails application, you should feel free to updat * The "Ruby On Rails guides":http://guides.rubyonrails.org * The "Ruby on Rails mailing list":http://groups.google.com/group/rubyonrails-talk * The #rubyonrails channel on irc.freenode.net +* The "Rails Wiki":http://wiki.rubyonrails.org/ Rails also comes with built-in help that you can generate using the rake command-line utility: diff --git a/railties/guides/source/i18n.textile b/railties/guides/source/i18n.textile index 103ccb1c7a..bc739c5023 100644 --- a/railties/guides/source/i18n.textile +++ b/railties/guides/source/i18n.textile @@ -97,7 +97,7 @@ The *translations load path* (+I18n.load_path+) is just a Ruby Array of paths to 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. -The default +environment.rb+ files has instruction how to add locales from another directory and how to set a different default locale. Just uncomment and edit the specific lines. +The default +environment.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. <ruby> # The internationalization framework can be changed @@ -142,7 +142,7 @@ def set_locale end </ruby> -This requires you to pass the locale as a URL query parameter as in +http://example.com/books?locale=pt+. (This is, for example, Google's approach.) So +http://localhost:3000?locale=pt+ will load the Portugese localization, whereas +http://localhost:3000?locale=de+ would load the German localization, and so on. You may skip the next section and head over to the *Internationalize your application* section, if you want to try things out by manually placing the locale in the URL and reloading the page. +This requires you to pass the locale as a URL query parameter as in +http://example.com/books?locale=pt+. (This is, for example, Google's approach.) So +http://localhost:3000?locale=pt+ will load the Portuguese localization, whereas +http://localhost:3000?locale=de+ would load the German localization, and so on. You may skip the next section and head over to the *Internationalize your application* section, if you want to try things out by manually placing the locale in the URL and reloading the page. Of course, you probably don't want to manually include the locale in every URL all over your application, or want the URLs look differently, e.g. the usual +http://example.com/pt/books+ versus +http://example.com/en/books+. Let's discuss the different options you have. @@ -276,11 +276,11 @@ map.dashboard '/:locale', :controller => "dashboard" 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 +map.root+ declaration.) -IMPORTANT: This solution has currently one rather big *downside*. Due to the _default_url_options_ implementation, you have to pass the +:id+ option explicitely, 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/pages/how-to-encode-the-current-locale-in-the-url in the Rails i18n Wiki. +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/pages/how-to-encode-the-current-locale-in-the-url in the Rails i18n Wiki. h4. Setting the Locale from the Client Supplied Information -In specific cases, it would make sense to set the locale from client-supplied information, i.e. not from the URL. This information may come for example from the users' prefered language (set in their browser), can be based on the users' geographical location inferred from their IP, or users can provide it simply by choosing the locale in your application interface and saving it to their profile. This approach is more suitable for web-based applications or services, not for websites -- see the box about _sessions_, _cookies_ and RESTful architecture above. +In specific cases, it would make sense to set the locale from client-supplied information, i.e. not from the URL. This information may come for example from the users' preferred language (set in their browser), can be based on the users' geographical location inferred from their IP, or users can provide it simply by choosing the locale in your application interface and saving it to their profile. This approach is more suitable for web-based applications or services, not for websites -- see the box about _sessions_, _cookies_ and RESTful architecture above. h5. Using +Accept-Language+ @@ -305,7 +305,7 @@ Of course, in a production environment you would need much more robust code, and h5. Using GeoIP (or Similar) Database -Another way of choosing the locale from client information would be to use a database for mapping the client IP to the region, such as "GeoIP Lite Country":http://www.maxmind.com/app/geolitecountry. The mechanics of the code would be very similar to the code above -- you would need to query the database for the user's IP, and look up your prefered locale for the country/region/city returned. +Another way of choosing the locale from client information would be to use a database for mapping the client IP to the region, such as "GeoIP Lite Country":http://www.maxmind.com/app/geolitecountry. The mechanics of the code would be very similar to the code above -- you would need to query the database for the user's IP, and look up your preferred locale for the country/region/city returned. h5. User Profile @@ -315,7 +315,7 @@ h3. Internationalizing your Application OK! Now you've initialized I18n support for your Ruby on Rails application and told it which locale to use and how to preserve it between requests. With that in place, you're now ready for the really interesting stuff. -Let's _internationalize_ our application, i.e. abstract every locale-specific parts, and then _localize_ it, i.e. provide neccessary translations for these abstracts. +Let's _internationalize_ our application, i.e. abstract every locale-specific parts, and then _localize_ it, i.e. provide necessary translations for these abstracts. You most probably have something like this in one of your applications: @@ -365,12 +365,12 @@ NOTE: Rails adds a +t+ (+translate+) helper method to your views so that you do So let's add the missing translations into the dictionary files (i.e. do the "localization" part): <ruby> -# config/locale/en.yml +# config/locales/en.yml en: hello_world: Hello World hello_flash: Hello Flash -# config/locale/pirate.yml +# config/locales/pirate.yml pirate: hello_world: Ahoy World hello_flash: Ahoy Flash @@ -378,7 +378,7 @@ pirate: There you go. Because you haven't changed the default_locale, I18n will use English. Your application now shows: -!images/i18n/demo_translated_en.png(rails i18n demo translated to english)! +!images/i18n/demo_translated_en.png(rails i18n demo translated to English)! And when you change the URL to pass the pirate locale (+http://localhost:3000?locale=pirate+), you'll get: @@ -386,7 +386,7 @@ And when you change the URL to pass the pirate locale (+http://localhost:3000?lo NOTE: You need to restart the server when you add new locale files. -You may use YAML (+.yml+) or plain Ruby (+.rb+) files for storing your translations in SimpleStore. YAML is the prefered option among Rails developers. However, it has one big disadvantage. YAML is very sensitive to whitespace and special characters, so the application may not load your dictionary properly. Ruby files will crash your application on first request, so you may easily find what's wrong. (If you encounter any "weird issues" with YAML dictionaries, try putting the relevant portion of your dictionary into a Ruby file.) +You may use YAML (+.yml+) or plain Ruby (+.rb+) files for storing your translations in SimpleStore. YAML is the preferred option among Rails developers. However, it has one big disadvantage. YAML is very sensitive to whitespace and special characters, so the application may not load your dictionary properly. Ruby files will crash your application on first request, so you may easily find what's wrong. (If you encounter any "weird issues" with YAML dictionaries, try putting the relevant portion of your dictionary into a Ruby file.) h4. Adding Date/Time Formats @@ -402,7 +402,7 @@ OK! Now let's add a timestamp to the view, so we can demo the *date/time localiz And in our pirate translations file let's add a time format (it's already there in Rails' defaults for English): <ruby> -# config/locale/pirate.yml +# config/locales/pirate.yml pirate: time: formats: @@ -413,7 +413,7 @@ So that would give you: !images/i18n/demo_localized_pirate.png(rails i18n demo localized time to pirate)! -TIP: Right now you might need to add some more date/time formats in order to make the I18n backend work as expected (at least for the 'pirate' locale). Of course, there's a great chance that somebody already did all the work by *translating Rails's defaults for your locale*. See the "rails-i18n repository at Github":http://github.com/svenfuchs/rails-i18n/tree/master/rails/locale for an archive of various locale files. When you put such file(s) in +config/locale/+ directory, they will automatically be ready for use. +TIP: Right now you might need to add some more date/time formats in order to make the I18n backend work as expected (at least for the 'pirate' locale). Of course, there's a great chance that somebody already did all the work by *translating Rails's defaults for your locale*. See the "rails-i18n repository at Github":http://github.com/svenfuchs/rails-i18n/tree/master/rails/locale for an archive of various locale files. When you put such file(s) in +config/locales/+ directory, they will automatically be ready for use. h4. Localized Views @@ -425,7 +425,7 @@ h4. Organization of Locale Files When you are using the default SimpleStore shipped with the i18n library, dictionaries are stored in plain-text files on the disc. Putting translations for all parts of your application in one file per locale could be hard to manage. You can store these files in a hierarchy which makes sense to you. -For example, your +config/locale+ directory could look like this: +For example, your +config/locales+ directory could look like this: <pre> |-defaults @@ -463,7 +463,7 @@ Do check the "Rails i18n Wiki":http://rails-i18n.org/wiki for list of tools avai h3. Overview of the I18n API Features -You should have good understanding of using the i18n library now, knowing all neccessary aspects of internationalizing a basic Rails application. In the following chapters, we'll cover it's features in more depth. +You should have good understanding of using the i18n library now, knowing all necessary aspects of internationalizing a basic Rails application. In the following chapters, we'll cover it's features in more depth. Covered are features like these: @@ -686,7 +686,7 @@ en: # will translate User attribute "login" as "Handle" </ruby> -Then +User.human_name+ will return "Dude" and +User.human_attribute_name(:login)+ will return "Handle". +Then +User.human_name+ will return "Dude" and +User.human_attribute_name("login")+ will return "Handle". h5. Error Message Scopes diff --git a/railties/guides/source/layouts_and_rendering.textile b/railties/guides/source/layouts_and_rendering.textile index 809d2b2172..d7573e6314 100644 --- a/railties/guides/source/layouts_and_rendering.textile +++ b/railties/guides/source/layouts_and_rendering.textile @@ -447,7 +447,7 @@ redirect_to :back h5. Getting a Different Redirect Status Code -Rails uses HTTP status code 302 (permanent redirect) when you call +redirect_to+. If you'd like to use a different status code (perhaps 301, temporary redirect), you can do so by using the +:status+ option: +Rails uses HTTP status code 302 (temporary redirect) when you call +redirect_to+. If you'd like to use a different status code (perhaps 301, permanent redirect), you can do so by using the +:status+ option: <ruby> redirect_to photos_path, :status => 301 diff --git a/railties/guides/source/migrations.textile b/railties/guides/source/migrations.textile index 5ed94c30b7..c408e25e61 100644 --- a/railties/guides/source/migrations.textile +++ b/railties/guides/source/migrations.textile @@ -78,7 +78,7 @@ Active Record provides methods that perform common data definition tasks in a da If you need to perform tasks specific to your database (for example create a "foreign key":#active-record-and-referential-integrity constraint) then the +execute+ function allows you to execute arbitrary SQL. A migration is just a regular Ruby class so you're not limited to these functions. For example after adding a column you could write code to set the value of that column for existing records (if necessary using your models). -On databases that support transactions with statements that change the schema (such as PostgreSQL), migrations are wrapped in a transaction. If the database does not support this (for example MySQL and SQLite) then when a migration fails the parts of it that succeeded will not be rolled back. You will have to unpick the changes that were made by hand. +On databases that support transactions with statements that change the schema (such as PostgreSQL or SQLite3), migrations are wrapped in a transaction. If the database does not support this (for example MySQL) then when a migration fails the parts of it that succeeded will not be rolled back. You will have to unpick the changes that were made by hand. h4. What's in a Name @@ -508,7 +508,7 @@ The migration has its own minimal copy of the +Product+ model and no longer care h4. Dealing with Changing Models -For performance reasons information about the columns a model has is cached. For example if you add a column to a table and then try and use the corresponding model to insert a new row it may try and use the old column information. You can force Active Record to re-read the column information with the +reset_column_information+ method, for example +For performance reasons information about the columns a model has is cached. For example if you add a column to a table and then try and use the corresponding model to insert a new row it may try to use the old column information. You can force Active Record to re-read the column information with the +reset_column_information+ method, for example <ruby> class AddPartNumberToProducts < ActiveRecord::Migration diff --git a/railties/guides/source/plugins.textile b/railties/guides/source/plugins.textile index 55ecdcd3d1..a5d39c3d09 100644 --- a/railties/guides/source/plugins.textile +++ b/railties/guides/source/plugins.textile @@ -601,7 +601,7 @@ This is just a simple test to make sure the class is being loaded correctly. Af end </ruby> -Adding directories to the load path makes them appear just like files in the the main app directory - except that they are only loaded once, so you have to restart the web server to see the changes in the browser. Removing directories from the 'load_once_paths' allow those changes to picked up as soon as you save the file - without having to restart the web server. This is particularly useful as you develop the plugin. +Adding directories to the load path makes them appear just like files in the main app directory - except that they are only loaded once, so you have to restart the web server to see the changes in the browser. Removing directories from the 'load_once_paths' allow those changes to picked up as soon as you save the file - without having to restart the web server. This is particularly useful as you develop the plugin. * *vendor/plugins/yaffle/lib/app/models/woodpecker.rb:* diff --git a/railties/guides/source/rails_application_templates.textile b/railties/guides/source/rails_application_templates.textile index 49cd5bf5f5..fc178fa44b 100644 --- a/railties/guides/source/rails_application_templates.textile +++ b/railties/guides/source/rails_application_templates.textile @@ -1,18 +1,238 @@ h2. Rails Application Templates -This guide covers the Rails application templates, By referring to this guide, you will be able to: +Application templates are simple ruby files containing DSL for adding plugins/gems/initializers etc. to your freshly created Rails project or an existing Rails project. + +By referring to this guide, you will be able to: -* Use existing templates to generate a customized Rails application -* Write your own reusable Rails application templates +* Use templates to generate/customize Rails applications +* Write your own reusable application templates using the Rails template API endprologue. -h3. Introduction +h3. Usage -Application templates are simple ruby files containing DSL for adding plugins/gems/initializers etc. to your freshly created Rails project or an existing Rails project. +To apply a template, you need to provide the Rails generator with the location of the template you wish to apply, using -m option : + +<shell> +$ rails blog -m ~/template.rb +</shell> + +It's also possible to apply a template using a URL : + +<shell> +$ rails blog -m http://gist.github.com/31208.txt +</shell> + +Alternatively, you can use the rake task +rails:template+ to apply a template to an existing Rails application : + +<shell> +$ rake rails:template LOCATION=~/template.rb +</shell> + +h3. Template API + +Rails templates API is very self explanatory and easy to understand. Here's an example of a typical Rails template : + +<ruby> +# template.rb +run "rm public/index.html" +generate(:scaffold, "person name:string") +route "map.root :controller => 'people'" +rake("db:migrate") + +git :init +git :add => "." +git :commit => "-a -m 'Initial commit'" +</ruby> + +The following sections outlines the primary methods provided by the API : + +h4. gem(name, options = {}) + +Adds a +config.gem+ entry for the supplied gem to the generated application’s +config/environment.rb+. + +For example, if your application depends on the gems +bj+ and +hpricot+ : + +<ruby> +gem "bj" +gem "hpricot", :version => '0.6', :source => "http://code.whytheluckystiff.net" +</ruby> + +Please note that this will NOT install the gems for you. So you may want to run the +rake gems:install+ task too : + +<ruby> +rake "gems:install" +</ruby> + +And let Rails take care of installing the required gems if they’re not already installed. + +h4. plugin(name, options = {}) + +Installs a plugin to the generated application. + +Plugin can be installed from Git : + +<ruby> +plugin 'authentication', :git => 'git://github.com/foor/bar.git' +</ruby> + +You can even install plugins as git submodules : + +<ruby> +plugin 'authentication', :git => 'git://github.com/foor/bar.git', + :submodule => true +</ruby> + +Please note that you need to +git :init+ before you can install a plugin as a submodule. + +Or use plain old SVN : + +<ruby> +plugin 'wtfsvn', :svn => 'svn://crap.com/wtf/trunk' +</ruby> + +h4. vendor/lib/file/initializer(filename, data = nil, &block) + +Adds an initializer to the generated application’s +config/initializers+ directory. + +Lets say you like using +Object#not_nil?+ and +Object#not_blank?+ : + +<ruby> +initializer 'bloatlol.rb', <<-CODE +class Object + def not_nil? + !nil? + end + + def not_blank? + !blank? + end +end +CODE +</ruby> + +Similarly +lib()+ creates a file in the +lib/+ directory and +vendor()+ creates a file in the +vendor/+ directory. + +There is even +file()+, which accepts a relative path from +RAILS_ROOT+ and creates all the directories/file needed : + +<ruby> +file 'app/components/foo.rb', <<-CODE +class Foo +end +CODE +</ruby> + +That’ll create +app/components+ directory and put +foo.rb+ in there. + +h4. rakefile(filename, data = nil, &block) + +Creates a new rake file under +lib/tasks+ with the supplied tasks : + +<ruby> +rakefile("bootstrap.rake") do + <<-TASK + namespace :boot do + task :strap do + puts "i like boots!" + end + end + TASK +end +</ruby> + +The above creates +lib/tasks/bootstrap.rake+ with a +boot:strap+ rake task. + +h4. generate(what, args) + +Runs the supplied rails generator with given arguments. For example, I love to scaffold some whenever I’m playing with Rails : + +<ruby> +generate(:scaffold, "person", "name:string", "address:text", "age:number") +</ruby> + +h4. run(command) + +Executes an arbitrary command. Just like the backticks. Let's say you want to remove the +public/index.html+ file : + +<ruby> +run "rm public/index.html" +</ruby> + +h4. rake(command, options = {}) + +Runs the supplied rake tasks in the Rails application. Let's say you want to migrate the database : + +<ruby> +rake "db:migrate" +</ruby> + +You can also run rake tasks with a different Rails environment : + +<ruby> +rake "db:migrate", :env => 'production' +</ruby> + +Or even use sudo : + +<ruby> +rake "gems:install", :sudo => true +</ruby> + +h4. route(routing_code) + +This adds a routing entry to the +config/routes.rb+ file. In above steps, we generated a person scaffold and also removed +public/index.html+. Now to make +PeopleController#index+ as the default page for the application : + +<ruby> +route "map.root :controller => :person" +</ruby> + +h4. inside(dir) + +I have my edge rails lying at +~/commit-rails/rails+. So every time i have to manually symlink edge from my new app. But now : + +<ruby> +inside('vendor') do + run "ln -s ~/commit-rails/rails rails" +end +</ruby> + +So +inside()+ runs the command from the given directory. + +h4. ask(question) + ++ask()+ gives you a chance to get some feedback from the user and use it in your templates. Lets say you want your user to name the new shiny library you’re adding : + +<ruby> +lib_name = ask("What do you want to call the shiny library ?") +lib_name << ".rb" unless lib_name.index(".rb") + +lib lib_name, <<-CODE +class Shiny +end +CODE +</ruby> + +h4. yes?(question) or no?(question) + +These methods let you ask questions from templates and decide the flow based on the user’s answer. Lets say you want to freeze rails only if the user want to : + +<ruby> +rake("rails:freeze:gems") if yes?("Freeze rails gems ?") +no?(question) acts just the opposite. +</ruby> + +h4. git(:must => "-a love") + +Rails templates let you run any git command : + +<ruby> +git :init +git :add => "." +git :commit => "-a -m 'Initial commit'" +</ruby> h3. Changelog "Lighthouse ticket":http://rails.lighthouseapp.com/projects/16213-rails-guides/tickets/78 -* April 17, 2009: Initial version by "Pratik":credits.html#lifo +* April 29, 2009: Initial version by "Pratik":credits.html#lifo diff --git a/railties/guides/source/rails_on_rack.textile b/railties/guides/source/rails_on_rack.textile index 1164ed821d..42582b5d86 100644 --- a/railties/guides/source/rails_on_rack.textile +++ b/railties/guides/source/rails_on_rack.textile @@ -48,7 +48,7 @@ app = Rack::Builder.new { }.to_app </ruby> -Middlewares used in the code above are primarily useful only in the development envrionment. The following table explains their usage: +Middlewares used in the code above are primarily useful only in the development environment. The following table explains their usage: |_.Middleware|_.Purpose| |+Rails::Rack::LogTailer+|Appends log file output to console| diff --git a/railties/guides/source/routing.textile b/railties/guides/source/routing.textile index e9adb4b308..173b889546 100644 --- a/railties/guides/source/routing.textile +++ b/railties/guides/source/routing.textile @@ -695,7 +695,7 @@ Regular routes need not use the +connect+ method. You can use any other name her map.logout '/logout', :controller => 'sessions', :action => 'destroy' </ruby> -This will do two things. First, requests to +/logout+ will be sent to the +destroy+ method of the +Sessions+ controller. Second, Rails will maintain the +logout_path+ and +logout_url+ helpers for use within your code. +This will do two things. First, requests to +/logout+ will be sent to the +destroy+ action of the +Sessions+ controller. Second, Rails will maintain the +logout_path+ and +logout_url+ helpers for use within your code. h4. Route Requirements diff --git a/railties/guides/source/security.textile b/railties/guides/source/security.textile index 1b64cc1be7..875c4ae6e5 100644 --- a/railties/guides/source/security.textile +++ b/railties/guides/source/security.textile @@ -497,7 +497,7 @@ Depending on your web application, there may be more ways to hijack the user's a h4. CAPTCHAs --- _A CAPTCHA is a challenge-response test to determine that the response is not generated by a computer. It is often used to protect comment forms from automatic spam bots by asking the user to type the letters of a distorted image. The idea of a negative CAPTCHA is not to ask a user to proof that he is human, but reveal that a robot is a robot._ +-- _A CAPTCHA is a challenge-response test to determine that the response is not generated by a computer. It is often used to protect comment forms from automatic spam bots by asking the user to type the letters of a distorted image. The idea of a negative CAPTCHA is not for a user to prove that he is human, but reveal that a robot is a robot._ But not only spam robots (bots) are a problem, but also automatic login bots. A popular CAPTCHA API is "reCAPTCHA":http://recaptcha.net/ which displays two distorted images of words from old books. It also adds an angled line, rather than a distorted background and high levels of warping on the text as earlier CAPTCHAs did, because the latter were broken. As a bonus, using reCAPTCHA helps to digitize old books. "ReCAPTCHA":http://ambethia.com/recaptcha/ is also a Rails plug-in with the same name as the API. @@ -967,7 +967,7 @@ Transfer-Encoding: chunked Content-Type: text/html </plain> -Under certain circumstances this would present the malicious HTML to the victim. However, this seems to work with Keep-Alive connections, only (and many browsers are using one-time connections). But you can't rely on this. _(highlight)In any case this is a serious bug, and you should update your Rails to version 2.0.5 or 2.1.2 to eliminate Header Injection (and thus response splitting) risks._ +Under certain circumstances this would present the malicious HTML to the victim. However, this only seems to work with Keep-Alive connections (and many browsers are using one-time connections). But you can't rely on this. _(highlight)In any case this is a serious bug, and you should update your Rails to version 2.0.5 or 2.1.2 to eliminate Header Injection (and thus response splitting) risks._ h3. Additional Resources diff --git a/railties/guides/source/testing.textile b/railties/guides/source/testing.textile index 12fc836edf..43851e6659 100644 --- a/railties/guides/source/testing.textile +++ b/railties/guides/source/testing.textile @@ -211,7 +211,7 @@ $ rake db:migrate $ rake db:test:load </shell> -Above +rake db:migrate+ runs any pending migrations on the _developemnt_ environment and updates +db/schema.rb+. +rake db:test:load+ recreates the test database from the current db/schema.rb. On subsequent attempts it is a good to first run +db:test:prepare+ as it first checks for pending migrations and warns you appropriately. +Above +rake db:migrate+ runs any pending migrations on the _development_ environment and updates +db/schema.rb+. +rake db:test:load+ recreates the test database from the current db/schema.rb. On subsequent attempts it is a good to first run +db:test:prepare+ as it first checks for pending migrations and warns you appropriately. NOTE: +db:test:prepare+ will fail with an error if db/schema.rb doesn't exists. @@ -413,6 +413,8 @@ h4. Rails Specific Assertions Rails adds some custom assertions of its own to the +test/unit+ framework: +NOTE: +assert_valid(record)+ has been deprecated. Please use +assert(record.valid?)+ instead. + |_.Assertion |_.Purpose| |+assert_valid(record)+ |Ensures that the passed record is valid by Active Record standards and returns any error messages if it is not.| |+assert_difference(expressions, difference = 1, message = nil) {...}+ |Test numeric difference between the return value of an expression as a result of what is evaluated in the yielded block.| |