aboutsummaryrefslogtreecommitdiffstats
path: root/railties/guides/source
diff options
context:
space:
mode:
Diffstat (limited to 'railties/guides/source')
-rw-r--r--railties/guides/source/3_1_release_notes.textile109
-rw-r--r--railties/guides/source/3_2_release_notes.textile540
-rw-r--r--railties/guides/source/_license.html.erb2
-rw-r--r--railties/guides/source/_welcome.html.erb19
-rw-r--r--railties/guides/source/action_controller_overview.textile2
-rw-r--r--railties/guides/source/action_mailer_basics.textile15
-rw-r--r--railties/guides/source/action_view_overview.textile103
-rw-r--r--railties/guides/source/active_model_basics.textile2
-rw-r--r--railties/guides/source/active_record_basics.textile4
-rw-r--r--railties/guides/source/active_record_querying.textile223
-rw-r--r--railties/guides/source/active_record_validations_callbacks.textile51
-rw-r--r--railties/guides/source/active_resource_basics.textile2
-rw-r--r--railties/guides/source/active_support_core_extensions.textile258
-rw-r--r--railties/guides/source/api_documentation_guidelines.textile7
-rw-r--r--railties/guides/source/asset_pipeline.textile204
-rw-r--r--railties/guides/source/association_basics.textile13
-rw-r--r--railties/guides/source/caching_with_rails.textile36
-rw-r--r--railties/guides/source/command_line.textile42
-rw-r--r--railties/guides/source/configuring.textile43
-rw-r--r--railties/guides/source/contributing_to_ruby_on_rails.textile26
-rw-r--r--railties/guides/source/debugging_rails_applications.textile2
-rw-r--r--railties/guides/source/documents.yaml157
-rw-r--r--railties/guides/source/engines.textile12
-rw-r--r--railties/guides/source/form_helpers.textile16
-rw-r--r--railties/guides/source/generators.textile18
-rw-r--r--railties/guides/source/getting_started.textile209
-rw-r--r--railties/guides/source/i18n.textile8
-rw-r--r--railties/guides/source/index.html.erb189
-rw-r--r--railties/guides/source/initialization.textile42
-rw-r--r--railties/guides/source/kindle/KINDLE.md26
-rw-r--r--railties/guides/source/kindle/copyright.html.erb1
-rw-r--r--railties/guides/source/kindle/layout.html.erb27
-rw-r--r--railties/guides/source/kindle/rails_guides.opf.erb52
-rw-r--r--railties/guides/source/kindle/toc.html.erb24
-rw-r--r--railties/guides/source/kindle/toc.ncx.erb64
-rw-r--r--railties/guides/source/kindle/welcome.html.erb5
-rw-r--r--railties/guides/source/layout.html.erb59
-rw-r--r--railties/guides/source/layouts_and_rendering.textile67
-rw-r--r--railties/guides/source/migrations.textile563
-rw-r--r--railties/guides/source/performance_testing.textile4
-rw-r--r--railties/guides/source/plugins.textile37
-rw-r--r--railties/guides/source/rails_application_templates.textile27
-rw-r--r--railties/guides/source/rails_on_rack.textile1
-rw-r--r--railties/guides/source/routing.textile4
-rw-r--r--railties/guides/source/ruby_on_rails_guides_guidelines.textile16
-rw-r--r--railties/guides/source/security.textile2
-rw-r--r--railties/guides/source/testing.textile18
47 files changed, 2334 insertions, 1017 deletions
diff --git a/railties/guides/source/3_1_release_notes.textile b/railties/guides/source/3_1_release_notes.textile
index c4da87dc34..f88d8624ba 100644
--- a/railties/guides/source/3_1_release_notes.textile
+++ b/railties/guides/source/3_1_release_notes.textile
@@ -21,6 +21,113 @@ Rails 3.1 requires Ruby 1.8.7 or higher. Support for all of the previous Ruby ve
TIP: Note that Ruby 1.8.7 p248 and p249 have marshaling bugs that crash Rails. Ruby Enterprise Edition have these fixed since release 1.8.7-2010.02 though. On the 1.9 front, Ruby 1.9.1 is not usable because it outright segfaults, so if you want to use 1.9.x jump on 1.9.2 for smooth sailing.
+h4. What to update in your apps
+
+The following changes are meant for upgrading your application to Rails 3.1.3, the latest 3.1.x version of Rails.
+
+h5. Gemfile
+
+Make the following changes to your +Gemfile+.
+
+<ruby>
+gem 'rails', '= 3.1.3'
+gem 'mysql2'
+
+# Needed for the new asset pipeline
+group :assets do
+ gem 'sass-rails', "~> 3.1.5"
+ gem 'coffee-rails', "~> 3.1.1"
+ gem 'uglifier', ">= 1.0.3"
+end
+
+# jQuery is the default JavaScript library in Rails 3.1
+gem 'jquery-rails'
+</ruby>
+
+h5. config/application.rb
+
+* The asset pipeline requires the following additions:
+
+<ruby>
+config.assets.enabled = true
+config.assets.version = '1.0'
+</ruby>
+
+* If your application is using the "/assets" route for a resource you may want change the prefix used for assets to avoid conflicts:
+
+<ruby>
+# Defaults to '/assets'
+config.assets.prefix = '/asset-files'
+</ruby>
+
+h5. config/environments/development.rb
+
+* Remove the RJS setting <tt>config.action_view.debug_rjs = true</tt>.
+
+* Add the following, if you enable the asset pipeline.
+
+<ruby>
+# Do not compress assets
+config.assets.compress = false
+
+# Expands the lines which load the assets
+config.assets.debug = true
+</ruby>
+
+h5. config/environments/production.rb
+
+* Again, most of the changes below are for the asset pipeline. You can read more about these in the "Asset Pipeline":asset_pipeline.html guide.
+
+<ruby>
+# Compress JavaScripts and CSS
+config.assets.compress = true
+
+# Don't fallback to assets pipeline if a precompiled asset is missed
+config.assets.compile = false
+
+# Generate digests for assets URLs
+config.assets.digest = true
+
+# Defaults to Rails.root.join("public/assets")
+# config.assets.manifest = YOUR_PATH
+
+# Precompile additional assets (application.js, application.css, and all non-JS/CSS are already added)
+# config.assets.precompile += %w( search.js )
+
+
+# Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.
+# config.force_ssl = true
+
+</ruby>
+
+h5. config/environments/test.rb
+
+<ruby>
+# Configure static asset server for tests with Cache-Control for performance
+config.serve_static_assets = true
+config.static_cache_control = "public, max-age=3600"
+</ruby>
+
+h5. config/initializers/wrap_parameters.rb
+
+* Add this file with the following contents, if you wish to wrap parameters into a nested hash. This is on by default in new applications.
+
+<ruby>
+# Be sure to restart your server when you modify this file.
+# This file contains settings for ActionController::ParamsWrapper which
+# is enabled by default.
+
+# Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array.
+ActiveSupport.on_load(:action_controller) do
+ wrap_parameters :format => [:json]
+end
+
+# Disable root element in JSON by default.
+ActiveSupport.on_load(:active_record) do
+ self.include_root_in_json = false
+end
+</ruby>
+
h3. Creating a Rails 3.1 application
<shell>
@@ -46,7 +153,7 @@ $ rails new myapp --edge
If you have a local checkout of the Rails repository and want to generate an application using that, you can pass the +--dev+ flag:
<shell>
-$ ruby /path/to/rails/bin/rails new myapp --dev
+$ ruby /path/to/rails/railties/bin/rails new myapp --dev
</shell>
h3. Rails Architectural Changes
diff --git a/railties/guides/source/3_2_release_notes.textile b/railties/guides/source/3_2_release_notes.textile
new file mode 100644
index 0000000000..d669a7fdfa
--- /dev/null
+++ b/railties/guides/source/3_2_release_notes.textile
@@ -0,0 +1,540 @@
+h2. Ruby on Rails 3.2 Release Notes
+
+Highlights in Rails 3.2:
+
+* Faster Development Mode
+* New Routing Engine
+* Automatic Query Explains
+* Tagged Logging
+
+These release notes cover the major changes, but do not include each bug-fix and changes. If you want to see everything, check out the "list of commits":https://github.com/rails/rails/commits/3-2-stable in the main Rails repository on GitHub.
+
+endprologue.
+
+h3. Upgrading to Rails 3.2
+
+If you're upgrading an existing application, it's a great idea to have good test coverage before going in. You should also first upgrade to Rails 3.1 in case you haven't and make sure your application still runs as expected before attempting an update to Rails 3.2. Then take heed of the following changes:
+
+h4. Rails 3.2 requires at least Ruby 1.8.7
+
+Rails 3.2 requires Ruby 1.8.7 or higher. Support for all of the previous Ruby versions has been dropped officially and you should upgrade as early as possible. Rails 3.2 is also compatible with Ruby 1.9.2.
+
+TIP: Note that Ruby 1.8.7 p248 and p249 have marshaling bugs that crash Rails. Ruby Enterprise Edition has these fixed since the release of 1.8.7-2010.02. On the 1.9 front, Ruby 1.9.1 is not usable because it outright segfaults, so if you want to use 1.9.x, jump on to 1.9.2 or 1.9.3 for smooth sailing.
+
+h4. What to update in your apps
+
+* Update your Gemfile to depend on
+** <tt>rails = 3.2.0</tt>
+** <tt>sass-rails ~> 3.2.3</tt>
+** <tt>coffee-rails ~> 3.2.1</tt>
+** <tt>uglifier >= 1.0.3</tt>
+
+* Rails 3.2 deprecates <tt>vendor/plugins</tt> and Rails 4.0 will remove them completely. You can start replacing these plugins by extracting them as gems and adding them in your Gemfile. If you choose not to make them gems, you can move them into, say, <tt>lib/my_plugin/*</tt> and add an appropriate initializer in <tt>config/initializers/my_plugin.rb</tt>.
+
+* There are a couple of new configuration changes you'd want to add in <tt>config/environments/development.rb</tt>:
+
+<ruby>
+# Raise exception on mass assignment protection for Active Record models
+config.active_record.mass_assignment_sanitizer = :strict
+
+# Log the query plan for queries taking more than this (works
+# with SQLite, MySQL, and PostgreSQL)
+config.active_record.auto_explain_threshold_in_seconds = 0.5
+</ruby>
+
+The <tt>mass_assignment_sanitizer</tt> config also needs to be added in <tt>config/environments/test.rb</tt>:
+
+<ruby>
+# Raise exception on mass assignment protection for Active Record models
+config.active_record.mass_assignment_sanitizer = :strict
+</ruby>
+
+h3. Creating a Rails 3.2 application
+
+<shell>
+# You should have the 'rails' rubygem installed
+$ rails new myapp
+$ cd myapp
+</shell>
+
+h4. Vendoring Gems
+
+Rails now uses a +Gemfile+ in the application root to determine the gems you require for your application to start. This +Gemfile+ is processed by the "Bundler":https://github.com/carlhuda/bundler gem, which then installs all your dependencies. It can even install all the dependencies locally to your application so that it doesn't depend on the system gems.
+
+More information: "Bundler homepage":http://gembundler.com
+
+h4. Living on the Edge
+
++Bundler+ and +Gemfile+ makes freezing your Rails application easy as pie with the new dedicated +bundle+ command. If you want to bundle straight from the Git repository, you can pass the +--edge+ flag:
+
+<shell>
+$ rails new myapp --edge
+</shell>
+
+If you have a local checkout of the Rails repository and want to generate an application using that, you can pass the +--dev+ flag:
+
+<shell>
+$ ruby /path/to/rails/railties/bin/rails new myapp --dev
+</shell>
+
+h3. Major Features
+
+h4. Faster Development Mode & Routing
+
+Rails 3.2 comes with a development mode that's noticeably faster. Inspired by "Active Reload":https://github.com/paneq/active_reload, Rails reloads classes only when files actually change. The performance gains are dramatic on a larger application. Route recognition also got a bunch faster thanks to the new "Journey":https://github.com/rails/journey engine.
+
+h4. Automatic Query Explains
+
+Rails 3.2 comes with a nice feature that explains queries generated by ARel by defining an +explain+ method in <tt>ActiveRecord::Relation</tt>. For example, you can run something like <tt>puts Person.active.limit(5).explain</tt> and the query ARel produces is explained. This allows to check for the proper indexes and further optimizations.
+
+Queries that take more than half a second to run are *automatically* explained in the development mode. This threshold, of course, can be changed.
+
+h4. Tagged Logging
+
+When running a multi-user, multi-account application, it's a great help to be able to filter the log by who did what. TaggedLogging in Active Support helps in doing exactly that by stamping log lines with subdomains, request ids, and anything else to aid debugging such applications.
+
+h3. Documentation
+
+From Rails 3.2, the Rails guides are available for the Kindle and free Kindle Reading Apps for the iPad, iPhone, Mac, Android, etc.
+
+h3. Railties
+
+* Speed up development by only reloading classes if dependencies files changed. This can be turned off by setting <tt>config.reload_classes_only_on_change</tt> to false.
+
+* New applications get a flag <tt>config.active_record.auto_explain_threshold_in_seconds</tt> in the environments configuration files. With a value of <tt>0.5</tt> in <tt>development.rb</tt> and commented out in <tt>production.rb</tt>. No mention in <tt>test.rb</tt>.
+
+* Added <tt>config.exceptions_app</tt> to set the exceptions application invoked by the +ShowException+ middleware when an exception happens. Defaults to <tt>ActionDispatch::PublicExceptions.new(Rails.public_path)</tt>.
+
+* Added a <tt>DebugExceptions</tt> middleware which contains features extracted from <tt>ShowExceptions</tt> middleware.
+
+* Display mounted engines' routes in <tt>rake routes</tt>.
+
+* Allow to change the loading order of railties with <tt>config.railties_order</tt> like:
+
+<ruby>
+config.railties_order = [Blog::Engine, :main_app, :all]
+</ruby>
+
+* Scaffold returns 204 No Content for API requests without content. This makes scaffold work with jQuery out of the box.
+
+* Update <tt>Rails::Rack::Logger</tt> middleware to apply any tags set in <tt>config.log_tags</tt> to <tt>ActiveSupport::TaggedLogging</tt>. This makes it easy to tag log lines with debug information like subdomain and request id -- both very helpful in debugging multi-user production applications.
+
+* Default options to +rails new+ can be set in <tt>~/.railsrc</tt>. You can specify extra command-line arguments to be used every time 'rails new' runs in the <tt>.railsrc</tt> configuration file in your home directory.
+
+* Add an alias +d+ for +destroy+. This works for engines too.
+
+* Attributes on scaffold and model generators default to string. This allows the following: <tt>rails g scaffold Post title body:text author</tt>
+
+* Allow scaffold/model/migration generators to accept "index" and "uniq" modifiers. For example,
+
+<ruby>
+rails g scaffold Post title:string:index author:uniq price:decimal{7,2}
+</ruby>
+
+will create indexes for +title+ and +author+ with the latter being an unique index. Some types such as decimal accept custom options. In the example, +price+ will be a decimal column with precision and scale set to 7 and 2 respectively.
+
+* Turn gem has been removed from default Gemfile.
+
+* Remove old plugin generator +rails generate plugin+ in favor of +rails plugin new+ command.
+
+* Remove old <tt>config.paths.app.controller</tt> API in favor of <tt>config.paths["app/controller"]</tt>.
+
+h4(#railties_deprecations). Deprecations
+
+* +Rails::Plugin+ is deprecated and will be removed in Rails 4.0. Instead of adding plugins to +vendor/plugins+ use gems or bundler with path or git dependencies.
+
+h3. Action Mailer
+
+* Upgraded <tt>mail</tt> version to 2.4.0.
+
+* Removed the old Action Mailer API which was deprecated since Rails 3.0.
+
+h3. Action Pack
+
+h4. Action Controller
+
+* Make <tt>ActiveSupport::Benchmarkable</tt> a default module for <tt>ActionController::Base,</tt> so the <tt>#benchmark</tt> method is once again available in the controller context like it used to be.
+
+* Added +:gzip+ option to +caches_page+. The default option can be configured globally using <tt>page_cache_compression</tt>.
+
+* Rails will now use your default layout (such as "layouts/application") when you specify a layout with <tt>:only</tt> and <tt>:except</tt> condition, and those conditions fail.
+
+<ruby>
+class CarsController
+ layout 'single_car', :only => :show
+end
+</ruby>
+
+Rails will use 'layouts/single_car' when a request comes in :show action, and use 'layouts/application' (or 'layouts/cars', if exists) when a request comes in for any other actions.
+
+* form_for is changed to use "#{action}_#{as}" as the css class and id if +:as+ option is provided. Earlier versions used "#{as}_#{action}".
+
+* <tt>ActionController::ParamsWrapper</tt> on ActiveRecord models now only wrap <tt>attr_accessible</tt> attributes if they were set. If not, only the attributes returned by the class method +attribute_names+ will be wrapped. This fixes the wrapping of nested attributes by adding them to +attr_accessible+.
+
+* Log "Filter chain halted as CALLBACKNAME rendered or redirected" every time a before callback halts.
+
+* <tt>ActionDispatch::ShowExceptions</tt> is refactored. The controller is responsible for choosing to show exceptions. It's possible to override +show_detailed_exceptions?+ in controllers to specify which requests should provide debugging information on errors.
+
+* Responders now return 204 No Content for API requests without a response body (as in the new scaffold).
+
+* <tt>ActionController::TestCase</tt> cookies is refactored. Assigning cookies for test cases should now use <tt>cookies[]</tt>
+
+<ruby>
+cookies[:email] = 'user@example.com'
+get :index
+assert_equal 'user@example.com', cookies[:email]
+</ruby>
+
+To clear the cookies, use +clear+.
+
+<ruby>
+cookies.clear
+get :index
+assert_nil cookies[:email]
+</ruby>
+
+We now no longer write out HTTP_COOKIE and the cookie jar is persistent between requests so if you need to manipulate the environment for your test you need to do it before the cookie jar is created.
+
+* <tt>send_file</tt> now guesses the MIME type from the file extension if +:type+ is not provided.
+
+* MIME type entries for PDF, ZIP and other formats were added.
+
+* Allow fresh_when/stale? to take a record instead of an options hash.
+
+* Changed log level of warning for missing CSRF token from <tt>:debug</tt> to <tt>:warn</tt>.
+
+* Assets should use the request protocol by default or default to relative if no request is available.
+
+h5(#actioncontroller_deprecations). Deprecations
+
+* Deprecated implied layout lookup in controllers whose parent had a explicit layout set:
+
+<ruby>
+class ApplicationController
+ layout "application"
+end
+
+class PostsController < ApplicationController
+end
+</ruby>
+
+In the example above, Posts controller will no longer automatically look up for a posts layout. If you need this functionality you could either remove <tt>layout "application"</tt> from +ApplicationController+ or explicitly set it to +nil+ in +PostsController+.
+
+* Deprecated <tt>ActionController::UnknownAction</tt> in favour of <tt>AbstractController::ActionNotFound</tt>.
+
+* Deprecated <tt>ActionController::DoubleRenderError</tt> in favour of <tt>AbstractController::DoubleRenderError</tt>.
+
+* Deprecated <tt>method_missing</tt> in favour of +action_missing+ for missing actions.
+
+* Deprecated <tt>ActionController#rescue_action</tt>, <tt>ActionController#initialize_template_class</tt> and <tt>ActionController#assign_shortcuts</tt>.
+
+h4. Action Dispatch
+
+* Add <tt>config.action_dispatch.default_charset</tt> to configure default charset for <tt>ActionDispatch::Response</tt>.
+
+* Added <tt>ActionDispatch::RequestId</tt> middleware that'll make a unique X-Request-Id header available to the response and enables the <tt>ActionDispatch::Request#uuid</tt> method. This makes it easy to trace requests from end-to-end in the stack and to identify individual requests in mixed logs like Syslog.
+
+* The <tt>ShowExceptions</tt> middleware now accepts a exceptions application that is responsible to render an exception when the application fails. The application is invoked with a copy of the exception in +env["action_dispatch.exception"]+ and with the <tt>PATH_INFO</tt> rewritten to the status code.
+
+* Allow rescue responses to be configured through a railtie as in <tt>config.action_dispatch.rescue_responses</tt>.
+
+h5(#actiondispatch_deprecations). Deprecations
+
+* Deprecated the ability to set a default charset at the controller level, use the new <tt>config.action_dispatch.default_charset</tt> instead.
+
+h4. Action View
+
+* Add +button_tag+ support to <tt>ActionView::Helpers::FormBuilder</tt>. This support mimics the default behavior of +submit_tag+.
+
+<ruby>
+<%= form_for @post do |f| %>
+ <%= f.button %>
+<% end %>
+</ruby>
+
+* Date helpers accept a new option <tt>:use_two_digit_numbers => true</tt>, that renders select boxes for months and days with a leading zero without changing the respective values. For example, this is useful for displaying ISO 8601-style dates such as '2011-08-01'.
+
+* You can provide a namespace for your form to ensure uniqueness of id attributes on form elements. The namespace attribute will be prefixed with underscore on the generated HTML id.
+
+<ruby>
+<%= form_for(@offer, :namespace => 'namespace') do |f| %>
+ <%= f.label :version, 'Version' %>:
+ <%= f.text_field :version %>
+<% end %>
+</ruby>
+
+* Limit the number of options for +select_year+ to 1000. Pass +:max_years_allowed+ option to set your own limit.
+
+* +content_tag_for+ and +div_for+ can now take a collection of records. It will also yield the record as the first argument if you set a receiving argument in your block. So instead of having to do this:
+
+<ruby>
+@items.each do |item|
+ content_tag_for(:li, item) do
+ Title: <%= item.title %>
+ end
+end
+</ruby>
+
+You can do this:
+
+<ruby>
+content_tag_for(:li, @items) do |item|
+ Title: <%= item.title %>
+end
+</ruby>
+
+* Added +font_path+ helper method that computes the path to a font asset in <tt>public/fonts</tt>.
+
+h5(#actionview_deprecations). Deprecations
+
+* Passing formats or handlers to render :template and friends like <tt>render :template => "foo.html.erb"</tt> is deprecated. Instead, you can provide :handlers and :formats directly as an options: <tt> render :template => "foo", :formats => [:html, :js], :handlers => :erb</tt>.
+
+h4. Sprockets
+
+* Adds a configuration option <tt>config.assets.logger</tt> to control Sprockets logging. Set it to +false+ to turn off logging and to +nil+ to default to +Rails.logger+.
+
+h3. Active Record
+
+* Boolean columns with 'on' and 'ON' values are type cast to true.
+
+* When the +timestamps+ method creates the +created_at+ and +updated_at+ columns, it makes them non-nullable by default.
+
+* Implemented <tt>ActiveRecord::Relation#explain</tt>.
+
+* Implements <tt>AR::Base.silence_auto_explain</tt> which allows the user to selectively disable automatic EXPLAINs within a block.
+
+* Implements automatic EXPLAIN logging for slow queries. A new configuration parameter +config.active_record.auto_explain_threshold_in_seconds+ determines what's to be considered a slow query. Setting that to nil disables this feature. Defaults are 0.5 in development mode, and nil in test and production modes. Rails 3.2 supports this feature in SQLite, MySQL (mysql2 adapter), and PostgreSQL.
+
+* Added <tt>ActiveRecord::Base.store</tt> for declaring simple single-column key/value stores.
+
+<ruby>
+class User < ActiveRecord::Base
+ store :settings, accessors: [ :color, :homepage ]
+end
+
+u = User.new(color: 'black', homepage: '37signals.com')
+u.color # Accessor stored attribute
+u.settings[:country] = 'Denmark' # Any attribute, even if not specified with an accessor
+</ruby>
+
+* Added ability to run migrations only for a given scope, which allows to run migrations only from one engine (for example to revert changes from an engine that need to be removed).
+
+<ruby>
+rake db:migrate SCOPE=blog
+</ruby>
+
+* Migrations copied from engines are now scoped with engine's name, for example <tt>01_create_posts.blog.rb</tt>.
+
+* Implemented <tt>ActiveRecord::Relation#pluck</tt> method that returns an array of column values directly from the underlying table. This also works with serialized attributes.
+
+<ruby>
+Client.where(:active => true).pluck(:id)
+# SELECT id from clients where active = 1
+</ruby>
+
+* Generated association methods are created within a separate module to allow overriding and composition. For a class named MyModel, the module is named <tt>MyModel::GeneratedFeatureMethods</tt>. It is included into the model class immediately after the +generated_attributes_methods+ module defined in Active Model, so association methods override attribute methods of the same name.
+
+* Add <tt>ActiveRecord::Relation#uniq</tt> for generating unique queries.
+
+<ruby>
+Client.select('DISTINCT name')
+</ruby>
+
+..can be written as:
+
+<ruby>
+Client.select(:name).uniq
+</ruby>
+
+This also allows you to revert the uniqueness in a relation:
+
+<ruby>
+Client.select(:name).uniq.uniq(false)
+</ruby>
+
+* Support index sort order in SQLite, MySQL and PostgreSQL adapters.
+
+* Allow the +:class_name+ option for associations to take a symbol in addition to a string. This is to avoid confusing newbies, and to be consistent with the fact that other options like :foreign_key already allow a symbol or a string.
+
+<ruby>
+has_many :clients, :class_name => :Client # Note that the symbol need to be capitalized
+</ruby>
+
+* In development mode, <tt>db:drop</tt> also drops the test database in order to be symmetric with <tt>db:create</tt>.
+
+* Case-insensitive uniqueness validation avoids calling LOWER in MySQL when the column already uses a case-insensitive collation.
+
+* Transactional fixtures enlist all active database connections. You can test models on different connections without disabling transactional fixtures.
+
+* Add +first_or_create+, +first_or_create!+, +first_or_initialize+ methods to Active Record. This is a better approach over the old +find_or_create_by+ dynamic methods because it's clearer which arguments are used to find the record and which are used to create it.
+
+<ruby>
+User.where(:first_name => "Scarlett").first_or_create!(:last_name => "Johansson")
+</ruby>
+
+* Added a <tt>with_lock</tt> method to Active Record objects, which starts a transaction, locks the object (pessimistically) and yields to the block. The method takes one (optional) parameter and passes it to +lock!+.
+
+This makes it possible to write the following:
+
+<ruby>
+class Order < ActiveRecord::Base
+ def cancel!
+ transaction do
+ lock!
+ # ... cancelling logic
+ end
+ end
+end
+</ruby>
+
+as:
+
+<ruby>
+class Order < ActiveRecord::Base
+ def cancel!
+ with_lock do
+ # ... cancelling logic
+ end
+ end
+end
+</ruby>
+
+h4(#activerecord_deprecations). Deprecations
+
+* Automatic closure of connections in threads is deprecated. For example the following code is deprecated:
+
+<ruby>
+Thread.new { Post.find(1) }.join
+</ruby>
+
+It should be changed to close the database connection at the end of the thread:
+
+<ruby>
+Thread.new {
+ Post.find(1)
+ Post.connection.close
+}.join
+</ruby>
+
+Only people who spawn threads in their application code need to worry about this change.
+
+* The +set_table_name+, +set_inheritance_column+, +set_sequence_name+, +set_primary_key+, +set_locking_column+ methods are deprecated. Use an assignment method instead. For example, instead of +set_table_name+, use <tt>self.table_name=</tt>.
+
+<ruby>
+class Project < ActiveRecord::Base
+ self.table_name = "project"
+end
+</ruby>
+
+Or define your own <tt>self.table_name</tt> method:
+
+<ruby>
+class Post < ActiveRecord::Base
+ def self.table_name
+ "special_" + super
+ end
+end
+
+Post.table_name # => "special_posts"
+
+</ruby>
+
+h3. Active Model
+
+* Add <tt>ActiveModel::Errors#added?</tt> to check if a specific error has been added.
+
+* Add ability to define strict validations with <tt>strict => true</tt> that always raises exception when fails.
+
+* Provide mass_assignment_sanitizer as an easy API to replace the sanitizer behavior. Also support both :logger (default) and :strict sanitizer behavior.
+
+h4(#activemodel_deprecations). Deprecations
+
+* Deprecated <tt>define_attr_method</tt> in <tt>ActiveModel::AttributeMethods</tt> because this only existed to support methods like +set_table_name+ in Active Record, which are themselves being deprecated.
+
+* Deprecated <tt>Model.model_name.partial_path</tt> in favor of <tt>model.to_partial_path</tt>.
+
+h3. Active Resource
+
+* Redirect responses: 303 See Other and 307 Temporary Redirect now behave like 301 Moved Permanently and 302 Found.
+
+h3. Active Support
+
+* Added <tt>ActiveSupport:TaggedLogging</tt> that can wrap any standard +Logger+ class to provide tagging capabilities.
+
+<ruby>
+Logger = ActiveSupport::TaggedLogging.new(Logger.new(STDOUT))
+
+Logger.tagged("BCX") { Logger.info "Stuff" }
+# Logs "[BCX] Stuff"
+
+Logger.tagged("BCX", "Jason") { Logger.info "Stuff" }
+# Logs "[BCX] [Jason] Stuff"
+
+Logger.tagged("BCX") { Logger.tagged("Jason") { Logger.info "Stuff" } }
+# Logs "[BCX] [Jason] Stuff"
+</ruby>
+
+* The +beginning_of_week+ method in +Date+, +Time+ and +DateTime+ accepts an optional argument representing the day in which the week is assumed to start.
+
+* <tt>ActiveSupport::Notifications.subscribed</tt> provides subscriptions to events while a block runs.
+
+* Defined new methods <tt>Module#qualified_const_defined?</tt>, <tt>Module#qualified_const_get</tt> and <tt>Module#qualified_const_set</tt> that are analogous to the corresponding methods in the standard API, but accept qualified constant names.
+
+* Added +#deconstantize+ which complements +#demodulize+ in inflections. This removes the rightmost segment in a qualified constant name.
+
+* Added <tt>safe_constantize</tt> that constantizes a string but returns +nil+ instead of raising an exception if the constant (or part of it) does not exist.
+
+* <tt>ActiveSupport::OrderedHash</tt> is now marked as extractable when using <tt>Array#extract_options!</tt>.
+
+* Added <tt>Array#prepend</tt> as an alias for <tt>Array#unshift</tt> and <tt>Array#append</tt> as an alias for <tt>Array#<<</tt>.
+
+* The definition of a blank string for Ruby 1.9 has been extended to Unicode whitespace. Also, in Ruby 1.8 the ideographic space U+3000 is considered to be whitespace.
+
+* The inflector understands acronyms.
+
+* Added <tt>Time#all_day</tt>, <tt>Time#all_week</tt>, <tt>Time#all_quarter</tt> and <tt>Time#all_year</tt> as a way of generating ranges.
+
+<ruby>
+Event.where(:created_at => Time.now.all_week)
+Event.where(:created_at => Time.now.all_day)
+</ruby>
+
+* Added <tt>instance_accessor: false</tt> as an option to <tt>Class#cattr_accessor</tt> and friends.
+
+* <tt>ActiveSupport::OrderedHash</tt> now has different behavior for <tt>#each</tt> and <tt>#each_pair</tt> when given a block accepting its parameters with a splat.
+
+* Added <tt>ActiveSupport::Cache::NullStore</tt> for use in development and testing.
+
+* Removed <tt>ActiveSupport::SecureRandom</tt> in favor of <tt>SecureRandom</tt> from the standard library.
+
+h4(#activesupport_deprecations). Deprecations
+
+* +ActiveSupport::Base64+ is deprecated in favor of <tt>::Base64</tt>.
+
+* Deprecated <tt>ActiveSupport::Memoizable</tt> in favor of Ruby memoization pattern.
+
+* <tt>Module#synchronize</tt> is deprecated with no replacement. Please use monitor from ruby's standard library.
+
+* Deprecated <tt>ActiveSupport::MessageEncryptor#encrypt</tt> and <tt>ActiveSupport::MessageEncryptor#decrypt</tt>.
+
+* <tt>ActiveSupport::BufferedLogger#silence</tt> is deprecated. If you want to squelch logs for a certain block, change the log level for that block.
+
+* <tt>ActiveSupport::BufferedLogger#open_log</tt> is deprecated. This method should not have been public in the first place.
+
+* <tt>ActiveSupport::BufferedLogger's</tt> behavior of automatically creating the directory for your log file is deprecated. Please make sure to create the directory for your log file before instantiating.
+
+* <tt>ActiveSupport::BufferedLogger#auto_flushing</tt> is deprecated. Either set the sync level on the underlying file handle like this. Or tune your filesystem. The FS cache is now what controls flushing.
+
+<ruby>
+f = File.open('foo.log', 'w')
+f.sync = true
+ActiveSupport::BufferedLogger.new f
+</ruby>
+
+* <tt>ActiveSupport::BufferedLogger#flush</tt> is deprecated. Set sync on your filehandle, or tune your filesystem.
+
+h3. Credits
+
+See the "full list of contributors to Rails":http://contributors.rubyonrails.org/ for the many people who spent many hours making Rails, the stable and robust framework it is. Kudos to all of them.
+
+Rails 3.2 Release Notes were compiled by "Vijay Dev":https://github.com/vijaydev.
diff --git a/railties/guides/source/_license.html.erb b/railties/guides/source/_license.html.erb
new file mode 100644
index 0000000000..00b4466f50
--- /dev/null
+++ b/railties/guides/source/_license.html.erb
@@ -0,0 +1,2 @@
+<p>This work is licensed under a <a href="http://creativecommons.org/licenses/by-sa/3.0/">Creative Commons Attribution-Share Alike 3.0</a> License</p>
+<p>"Rails", "Ruby on Rails", and the Rails logo are trademarks of David Heinemeier Hansson. All rights reserved.</p>
diff --git a/railties/guides/source/_welcome.html.erb b/railties/guides/source/_welcome.html.erb
new file mode 100644
index 0000000000..9d2e9c1d68
--- /dev/null
+++ b/railties/guides/source/_welcome.html.erb
@@ -0,0 +1,19 @@
+<h2>Ruby on Rails Guides (<%= @version %>)</h2>
+
+<% if @edge %>
+<p>
+ These are <b>Edge Guides</b>, based on the current <a href="https://github.com/rails/rails/tree/<%= @version %>">master</a> branch.
+</p>
+<p>
+ If you are looking for the ones for the stable version, please check
+ <a href="http://guides.rubyonrails.org">http://guides.rubyonrails.org</a> instead.
+</p>
+<% else %>
+<p>
+ These are the new guides for Rails 3.2 based on <a href="https://github.com/rails/rails/tree/<%= @version %>"><%= @version %></a>.
+ These guides are designed to make you immediately productive with Rails, and to help you understand how all of the pieces fit together.
+</p>
+<% end %>
+<p>
+ The guides for Rails 2.3.x are available at <a href="http://guides.rubyonrails.org/v2.3.11/">http://guides.rubyonrails.org/v2.3.11/</a>.
+</p>
diff --git a/railties/guides/source/action_controller_overview.textile b/railties/guides/source/action_controller_overview.textile
index b34c223b31..bc85f07ecc 100644
--- a/railties/guides/source/action_controller_overview.textile
+++ b/railties/guides/source/action_controller_overview.textile
@@ -16,7 +16,7 @@ h3. What Does a Controller Do?
Action Controller is the C in MVC. After routing has determined which controller to use for a request, your controller is responsible for making sense of the request and producing the appropriate output. Luckily, Action Controller does most of the groundwork for you and uses smart conventions to make this as straightforward as possible.
-For most conventional RESTful applications, the controller will receive the request (this is invisible to you as the developer), fetch or save data from a model and use a view to create HTML output. If your controller needs to do things a little differently, that's not a problem, this is just the most common way for a controller to work.
+For most conventional "RESTful":http://en.wikipedia.org/wiki/Representational_state_transfer applications, the controller will receive the request (this is invisible to you as the developer), fetch or save data from a model and use a view to create HTML output. If your controller needs to do things a little differently, that's not a problem, this is just the most common way for a controller to work.
A controller can thus be thought of as a middle man between models and views. It makes the model data available to the view so it can display that data to the user, and it saves or updates data from the user to the model.
diff --git a/railties/guides/source/action_mailer_basics.textile b/railties/guides/source/action_mailer_basics.textile
index ad5b848d2c..26c95be031 100644
--- a/railties/guides/source/action_mailer_basics.textile
+++ b/railties/guides/source/action_mailer_basics.textile
@@ -362,21 +362,14 @@ When using named routes you only need to supply the +:host+:
Email clients have no web context and so paths have no base URL to form complete web addresses. Thus, when using named routes only the "_url" variant makes sense.
-It is also possible to set a default host that will be used in all mailers by setting the +:host+ option in the +ActionMailer::Base.default_url_options+ hash as follows:
+It is also possible to set a default host that will be used in all mailers by setting the <tt>:host</tt> option as a configuration option in <tt>config/application.rb</tt>:
<ruby>
-class UserMailer < ActionMailer::Base
- default_url_options[:host] = "example.com"
-
- def welcome_email(user)
- @user = user
- @url = user_url(@user)
- mail(:to => user.email,
- :subject => "Welcome to My Awesome Site")
- end
-end
+config.action_mailer.default_url_options = { :host => "example.com" }
</ruby>
+If you use this setting, you should pass the <tt>:only_path => false</tt> option when using +url_for+. This will ensure that absolute URLs are generated because the +url_for+ view helper will, by default, generate relative URLs when a <tt>:host</tt> option isn't explicitly provided.
+
h4. Sending Multipart Emails
Action Mailer will automatically send multipart emails if you have different templates for the same action. So, for our UserMailer example, if you have +welcome_email.text.erb+ and +welcome_email.html.erb+ in +app/views/user_mailer+, Action Mailer will automatically send a multipart email with the HTML and text versions setup as different parts.
diff --git a/railties/guides/source/action_view_overview.textile b/railties/guides/source/action_view_overview.textile
index 40cde6ad84..2c0b81121f 100644
--- a/railties/guides/source/action_view_overview.textile
+++ b/railties/guides/source/action_view_overview.textile
@@ -16,7 +16,7 @@ Action View and Action Controller are the two major components of Action Pack. I
Action View templates are written using embedded Ruby in tags mingled with HTML. To avoid cluttering the templates with boilerplate code, a number of helper classes provide common behavior for forms, dates, and strings. It's also easy to add new helpers to your application as it evolves.
-Note: Some features of Action View are tied to Active Record, but that doesn't mean that Action View depends on Active Record. Action View is an independent package that can be used with any sort of backend.
+NOTE. Some features of Action View are tied to Active Record, but that doesn't mean that Action View depends on Active Record. Action View is an independent package that can be used with any sort of backend.
h3. Using Action View with Rails
@@ -570,7 +570,7 @@ stylesheet_link_tag :monkey # =>
h5. auto_discovery_link_tag
-Returns a link tag that browsers and news readers can use to auto-detect an RSS or ATOM feed.
+Returns a link tag that browsers and news readers can use to auto-detect an RSS or Atom feed.
<ruby>
auto_discovery_link_tag(:rss, "http://www.example.com/feed.rss", {:title => "RSS Feed"}) # =>
@@ -585,6 +585,14 @@ Computes the path to an image asset in the +public/images+ directory. Full paths
image_path("edit.png") # => /images/edit.png
</ruby>
+h5. image_url
+
+Computes the url to an image asset in the +public/images+ directory. This will call +image_path+ internally and merge with your current host or your asset host.
+
+<ruby>
+image_url("edit.png") # => http://www.example.com/images/edit.png
+</ruby>
+
h5. image_tag
Returns an html image tag for the source. The source can be a full path or a file that exists in your +public/images+ directory.
@@ -629,6 +637,14 @@ Computes the path to a JavaScript asset in the +public/javascripts+ directory. I
javascript_path "common" # => /javascripts/common.js
</ruby>
+h5. javascript_url
+
+Computes the url to a JavaScript asset in the +public/javascripts+ directory. This will call +javascript_path+ internally and merge with your current host or your asset host.
+
+<ruby>
+javascript_url "common" # => http://www.example.com/javascripts/common.js
+</ruby>
+
h5. stylesheet_link_tag
Returns a stylesheet link tag for the sources specified as arguments. If you don't specify an extension, +.css+ will be appended automatically.
@@ -659,11 +675,19 @@ Computes the path to a stylesheet asset in the +public/stylesheets+ directory. I
stylesheet_path "application" # => /stylesheets/application.css
</ruby>
+h5. stylesheet_url
+
+Computes the url to a stylesheet asset in the +public/stylesheets+ directory. This will call +stylesheet_path+ internally and merge with your current host or your asset host.
+
+<ruby>
+stylesheet_url "application" # => http://www.example.com/stylesheets/application.css
+</ruby>
+
h4. AtomFeedHelper
h5. atom_feed
-This helper makes building an ATOM feed easy. Here's a full usage example:
+This helper makes building an Atom feed easy. Here's a full usage example:
*config/routes.rb*
@@ -1124,6 +1148,79 @@ If <tt>@post.author_id</tt> is 1, this would return:
</select>
</html>
+h5. collection_radio_buttons
+
+Returns +radio_button+ tags for the collection of existing return values of +method+ for +object+'s class.
+
+Example object structure for use with this method:
+
+<ruby>
+class Post < ActiveRecord::Base
+ belongs_to :author
+end
+
+class Author < ActiveRecord::Base
+ has_many :posts
+ def name_with_initial
+ "#{first_name.first}. #{last_name}"
+ end
+end
+</ruby>
+
+Sample usage (selecting the associated Author for an instance of Post, +@post+):
+
+<ruby>
+collection_radio_buttons(:post, :author_id, Author.all, :id, :name_with_initial)
+</ruby>
+
+If <tt>@post.author_id</tt> is 1, this would return:
+
+<html>
+<input id="post_author_id_1" name="post[author_id]" type="radio" value="1" checked="checked" />
+<label for="post_author_id_1">D. Heinemeier Hansson</label>
+<input id="post_author_id_2" name="post[author_id]" type="radio" value="2" />
+<label for="post_author_id_2">D. Thomas</label>
+<input id="post_author_id_3" name="post[author_id]" type="radio" value="3" />
+<label for="post_author_id_3">M. Clark</label>
+</html>
+
+h5. collection_check_boxes
+
+Returns +check_box+ tags for the collection of existing return values of +method+ for +object+'s class.
+
+Example object structure for use with this method:
+
+<ruby>
+class Post < ActiveRecord::Base
+ has_and_belongs_to_many :author
+end
+
+class Author < ActiveRecord::Base
+ has_and_belongs_to_many :posts
+ def name_with_initial
+ "#{first_name.first}. #{last_name}"
+ end
+end
+</ruby>
+
+Sample usage (selecting the associated Authors for an instance of Post, +@post+):
+
+<ruby>
+collection_check_boxes(:post, :author_ids, Author.all, :id, :name_with_initial)
+</ruby>
+
+If <tt>@post.author_ids</tt> is [1], this would return:
+
+<html>
+<input id="post_author_ids_1" name="post[author_ids][]" type="checkbox" value="1" checked="checked" />
+<label for="post_author_ids_1">D. Heinemeier Hansson</label>
+<input id="post_author_ids_2" name="post[author_ids][]" type="checkbox" value="2" />
+<label for="post_author_ids_2">D. Thomas</label>
+<input id="post_author_ids_3" name="post[author_ids][]" type="checkbox" value="3" />
+<label for="post_author_ids_3">M. Clark</label>
+<input name="post[author_ids][]" type="hidden" value="" />
+</html>
+
h5. country_options_for_select
Returns a string of option tags for pretty much any country in the world.
diff --git a/railties/guides/source/active_model_basics.textile b/railties/guides/source/active_model_basics.textile
index 9c8ad24cee..98b3533000 100644
--- a/railties/guides/source/active_model_basics.textile
+++ b/railties/guides/source/active_model_basics.textile
@@ -56,7 +56,7 @@ class Person
before_update :reset_me
def update
- _run_update_callbacks do
+ run_callbacks(:update) do
# This will call when we are trying to call update on object.
end
end
diff --git a/railties/guides/source/active_record_basics.textile b/railties/guides/source/active_record_basics.textile
index 66ad7b0255..487f8b70f9 100644
--- a/railties/guides/source/active_record_basics.textile
+++ b/railties/guides/source/active_record_basics.textile
@@ -101,11 +101,11 @@ h3. Overriding the Naming Conventions
What if you need to follow a different naming convention or need to use your Rails application with a legacy database? No problem, you can easily override the default conventions.
-You can use the +ActiveRecord::Base.set_table_name+ method to specify the table name that should be used:
+You can use the +ActiveRecord::Base.table_name=+ method to specify the table name that should be used:
<ruby>
class Product < ActiveRecord::Base
- set_table_name "PRODUCT"
+ self.table_name = "PRODUCT"
end
</ruby>
diff --git a/railties/guides/source/active_record_querying.textile b/railties/guides/source/active_record_querying.textile
index 2e1f89cb78..21bbc64255 100644
--- a/railties/guides/source/active_record_querying.textile
+++ b/railties/guides/source/active_record_querying.textile
@@ -8,6 +8,7 @@ This guide covers different ways to retrieve data from the database using Active
* Use dynamic finders methods
* Check for the existence of particular records
* Perform various calculations on Active Record models
+* Run EXPLAIN on relations
endprologue.
@@ -201,7 +202,7 @@ end
But this approach becomes increasingly impractical as the table size increases, since +User.all.each+ instructs Active Record to fetch _the entire table_ in a single pass, build a model object per row, and then keep the entire array of model objects in memory. Indeed, if we have a large number of records, the entire collection may exceed the amount of memory available.
-Rails provides two methods that address this problem by dividing records into memory-friendly batches for processing. The first method, +find_each+, retrieves a batch of records and then yields _each_ record to the block individually as a model. The second method, +find_in_batches+, retrieves a batch of records and then yields _the entire batch_ to the block as an array of models.
+Rails provides two methods that address this problem by dividing records into memory-friendly batches for processing. The first method, +find_each+, retrieves a batch of records and then yields _each_ record to the block individually as a model. The second method, +find_in_batches+, retrieves a batch of records and then yields _the entire batch_ to the block as an array of models.
TIP: The +find_each+ and +find_in_batches+ methods are intended for use in the batch processing of a large number of records that wouldn't fit in memory all at once. If you just need to loop over a thousand records the regular find methods are the preferred option.
@@ -403,6 +404,8 @@ Or ordering by multiple fields:
<ruby>
Client.order("orders_count ASC, created_at DESC")
+# OR
+Client.order("orders_count ASC", "created_at DESC")
</ruby>
h3. Selecting Specific Fields
@@ -435,10 +438,26 @@ ActiveModel::MissingAttributeError: missing attribute: <attribute>
Where +&lt;attribute&gt;+ is the attribute you asked for. The +id+ method will not raise the +ActiveRecord::MissingAttributeError+, so just be careful when working with associations because they need the +id+ method to function properly.
-You can also call SQL functions within the select option. For example, if you would like to only grab a single record per unique value in a certain field by using the +DISTINCT+ function you can do it like this:
+If you would like to only grab a single record per unique value in a certain field, you can use +uniq+:
<ruby>
-Client.select("DISTINCT(name)")
+Client.select(:name).uniq
+</ruby>
+
+This would generate SQL like:
+
+<sql>
+SELECT DISTINCT name FROM clients
+</sql>
+
+You can also remove the uniqueness constraint:
+
+<ruby>
+query = Client.select(:name).uniq
+# => Returns unique names
+
+query.uniq(false)
+# => Returns all names, even if there are duplicates
</ruby>
h3. Limit and Offset
@@ -589,9 +608,33 @@ SELECT * FROM clients WHERE orders_count > 10 ORDER BY clients.id DESC
This method accepts *no* arguments.
+h3. Null Relation
+
+The +none+ method returns a chainable relation with no records. Any subsequent conditions chained to the returned relation will continue generating empty relations. This is useful in scenarios where you need a chainable response to a method or a scope that could return zero results.
+
+<ruby>
+Post.none # returns an empty Relation and fires no queries.
+</ruby>
+
+<ruby>
+# The visible_posts method below is expected to return a Relation.
+@posts = current_user.visible_posts.where(:name => params[:name])
+
+def visible_posts
+ case role
+ when 'Country Manager'
+ Post.where(:country => country)
+ when 'Reviewer'
+ Post.published
+ when 'Bad User'
+ Post.none # => returning [] or nil breaks the caller code in this case
+ end
+end
+</ruby>
+
h3. Readonly Objects
-Active Record provides +readonly+ method on a relation to explicitly disallow modification or deletion of any of the returned object. Any attempt to alter or destroy a readonly record will not succeed, raising an +ActiveRecord::ReadOnlyRecord+ exception.
+Active Record provides +readonly+ method on a relation to explicitly disallow modification of any of the returned objects. Any attempt to alter a readonly record will not succeed, raising an +ActiveRecord::ReadOnlyRecord+ exception.
<ruby>
client = Client.readonly.first
@@ -631,15 +674,13 @@ c2.save # Raises an ActiveRecord::StaleObjectError
You're then responsible for dealing with the conflict by rescuing the exception and either rolling back, merging, or otherwise apply the business logic needed to resolve the conflict.
-NOTE: You must ensure that your database schema defaults the +lock_version+ column to +0+.
-
This behavior can be turned off by setting <tt>ActiveRecord::Base.lock_optimistically = false</tt>.
-To override the name of the +lock_version+ column, +ActiveRecord::Base+ provides a class method called +set_locking_column+:
+To override the name of the +lock_version+ column, +ActiveRecord::Base+ provides a class attribute called +locking_column+:
<ruby>
class Client < ActiveRecord::Base
- set_locking_column :lock_client_column
+ self.locking_column = :lock_client_column
end
</ruby>
@@ -675,6 +716,17 @@ Item.transaction do
end
</ruby>
+If you already have an instance of your model, you can start a transaction and acquire the lock in one go using the following code:
+
+<ruby>
+item = Item.first
+item.with_lock do
+ # This block is called within a transaction,
+ # item is already locked.
+ item.increment!(:views)
+end
+</ruby>
+
h3. Joining Tables
Active Record provides a finder method called +joins+ for specifying +JOIN+ clauses on the resulting SQL. There are multiple ways to use the +joins+ method.
@@ -741,7 +793,7 @@ SELECT categories.* FROM categories
INNER JOIN posts ON posts.category_id = categories.id
</sql>
-Or, in English: "return a Category object for all categories with posts". Note that you will see duplicate categories if more than one post has the same category. If you want unique categories, you can use Category.joins(:post).select("distinct(categories.id)").
+Or, in English: "return a Category object for all categories with posts". Note that you will see duplicate categories if more than one post has the same category. If you want unique categories, you can use Category.joins(:post).select("distinct(categories.id)").
h5. Joining Multiple Associations
@@ -937,7 +989,7 @@ If you're working with dates or times within scopes, due to how they are evaluat
<ruby>
class Post < ActiveRecord::Base
- scope :last_week, lambda { where("created_at < ?", Time.zone.now ) }
+ scope :created_before_now, lambda { where("created_at < ?", Time.zone.now ) }
end
</ruby>
@@ -949,21 +1001,21 @@ When a +lambda+ is used for a +scope+, it can take arguments:
<ruby>
class Post < ActiveRecord::Base
- scope :1_week_before, lambda { |time| where("created_at < ?", time)
+ scope :created_before, lambda { |time| where("created_at < ?", time) }
end
</ruby>
This may then be called using this:
<ruby>
-Post.1_week_before(Time.zone.now)
+Post.created_before(Time.zone.now)
</ruby>
However, this is just duplicating the functionality that would be provided to you by a class method.
<ruby>
class Post < ActiveRecord::Base
- def self.1_week_before(time)
+ def self.created_before(time)
where("created_at < ?", time)
end
end
@@ -972,7 +1024,7 @@ end
Using a class method is the preferred way to accept arguments for scopes. These methods will still be accessible on the association objects:
<ruby>
-category.posts.1_week_before(time)
+category.posts.created_before(time)
</ruby>
h4. Working with scopes
@@ -1129,6 +1181,30 @@ h3. +select_all+
Client.connection.select_all("SELECT * FROM clients WHERE id = '1'")
</ruby>
+h3. +pluck+
+
+<tt>pluck</tt> can be used to query a single column from the underlying table of a model. It accepts a column name as argument and returns an array of values of the specified column with the corresponding data type.
+
+<ruby>
+Client.where(:active => true).pluck(:id)
+# SELECT id FROM clients WHERE active = 1
+
+Client.uniq.pluck(:role)
+# SELECT DISTINCT role FROM clients
+</ruby>
+
++pluck+ makes it possible to replace code like
+
+<ruby>
+Client.select(:id).map { |c| c.id }
+</ruby>
+
+with
+
+<ruby>
+Client.pluck(:id)
+</ruby>
+
h3. Existence of Objects
If you simply want to check for the existence of the object there's a method called +exists?+. This method will query the database using the same query as +find+, but instead of returning an object or collection of objects it will return either +true+ or +false+.
@@ -1258,3 +1334,122 @@ Client.sum("orders_count")
</ruby>
For options, please see the parent section, "Calculations":#calculations.
+
+h3. Running EXPLAIN
+
+You can run EXPLAIN on the queries triggered by relations. For example,
+
+<ruby>
+User.where(:id => 1).joins(:posts).explain
+</ruby>
+
+may yield
+
+<plain>
+EXPLAIN for: SELECT `users`.* FROM `users` INNER JOIN `posts` ON `posts`.`user_id` = `users`.`id` WHERE `users`.`id` = 1
+<plus>----<plus>-------------<plus>-------<plus>-------<plus>---------------<plus>---------<plus>---------<plus>-------<plus>------<plus>-------------<plus>
+| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+<plus>----<plus>-------------<plus>-------<plus>-------<plus>---------------<plus>---------<plus>---------<plus>-------<plus>------<plus>-------------<plus>
+| 1 | SIMPLE | users | const | PRIMARY | PRIMARY | 4 | const | 1 | |
+| 1 | SIMPLE | posts | ALL | NULL | NULL | NULL | NULL | 1 | Using where |
+<plus>----<plus>-------------<plus>-------<plus>-------<plus>---------------<plus>---------<plus>---------<plus>-------<plus>------<plus>-------------<plus>
+2 rows in set (0.00 sec)
+</plain>
+
+under MySQL.
+
+Active Record performs a pretty printing that emulates the one of the database
+shells. So, the same query running with the PostgreSQL adapter would yield instead
+
+<plain>
+EXPLAIN for: SELECT "users".* FROM "users" INNER JOIN "posts" ON "posts"."user_id" = "users"."id" WHERE "users"."id" = 1
+ QUERY PLAN
+------------------------------------------------------------------------------
+ Nested Loop Left Join (cost=0.00..37.24 rows=8 width=0)
+ Join Filter: (posts.user_id = users.id)
+ -> Index Scan using users_pkey on users (cost=0.00..8.27 rows=1 width=4)
+ Index Cond: (id = 1)
+ -> Seq Scan on posts (cost=0.00..28.88 rows=8 width=4)
+ Filter: (posts.user_id = 1)
+(6 rows)
+</plain>
+
+Eager loading may trigger more than one query under the hood, and some queries
+may need the results of previous ones. Because of that, +explain+ actually
+executes the query, and then asks for the query plans. For example,
+
+<ruby>
+User.where(:id => 1).includes(:posts).explain
+</ruby>
+
+yields
+
+<plain>
+EXPLAIN for: SELECT `users`.* FROM `users` WHERE `users`.`id` = 1
+<plus>----<plus>-------------<plus>-------<plus>-------<plus>---------------<plus>---------<plus>---------<plus>-------<plus>------<plus>-------<plus>
+| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+<plus>----<plus>-------------<plus>-------<plus>-------<plus>---------------<plus>---------<plus>---------<plus>-------<plus>------<plus>-------<plus>
+| 1 | SIMPLE | users | const | PRIMARY | PRIMARY | 4 | const | 1 | |
+<plus>----<plus>-------------<plus>-------<plus>-------<plus>---------------<plus>---------<plus>---------<plus>-------<plus>------<plus>-------<plus>
+1 row in set (0.00 sec)
+
+EXPLAIN for: SELECT `posts`.* FROM `posts` WHERE `posts`.`user_id` IN (1)
+<plus>----<plus>-------------<plus>-------<plus>------<plus>---------------<plus>------<plus>---------<plus>------<plus>------<plus>-------------<plus>
+| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+<plus>----<plus>-------------<plus>-------<plus>------<plus>---------------<plus>------<plus>---------<plus>------<plus>------<plus>-------------<plus>
+| 1 | SIMPLE | posts | ALL | NULL | NULL | NULL | NULL | 1 | Using where |
+<plus>----<plus>-------------<plus>-------<plus>------<plus>---------------<plus>------<plus>---------<plus>------<plus>------<plus>-------------<plus>
+1 row in set (0.00 sec)
+</plain>
+
+under MySQL.
+
+h4. Automatic EXPLAIN
+
+Active Record is able to run EXPLAIN automatically on slow queries and log its
+output. This feature is controlled by the configuration parameter
+
+<ruby>
+config.active_record.auto_explain_threshold_in_seconds
+</ruby>
+
+If set to a number, any query exceeding those many seconds will have its EXPLAIN
+automatically triggered and logged. In the case of relations, the threshold is
+compared to the total time needed to fetch records. So, a relation is seen as a
+unit of work, no matter whether the implementation of eager loading involves
+several queries under the hood.
+
+A threshold of +nil+ disables automatic EXPLAINs.
+
+The default threshold in development mode is 0.5 seconds, and +nil+ in test and
+production modes.
+
+INFO. Automatic EXPLAIN gets disabled if Active Record has no logger, regardless
+of the value of the threshold.
+
+h5. Disabling Automatic EXPLAIN
+
+Automatic EXPLAIN can be selectively silenced with +ActiveRecord::Base.silence_auto_explain+:
+
+<ruby>
+ActiveRecord::Base.silence_auto_explain do
+ # no automatic EXPLAIN is triggered here
+end
+</ruby>
+
+That may be useful for queries you know are slow but fine, like a heavyweight
+report of an admin interface.
+
+As its name suggests, +silence_auto_explain+ only silences automatic EXPLAINs.
+Explicit calls to +ActiveRecord::Relation#explain+ run.
+
+h4. Interpreting EXPLAIN
+
+Interpretation of the output of EXPLAIN is beyond the scope of this guide. The
+following pointers may be helpful:
+
+* SQLite3: "EXPLAIN QUERY PLAN":http://www.sqlite.org/eqp.html
+
+* MySQL: "EXPLAIN Output Format":http://dev.mysql.com/doc/refman/5.6/en/explain-output.html
+
+* PostgreSQL: "Using EXPLAIN":http://www.postgresql.org/docs/current/static/using-explain.html
diff --git a/railties/guides/source/active_record_validations_callbacks.textile b/railties/guides/source/active_record_validations_callbacks.textile
index 665e7f9ccc..15d24f9ac1 100644
--- a/railties/guides/source/active_record_validations_callbacks.textile
+++ b/railties/guides/source/active_record_validations_callbacks.textile
@@ -614,7 +614,7 @@ As shown in the example, you can also combine standard validations with your own
h4. Custom Methods
-You can also create methods that verify the state of your models and add messages to the +errors+ collection when they are invalid. You must then register these methods by using one or more of the +validate+, +validate_on_create+ or +validate_on_update+ class methods, passing in the symbols for the validation methods' names.
+You can also create methods that verify the state of your models and add messages to the +errors+ collection when they are invalid. You must then register these methods by using the +validate+ class method, passing in the symbols for the validation methods' names.
You can pass more than one symbol for each class method and the respective validations will be run in the same order as they were registered.
@@ -637,12 +637,24 @@ class Invoice < ActiveRecord::Base
end
</ruby>
+By default such validations will run every time you call +valid?+. It is also possible to control when to run these custom validations by giving an +:on+ option to the +validate+ method, with either: +:create+ or +:update+.
+
+<ruby>
+class Invoice < ActiveRecord::Base
+ validate :active_customer, :on => :create
+
+ def active_customer
+ errors.add(:customer_id, "is not active") unless customer.active?
+ end
+end
+</ruby>
+
You can even create your own validation helpers and reuse them in several different models. For example, an application that manages surveys may find it useful to express that a certain field corresponds to a set of choices:
<ruby>
ActiveRecord::Base.class_eval do
def self.validates_as_choice(attr_name, n, options={})
- validates attr_name, :inclusion => { {:in => 1..n}.merge(options) }
+ validates attr_name, :inclusion => { { :in => 1..n }.merge!(options) }
end
end
</ruby>
@@ -659,7 +671,7 @@ h3. Working with Validation Errors
In addition to the +valid?+ and +invalid?+ methods covered earlier, Rails provides a number of methods for working with the +errors+ collection and inquiring about the validity of objects.
-The following is a list of the most commonly used methods. Please refer to the +ActiveRecord::Errors+ documentation for a list of all the available methods.
+The following is a list of the most commonly used methods. Please refer to the +ActiveModel::Errors+ documentation for a list of all the available methods.
h4(#working_with_validation_errors-errors). +errors+
@@ -796,17 +808,9 @@ person.errors.size # => 0
h3. Displaying Validation Errors in the View
-Rails maintains an official plugin, DynamicForm, that provides helpers to display the error messages of your models in your view templates. You can install it as a plugin or as a Gem.
+"DynamicForm":https://github.com/joelmoss/dynamic_form provides helpers to display the error messages of your models in your view templates.
-h4. Installing as a plugin
-
-<shell>
-$ rails plugin install git://github.com/joelmoss/dynamic_form.git
-</shell>
-
-h4. Installing as a Gem
-
-Add this line in your Gemfile:
+You can install it as a gem by adding this line to your Gemfile:
<ruby>
gem "dynamic_form"
@@ -897,13 +901,8 @@ Below is a simple example where we change the Rails behavior to always display t
<ruby>
ActionView::Base.field_error_proc = Proc.new do |html_tag, instance|
- if instance.error_message.kind_of?(Array)
- %(#{html_tag}<span class="validation-error">&nbsp;
- #{instance.error_message.join(',')}</span>).html_safe
- else
- %(#{html_tag}<span class="validation-error">&nbsp;
- #{instance.error_message}</span>).html_safe
- end
+ errors = Array(instance.error_message).join(',')
+ %(#{html_tag}<span class="validation-error">&nbsp;#{errors}</span>).html_safe
end
</ruby>
@@ -957,6 +956,7 @@ h4. Creating an Object
* +before_validation+
* +after_validation+
* +before_save+
+* +around_save+
* +before_create+
* +around_create+
* +after_create+
@@ -967,6 +967,7 @@ h4. Updating an Object
* +before_validation+
* +after_validation+
* +before_save+
+* +around_save+
* +before_update+
* +around_update+
* +after_update+
@@ -975,8 +976,8 @@ h4. Updating an Object
h4. Destroying an Object
* +before_destroy+
-* +after_destroy+
* +around_destroy+
+* +after_destroy+
WARNING. +after_save+ runs both on create and update, but always _after_ the more specific callbacks +after_create+ and +after_update+, no matter the order in which the macro calls were executed.
@@ -986,15 +987,15 @@ The +after_initialize+ callback will be called whenever an Active Record object
The +after_find+ callback will be called whenever Active Record loads a record from the database. +after_find+ is called before +after_initialize+ if both are defined.
-The +after_initialize+ and +after_find+ callbacks are a bit different from the others. They have no +before_*+ counterparts, and they are registered simply by defining them as regular methods with predefined names. If you try to register +after_initialize+ or +after_find+ using macro-style class methods, they will just be ignored. This behavior is due to performance reasons, since +after_initialize+ and +after_find+ will both be called for each record found in the database, which would otherwise significantly slow down the queries.
+The +after_initialize+ and +after_find+ callbacks have no +before_*+ counterparts, but they can be registered just like the other Active Record callbacks.
<ruby>
class User < ActiveRecord::Base
- def after_initialize
+ after_initialize do |user|
puts "You have initialized an object!"
end
- def after_find
+ after_find do |user|
puts "You have found an object!"
end
end
@@ -1021,7 +1022,7 @@ The following methods trigger callbacks:
* +increment!+
* +save+
* +save!+
-* +save(false)+
+* +save(:validate => false)+
* +toggle!+
* +update+
* +update_attribute+
diff --git a/railties/guides/source/active_resource_basics.textile b/railties/guides/source/active_resource_basics.textile
index 851aac1a3f..37abb8a640 100644
--- a/railties/guides/source/active_resource_basics.textile
+++ b/railties/guides/source/active_resource_basics.textile
@@ -71,7 +71,7 @@ person.destroy
h3. Validations
-Module to support validation and errors with Active Resource objects. The module overrides Base#save to rescue ActiveResource::ResourceInvalid exceptions and parse the errors returned in the web service response. The module also adds an errors collection that mimics the interface of the errors provided by ActiveRecord::Errors.
+Module to support validation and errors with Active Resource objects. The module overrides Base#save to rescue ActiveResource::ResourceInvalid exceptions and parse the errors returned in the web service response. The module also adds an errors collection that mimics the interface of the errors provided by ActiveModel::Errors.
h4. Validating client side resources by overriding validation methods in base class
diff --git a/railties/guides/source/active_support_core_extensions.textile b/railties/guides/source/active_support_core_extensions.textile
index ff6c5f967f..61fdb5ccc6 100644
--- a/railties/guides/source/active_support_core_extensions.textile
+++ b/railties/guides/source/active_support_core_extensions.textile
@@ -177,19 +177,6 @@ end
NOTE: Defined in +active_support/core_ext/object/try.rb+.
-h4. +singleton_class+
-
-The method +singleton_class+ returns the singleton class of the receiver:
-
-<ruby>
-String.singleton_class # => #<Class:String>
-String.new.singleton_class # => #<Class:#<String:0x17a1d1c>>
-</ruby>
-
-WARNING: Fixnums and symbols have no singleton classes, +singleton_class+ raises +TypeError+ on them. Moreover, the singleton classes of +nil+, +true+, and +false+, are +NilClass+, +TrueClass+, and +FalseClass+, respectively.
-
-NOTE: Defined in +active_support/core_ext/kernel/singleton_class.rb+.
-
h4. +class_eval(*args, &block)+
You can evaluate code in the context of any object's singleton class using +class_eval+:
@@ -389,7 +376,7 @@ NOTE: Defined in +active_support/core_ext/object/instance_variables.rb+.
h5. +instance_values+
The method +instance_values+ returns a hash that maps instance variable names without "@" to their
-corresponding values. Keys are strings both in Ruby 1.8 and 1.9:
+corresponding values. Keys are strings:
<ruby>
class C
@@ -440,14 +427,16 @@ NOTE: Defined in +active_support/core_ext/kernel/reporting.rb+.
h4. +in?+
-The predicate +in?+ tests if an object is included in another object. An +ArgumentError+ exception will be raised if the argument passed does not respond to +include?+.
+The predicate +in?+ tests if an object is included in another object or a list of objects. An +ArgumentError+ exception will be raised if a single argument is passed and it does not respond to +include?+.
Examples of +in?+:
<ruby>
+1.in?(1,2) # => true
1.in?([1,2]) # => true
"lo".in?("hello") # => true
25.in?(30..50) # => false
+1.in?(1) # => ArgumentError
</ruby>
NOTE: Defined in +active_support/core_ext/object/inclusion.rb+.
@@ -571,7 +560,7 @@ NOTE: Defined in +active_support/core_ext/module/attr_accessor_with_default.rb+.
h5. Internal Attributes
-When you are defining an attribute in a class that is meant to be subclassed name collisions are a risk. That's remarkably important for libraries.
+When you are defining an attribute in a class that is meant to be subclassed, name collisions are a risk. That's remarkably important for libraries.
Active Support defines the macros +attr_internal_reader+, +attr_internal_writer+, and +attr_internal_accessor+. They behave like their Ruby built-in +attr_*+ counterparts, except they name the underlying instance variable in a way that makes collisions less likely.
@@ -703,7 +692,8 @@ NOTE: Defined in +active_support/core_ext/module/introspection.rb+.
h4. Constants
-The method +local_constants+ returns the names of the constants that have been defined in the receiver module:
+The method +local_constants+ returns the names of the constants that have been
+defined in the receiver module:
<ruby>
module X
@@ -715,13 +705,11 @@ module X
end
end
-X.local_constants # => ["X2", "X1", "Y"], assumes Ruby 1.8
-X::Y.local_constants # => ["X1", "Y1"], assumes Ruby 1.8
+X.local_constants # => [:X1, :X2, :Y]
+X::Y.local_constants # => [:Y1, :X1]
</ruby>
-The names are returned as strings in Ruby 1.8, and as symbols in Ruby 1.9. The method +local_constant_names+ always returns strings.
-
-WARNING: This method returns precise results in Ruby 1.9. In older versions of Ruby, however, it may miss some constants in case the same constant exists in the receiver module as well as in any of its ancestors and both constants point to the same object (objects are compared using +Object#object_id+).
+The names are returned as symbols. (The deprecated method +local_constant_names+ returns strings.)
NOTE: Defined in +active_support/core_ext/module/introspection.rb+.
@@ -748,8 +736,8 @@ Math.qualified_const_get("E") # => 2.718281828459045
</ruby>
These methods are analogous to their builtin counterparts. In particular,
-+qualified_constant_defined?+ accepts an optional second argument in 1.9
-to be able to say whether you want the predicate to look in the ancestors.
++qualified_constant_defined?+ accepts an optional second argument to be
+able to say whether you want the predicate to look in the ancestors.
This flag is taken into account for each constant in the expression while
walking down the path.
@@ -770,12 +758,12 @@ end
+qualified_const_defined?+ behaves this way:
<ruby>
-N.qualified_const_defined?("C::X", false) # => false (1.9 only)
-N.qualified_const_defined?("C::X", true) # => true (1.9 only)
-N.qualified_const_defined?("C::X") # => false in 1.8, true in 1.9
+N.qualified_const_defined?("C::X", false) # => false
+N.qualified_const_defined?("C::X", true) # => true
+N.qualified_const_defined?("C::X") # => true
</ruby>
-As the last example implies, in 1.9 the second argument defaults to true,
+As the last example implies, the second argument defaults to true,
as in +const_defined?+.
For coherence with the builtin methods only relative paths are accepted.
@@ -783,30 +771,6 @@ Absolute qualified constant names like +::Math::PI+ raise +NameError+.
NOTE: Defined in +active_support/core_ext/module/qualified_const.rb+.
-h4. Synchronization
-
-The +synchronize+ macro declares a method to be synchronized:
-
-<ruby>
-class Counter
- @@mutex = Mutex.new
- attr_reader :value
-
- def initialize
- @value = 0
- end
-
- def incr
- @value += 1 # non-atomic
- end
- synchronize :incr, :with => '@@mutex'
-end
-</ruby>
-
-The method receives the name of an action, and a +:with+ option with code. The code is evaluated in the context of the receiver each time the method is invoked, and it should evaluate to a +Mutex+ instance or any other object that responds to +synchronize+ and accepts a block.
-
-NOTE: Defined in +active_support/core_ext/module/synchronization.rb+.
-
h4. Reachable
A named module is reachable if it is stored in its corresponding constant. It means you can reach the module object via the constant.
@@ -857,7 +821,7 @@ M.name # => "M"
N = Module.new
N.name # => "N"
-Module.new.name # => "" in 1.8, nil in 1.9
+Module.new.name # => nil
</ruby>
You can check whether a module has a name with the predicate +anonymous?+:
@@ -970,18 +934,6 @@ In the previous example the macro generates +avatar_size+ rather than +size+.
NOTE: Defined in +active_support/core_ext/module/delegation.rb+
-h4. Method Names
-
-The builtin methods +instance_methods+ and +methods+ return method names as strings or symbols depending on the Ruby version. Active Support defines +instance_method_names+ and +method_names+ to be equivalent to them, respectively, but always getting strings back.
-
-For example, +ActionView::Helpers::FormBuilder+ knows this array difference is going to work no matter the Ruby version:
-
-<ruby>
-self.field_helpers = (FormHelper.instance_method_names - ['form_for'])
-</ruby>
-
-NOTE: Defined in +active_support/core_ext/module/method_names.rb+
-
h4. Redefining Methods
There are cases where you need to define a method with +define_method+, but don't know whether a method with that name already exists. If it does, a warning is issued if they are enabled. No big deal, but not clean either.
@@ -1299,7 +1251,7 @@ NOTE: Defined in +active_support/core_ext/string/output_safety.rb+.
h5. Transformation
-As a rule of thumb, except perhaps for concatenation as explained above, any method that may change a string gives you an unsafe string. These are +donwcase+, +gsub+, +strip+, +chomp+, +underscore+, etc.
+As a rule of thumb, except perhaps for concatenation as explained above, any method that may change a string gives you an unsafe string. These are +downcase+, +gsub+, +strip+, +chomp+, +underscore+, etc.
In the case of in-place transformations like +gsub!+ the receiver itself becomes unsafe.
@@ -1849,43 +1801,6 @@ NOTE: Defined in +active_support/core_ext/string/inflections.rb+.
h4(#string-conversions). Conversions
-h5. +ord+
-
-Ruby 1.9 defines +ord+ to be the codepoint of the first character of the receiver. Active Support backports +ord+ for single-byte encodings like ASCII or ISO-8859-1 in Ruby 1.8:
-
-<ruby>
-"a".ord # => 97
-"à".ord # => 224, in ISO-8859-1
-</ruby>
-
-In Ruby 1.8 +ord+ doesn't work in general in UTF8 strings, use the multibyte support in Active Support for that:
-
-<ruby>
-"a".mb_chars.ord # => 97
-"à".mb_chars.ord # => 224, in UTF8
-</ruby>
-
-Note that the 224 is different in both examples. In ISO-8859-1 "à" is represented as a single byte, 224. Its single-character representation in UTF8 has two bytes, namely 195 and 160, but its Unicode codepoint is 224. If we call +ord+ on the UTF8 string "à" the return value will be 195 in Ruby 1.8. That is not an error, because UTF8 is unsupported, the call itself would be bogus.
-
-INFO: +ord+ is equivalent to +getbyte(0)+.
-
-NOTE: Defined in +active_support/core_ext/string/conversions.rb+.
-
-h5. +getbyte+
-
-Active Support backports +getbyte+ from Ruby 1.9:
-
-<ruby>
-"foo".getbyte(0) # => 102, same as "foo".ord
-"foo".getbyte(1) # => 111
-"foo".getbyte(9) # => nil
-"foo".getbyte(-1) # => 111
-</ruby>
-
-INFO: +getbyte+ is equivalent to +[]+.
-
-NOTE: Defined in +active_support/core_ext/string/conversions.rb+.
-
h5. +to_date+, +to_time+, +to_datetime+
The methods +to_date+, +to_time+, and +to_datetime+ are basically convenience wrappers around +Date._parse+:
@@ -1957,9 +1872,24 @@ The method +multiple_of?+ tests whether an integer is multiple of the argument:
NOTE: Defined in +active_support/core_ext/integer/multiple.rb+.
+h4. +ordinal+
+
+The method +ordinal+ returns the ordinal suffix string corresponding to the receiver integer:
+
+<ruby>
+1.ordinal # => "st"
+2.ordinal # => "nd"
+53.ordinal # => "rd"
+2009.ordinal # => "th"
+-21.ordinal # => "st"
+-134.ordinal # => "th"
+</ruby>
+
+NOTE: Defined in +active_support/core_ext/integer/inflections.rb+.
+
h4. +ordinalize+
-The method +ordinalize+ returns the ordinal string corresponding to the receiver integer:
+The method +ordinalize+ returns the ordinal string corresponding to the receiver integer. In comparison, note that the +ordinal+ method returns *only* the suffix string.
<ruby>
1.ordinalize # => "1st"
@@ -1972,38 +1902,12 @@ The method +ordinalize+ returns the ordinal string corresponding to the receiver
NOTE: Defined in +active_support/core_ext/integer/inflections.rb+.
-h3. Extensions to +Float+
-
-h4. +round+
-
-The built-in method +Float#round+ rounds a float to the nearest integer. In Ruby 1.9 this method takes an optional argument to let you specify a precision. Active Support adds that functionality to +round+ in previous versions of Ruby:
-
-<ruby>
-Math::E.round(4) # => 2.7183
-</ruby>
-
-NOTE: Defined in +active_support/core_ext/float/rounding.rb+.
-
h3. Extensions to +BigDecimal+
...
h3. Extensions to +Enumerable+
-h4. +group_by+
-
-Active Support redefines +group_by+ in Ruby 1.8.7 so that it returns an ordered hash as in 1.9:
-
-<ruby>
-entries_by_surname_initial = address_book.group_by do |entry|
- entry.surname.at(0).upcase
-end
-</ruby>
-
-Distinct block return values are added to the hash as they come, so that's the resulting order.
-
-NOTE: Defined in +active_support/core_ext/enumerable.rb+.
-
h4. +sum+
The method +sum+ adds the elements of an enumerable:
@@ -2051,32 +1955,6 @@ end
NOTE: Defined in +active_support/core_ext/enumerable.rb+.
-h4. +each_with_object+
-
-The +inject+ method offers iteration with an accumulator:
-
-<ruby>
-[2, 3, 4].inject(1) {|product, i| product*i } # => 24
-</ruby>
-
-The block is expected to return the value for the accumulator in the next iteration, and this makes building mutable objects a bit cumbersome:
-
-<ruby>
-[1, 2].inject({}) {|h, i| h[i] = i**2; h} # => {1 => 1, 2 => 4}
-</ruby>
-
-See that spurious "+; h+"?
-
-Active Support backports +each_with_object+ from Ruby 1.9, which addresses that use case. It iterates over the collection, passes the accumulator, and returns the accumulator when done. You normally modify the accumulator in place. The example above would be written this way:
-
-<ruby>
-[1, 2].each_with_object({}) {|i, h| h[i] = i**2} # => {1 => 1, 2 => 4}
-</ruby>
-
-WARNING. Note that the item of the collection and the accumulator come in different order in +inject+ and +each_with_object+.
-
-NOTE: Defined in +active_support/core_ext/enumerable.rb+.
-
h4. +index_by+
The method +index_by+ generates a hash with the elements of an enumerable indexed by some key.
@@ -2148,20 +2026,6 @@ The methods +second+, +third+, +fourth+, and +fifth+ return the corresponding el
NOTE: Defined in +active_support/core_ext/array/access.rb+.
-h4. Random Access
-
-Active Support backports +sample+ from Ruby 1.9:
-
-<ruby>
-shape_type = [Circle, Square, Triangle].sample
-# => Square, for example
-
-shape_types = [Circle, Square, Triangle].sample(2)
-# => [Triangle, Circle], for example
-</ruby>
-
-NOTE: Defined in +active_support/core_ext/array/random_access.rb+.
-
h4. Adding Elements
h5. +prepend+
@@ -2388,9 +2252,6 @@ The last point is particularly worth comparing for some enumerables:
<ruby>
Array.wrap(:foo => :bar) # => [{:foo => :bar}]
Array(:foo => :bar) # => [[:foo, :bar]]
-
-Array.wrap("foo\nbar") # => ["foo\nbar"]
-Array("foo\nbar") # => ["foo\n", "bar"], in Ruby 1.8
</ruby>
There's also a related idiom that uses the splat operator:
@@ -2914,14 +2775,6 @@ WARNING: The original +Range#include?+ is still the one aliased to +Range#===+.
NOTE: Defined in +active_support/core_ext/range/include_range.rb+.
-h4. +cover?+
-
-Ruby 1.9 provides +cover?+, and Active Support defines it for previous versions as an alias for +include?+.
-
-The method +include?+ in Ruby 1.9 is different from the one in 1.8 for non-numeric ranges: instead of being based on comparisons between the value and the range's endpoints, it walks the range with +succ+ looking for value. This works better for ranges with holes, but it has different complexity and may not finish in some other cases.
-
-In Ruby 1.9 the old behavior is still available in the new +cover?+, which Active Support backports for forward compatibility. For example, Rails uses +cover?+ for ranges in +validates_inclusion_of+.
-
h4. +overlaps?+
The method +Range#overlaps?+ says whether any two given ranges have non-void intersection:
@@ -3039,15 +2892,30 @@ Active Support defines these methods as well for Ruby 1.8.
h6. +beginning_of_week+, +end_of_week+
-The methods +beginning_of_week+ and +end_of_week+ return the dates for the beginning and end of week, assuming weeks start on Monday:
+The methods +beginning_of_week+ and +end_of_week+ return the dates for the
+beginning and end of the week, respectively. Weeks are assumed to start on
+Monday, but that can be changed passing an argument.
<ruby>
-d = Date.new(2010, 5, 8) # => Sat, 08 May 2010
-d.beginning_of_week # => Mon, 03 May 2010
-d.end_of_week # => Sun, 09 May 2010
+d = Date.new(2010, 5, 8) # => Sat, 08 May 2010
+d.beginning_of_week # => Mon, 03 May 2010
+d.beginning_of_week(:sunday) # => Sun, 02 May 2010
+d.end_of_week # => Sun, 09 May 2010
+d.end_of_week(:sunday) # => Sat, 08 May 2010
</ruby>
-+beginning_of_week+ is aliased to +monday+ and +at_beginning_of_week+. +end_of_week+ is aliased to +sunday+ and +at_end_of_week+.
++beginning_of_week+ is aliased to +at_beginning_of_week+ and +end_of_week+ is aliased to +at_end_of_week+.
+
+h6. +monday+, +sunday+
+
+The methods +monday+ and +sunday+ return the dates for the beginning and
+end of the week, respectively. Weeks are assumed to start on Monday.
+
+<ruby>
+d = Date.new(2010, 5, 8) # => Sat, 08 May 2010
+d.monday # => Mon, 03 May 2010
+d.sunday # => Sun, 09 May 2010
+</ruby>
h6. +prev_week+, +next_week+
@@ -3272,8 +3140,10 @@ The class +DateTime+ is a subclass of +Date+ so by loading +active_support/core_
<ruby>
yesterday
tomorrow
-beginning_of_week (monday, at_beginning_of_week)
-end_on_week (at_end_of_week)
+beginning_of_week (at_beginning_of_week)
+end_of_week (at_end_of_week)
+monday
+sunday
weeks_ago
prev_week
next_week
@@ -3446,8 +3316,10 @@ ago
since (in)
beginning_of_day (midnight, at_midnight, at_beginning_of_day)
end_of_day
-beginning_of_week (monday, at_beginning_of_week)
-end_on_week (at_end_of_week)
+beginning_of_week (at_beginning_of_week)
+end_of_week (at_end_of_week)
+monday
+sunday
weeks_ago
prev_week
next_week
@@ -3572,12 +3444,6 @@ Time.utc_time(1582, 10, 3) + 5.days
# => Mon Oct 18 00:00:00 UTC 1582
</ruby>
-h3. Extensions to +Process+
-
-h4. +daemon+
-
-Ruby 1.9 provides +Process.daemon+, and Active Support defines it for previous versions. It accepts the same two arguments, whether it should chdir to the root directory (default, true), and whether it should inherit the standard file descriptors from the parent (default, false).
-
h3. Extensions to +File+
h4. +atomic_write+
diff --git a/railties/guides/source/api_documentation_guidelines.textile b/railties/guides/source/api_documentation_guidelines.textile
index 99eb668513..93120c15a7 100644
--- a/railties/guides/source/api_documentation_guidelines.textile
+++ b/railties/guides/source/api_documentation_guidelines.textile
@@ -134,13 +134,6 @@ h4. Regular Font
When "true" and "false" are English words rather than Ruby keywords use a regular font:
-<ruby>
-# If <tt>reload_plugins?</tt> is false, add this to your plugin's <tt>init.rb</tt>
-# to make it reloadable:
-#
-# Dependencies.load_once_paths.delete lib_path
-</ruby>
-
h3. Description Lists
In lists of options, parameters, etc. use a hyphen between the item and its description (reads better than a colon because normally options are symbols):
diff --git a/railties/guides/source/asset_pipeline.textile b/railties/guides/source/asset_pipeline.textile
index 6ff5e87b6d..ff2bd08602 100644
--- a/railties/guides/source/asset_pipeline.textile
+++ b/railties/guides/source/asset_pipeline.textile
@@ -6,7 +6,7 @@ By referring to this guide you will be able to:
* Understand what the asset pipeline is and what it does
* Properly organize your application assets
* Understand the benefits of the asset pipeline
-* Adding a pre-processor to the pipeline
+* Add a pre-processor to the pipeline
* Package assets with a gem
endprologue.
@@ -17,7 +17,7 @@ The asset pipeline provides a framework to concatenate and minify or compress Ja
Prior to Rails 3.1 these features were added through third-party Ruby libraries such as Jammit and Sprockets. Rails 3.1 is integrated with Sprockets through Action Pack which depends on the +sprockets+ gem, by default.
-By having this as a core feature of Rails, all developers can benefit from the power of having their assets pre-processed, compressed and minified by one central library, Sprockets. This is part of Rails' "fast by default" strategy as outlined by DHH in his keynote at RailsConf 2011.
+Making the asset pipeline a core feature of Rails means that all developers can benefit from the power of having their assets pre-processed, compressed and minified by one central library, Sprockets. This is part of Rails' "fast by default" strategy as outlined by DHH in his keynote at RailsConf 2011.
In Rails 3.1, the asset pipeline is enabled by default. It can be disabled in +config/application.rb+ by putting this line inside the application class definition:
@@ -25,34 +25,34 @@ In Rails 3.1, the asset pipeline is enabled by default. It can be disabled in +c
config.assets.enabled = false
</ruby>
-You can also disable it while creating a new application by passing the <tt>--skip-sprockets</tt> option.
+You can also disable the asset pipeline while creating a new application by passing the <tt>--skip-sprockets</tt> option.
<plain>
rails new appname --skip-sprockets
</plain>
-It is recommended that you use the defaults for all new apps.
+You should use the defaults for all new applications unless you have a specific reason to avoid the asset pipeline.
h4. Main Features
-The first feature of the pipeline is to concatenate assets. This is important in a production environment, as it reduces the number of requests that a browser must make to render a web page.
+The first feature of the pipeline is to concatenate assets. This is important in a production environment, because it can reduce the number of requests that a browser must make to render a web page. Web browsers are limited in the number of requests that they can make in parallel, so fewer requests can mean faster loading for your application.
-While Rails already has a feature to concatenate these types of assets by placing +:cache => true+ at the end of tags such as +javascript_include_tag+ and +stylesheet_link_tag+, it has a series of limitations. For example, it cannot generate the caches in advance, and it is not able to transparently include assets provided by third-party libraries.
+Rails 2.x introduced the ability to concatenate JavaScript and CSS assets by placing +:cache => true+ at the end of the +javascript_include_tag+ and +stylesheet_link_tag+ methods. But this technique has some limitations. For example, it cannot generate the caches in advance, and it is not able to transparently include assets provided by third-party libraries.
-The default behavior in Rails 3.1 and onward is to concatenate all files into one master file each for JS and CSS. However, you can separate files or groups of files if required (see below). In production, an MD5 fingerprint is inserted into each filename so that the file is cached by the web browser but can be invalidated if the fingerprint is altered.
+Starting with version 3.1, Rails defaults to concatenating all JavaScript files into one master +.js+ file and all CSS files into one master +.css+ file. As you'll learn later in this guide, you can customize this strategy to group files any way you like. In production, Rails inserts an MD5 fingerprint into each filename so that the file is cached by the web browser. You can invalidate the cache by altering this fingerprint, which happens automatically whenever you change the file contents..
-The second feature is to minify or compress assets. For CSS, this usually involves removing whitespace and comments. For JavaScript, more complex processes can be applied. You can choose from a set of built in options or specify your own.
+The second feature of the asset pipeline is asset minification or compression. For CSS files, this is done by removing whitespace and comments. For JavaScript, more complex processes can be applied. You can choose from a set of built in options or specify your own.
-The third feature is the ability to code these assets using another language, or language extension. These include Sass for CSS, CoffeeScript for JavaScript, and ERB for both.
+The third feature of the asset pipeline is that it allows coding assets via a higher-level language, with precompilation down to the actual assets. Supported languages include Sass for CSS, CoffeeScript for JavaScript, and ERB for both by default.
h4. What is Fingerprinting and Why Should I Care?
-Fingerprinting is a technique whereby the filenames of content that is static or infrequently updated are altered to be unique to the content contained in the file.
+Fingerprinting is a technique that makes the name of a file dependent on the contents of the file. When the file contents change, the filename is also changed. For content that is static or infrequently changed, this provides an easy way to tell whether two versions of a file are identical, even across different servers or deployment dates.
-When a filename is unique and based on its content, HTTP headers can be set to encourage caches everywhere (at ISPs, in browsers) to keep their own copy of the content. When the content is updated, the fingerprint will change and the remote clients will request the new file. This is generally known as _cache busting_.
+When a filename is unique and based on its content, HTTP headers can be set to encourage caches everywhere (whether at CDNs, at ISPs, in networking equipment, or in web browsers) to keep their own copy of the content. When the content is updated, the fingerprint will change. This will cause the remote clients to request a new copy of the content. This is generally known as _cache busting_.
-The most effective technique is to insert a hash of the content into the name, usually at the end. For example a CSS file +global.css+ is hashed and the filename is updated to incorporate the digest, for example becoming:
+The technique that Rails uses for fingerprinting is to insert a hash of the content into the name, usually at the end. For example a CSS file +global.css+ could be renamed with an MD5 digest of its contents:
<plain>
global-908e25f4bf641868d8683022a5b62f54.css
@@ -60,30 +60,32 @@ global-908e25f4bf641868d8683022a5b62f54.css
This is the strategy adopted by the Rails asset pipeline.
-Rails' old strategy was to append a query string to every asset linked with a built-in helper. In the source the generated code looked like this:
+Rails' old strategy was to append a date-based query string to every asset linked with a built-in helper. In the source the generated code looked like this:
<plain>
/stylesheets/global.css?1309495796
</plain>
-This has several disadvantages:
+The query string strategy has several disadvantages:
<ol>
<li>
- <strong>Not all caches will cache content with a query string</strong>.<br>
+ <strong>Not all caches will reliably cache content where the filename only differs by query parameters</strong>.<br>
"Steve Souders recommends":http://www.stevesouders.com/blog/2008/08/23/revving-filenames-dont-use-querystring/, "...avoiding a querystring for cacheable resources". He found that in this case 5-20% of requests will not be cached. Query strings in particular do not work at all with some CDNs for cache invalidation.
</li>
<li>
<strong>The file name can change between nodes in multi-server environments.</strong><br>
- The query string in Rails is based on the modification time of the files. When assets are deployed to a cluster, there is no guarantee that the timestamps will be the same, resulting in different values being used depending on which server handles the request.
+ The default query string in Rails 2.x is based on the modification time of the files. When assets are deployed to a cluster, there is no guarantee that the timestamps will be the same, resulting in different values being used depending on which server handles the request.
+ </li>
+ <li>
+ <strong>Too much cache invalidation</strong><br />
+ When static assets are deployed with each new release of code, the mtime of _all_ these files changes, forcing all remote clients to fetch them again, even when the content of those assets has not changed.
</li>
</ol>
-The other problem is that when static assets are deployed with each new release of code, the mtime of _all_ these files changes, forcing all remote clients to fetch them again, even when the content of those assets has not changed.
+Fingerprinting fixes these problems by avoiding query strings, and by ensuring that filenames are consistent based on their content.
-Fingerprinting fixes these problems by avoiding query strings, and by ensuring filenames are consistent based on their content.
-
-Fingerprinting is enabled by default for production and disabled for all the others environments. You can enable or disable it in your configuration through the +config.assets.digest+ option.
+Fingerprinting is enabled by default for production and disabled for all other environments. You can enable or disable it in your configuration through the +config.assets.digest+ option.
More reading:
@@ -95,34 +97,86 @@ h3. How to Use the Asset Pipeline
In previous versions of Rails, all assets were located in subdirectories of +public+ such as +images+, +javascripts+ and +stylesheets+. With the asset pipeline, the preferred location for these assets is now the +app/assets+ directory. Files in this directory are served by the Sprockets middleware included in the sprockets gem.
-This is not to say that assets can (or should) no longer be placed in +public+; they still can be and will be served as static files by the application or web server. You would only use +app/assets+ if you wish your files to undergo some pre-processing before they are served.
+Assets can still be placed in the +public+ hierarchy. Any assets under +public+ will be served as static files by the application or web server. You should use +app/assets+ for files that must undergo some pre-processing before they are served.
-In production, the default is to precompile these files to +public/assets+ so that they can be more efficiently delivered by the web server.
+In production, Rails precompiles these files to +public/assets+ by default. The precompiled copies are then served as static assets by the web server. The files in +app/assets+ are never served directly in production.
-When a scaffold or controller is generated for the application, Rails also generates a JavaScript file (or CoffeeScript file if the +coffee-rails+ gem is in the +Gemfile+) and a Cascading Style Sheet file (or SCSS file if +sass-rails+ is in the +Gemfile+) for that controller.
+When you generate a scaffold or a controller, Rails also generates a JavaScript file (or CoffeeScript file if the +coffee-rails+ gem is in the +Gemfile+) and a Cascading Style Sheet file (or SCSS file if +sass-rails+ is in the +Gemfile+) for that controller.
-For example, if a +ProjectsController+ is generated, there will be a new file at +app/assets/javascripts/projects.js.coffee+ and another at +app/assets/stylesheets/projects.css.scss+. You should put any JavaScript or CSS unique to a controller inside their respective asset files, as these files can then be loaded just for these controllers with lines such as +<%= javascript_include_tag params[:controller] %>+ or +<%= stylesheet_link_tag params[:controller] %>+.
+For example, if you generate a +ProjectsController+, Rails will also add a new file at +app/assets/javascripts/projects.js.coffee+ and another at +app/assets/stylesheets/projects.css.scss+. You should put any JavaScript or CSS unique to a controller inside their respective asset files, as these files can then be loaded just for these controllers with lines such as +<%= javascript_include_tag params[:controller] %>+ or +<%= stylesheet_link_tag params[:controller] %>+.
-NOTE: You will need a "ExecJS":https://github.com/sstephenson/execjs#readme supported runtime in order to use CoffeeScript. If you are using Mac OS X or Windows you have a JavaScript runtime installed in your operating system. Check "ExecJS":https://github.com/sstephenson/execjs#readme documentation to know all supported JavaScript runtimes.
+NOTE: You must have an "ExecJS":https://github.com/sstephenson/execjs#readme supported runtime in order to use CoffeeScript. If you are using Mac OS X or Windows you have a JavaScript runtime installed in your operating system. Check "ExecJS":https://github.com/sstephenson/execjs#readme documentation to know all supported JavaScript runtimes.
h4. Asset Organization
-Assets can be placed inside an application in one of three locations: +app/assets+, +lib/assets+ or +vendor/assets+.
+Pipeline assets can be placed inside an application in one of three locations: +app/assets+, +lib/assets+ or +vendor/assets+.
+app/assets+ is for assets that are owned by the application, such as custom images, JavaScript files or stylesheets.
+lib/assets+ is for your own libraries' code that doesn't really fit into the scope of the application or those libraries which are shared across applications.
-+vendor/assets+ is for assets that are owned by outside entities, such as code for JavaScript plugins.
++vendor/assets+ is for assets that are owned by outside entities, such as code for JavaScript plugins and CSS frameworks.
+
+h5. Search paths
+
+When a file is referenced from a manifest or a helper, Sprockets searches the three default asset locations for it.
+
+The default locations are: +app/assets/images+ and the subdirectories +javascripts+ and +stylesheets+ in all three asset locations.
+
+For example, these files:
+
+<plain>
+app/assets/javascripts/home.js
+lib/assets/javascripts/moovinator.js
+vendor/assets/javascript/slider.js
+</plain>
+
+would be referenced in a manifest like this:
+
+<plain>
+//= require home
+//= require moovinator
+//= require slider
+</plain>
+
+Assets inside subdirectories can also be accessed.
+
+<plain>
+app/assets/javascripts/sub/something.js
+</plain>
+
+is referenced as:
+
+<plain>
+//= require sub/something
+</plain>
-All subdirectories that exist within these three locations are added to the search path for Sprockets (visible by calling +Rails.application.config.assets.paths+ in a console). When an asset is requested, these paths are traversed to see if they contain an asset matching the name specified. Once an asset has been found, it's processed by Sprockets and served.
+You can view the search path by inspecting +Rails.application.config.assets.paths+ in the Rails console.
-You can add additional (fully qualified) paths to the pipeline in +config/application.rb+. For example:
+Additional (fully qualified) paths can be added to the pipeline in +config/application.rb+. For example:
<ruby>
config.assets.paths << Rails.root.join("app", "assets", "flash")
</ruby>
+Paths are traversed in the order that they occur in the search path.
+
+It is important to note that files you want to reference outside a manifest must be added to the precompile array or they will not be available in the production environment.
+
+h5. Using index files
+
+Sprockets uses files named +index+ (with the relevant extensions) for a special purpose.
+
+For example, if you have a jQuery library with many modules, which is stored in +lib/assets/library_name+, the file +lib/assets/library_name/index.js+ serves as the manifest for all files in this library. This file could include a list of all the required files in order, or a simple <tt>require_tree</tt> directive.
+
+The library as a whole can be accessed in the site's application manifest like so:
+
+<plain>
+//= require library_name
+</plain>
+
+This simplifies maintenance and keeps things clean by allowing related code to be grouped before inclusion elsewhere.
+
h4. Coding Links to Assets
Sprockets does not add any new methods to access your assets - you still use the familiar +javascript_include_tag+ and +stylesheet_link_tag+.
@@ -138,7 +192,7 @@ In regular views you can access images in the +assets/images+ directory like thi
<%= image_tag "rails.png" %>
</erb>
-Provided that the pipeline is enabled within your application (and not disabled in the current environment context), this file is served by Sprockets. If a file exists at +public/assets/rails.png+ it is served by the webserver.
+Provided that the pipeline is enabled within your application (and not disabled in the current environment context), this file is served by Sprockets. If a file exists at +public/assets/rails.png+ it is served by the web server.
Alternatively, a request for a file with an MD5 hash such as +public/assets/rails-af27b6a414e6da00003503148be9b409.png+ is treated the same way. How these hashes are generated is covered in the "In Production":#in-production section later on in this guide.
@@ -152,7 +206,7 @@ Images can also be organized into subdirectories if required, and they can be ac
h5. CSS and ERB
-If you add an +erb+ extension to a CSS asset, making it something such as +application.css.erb+, then helpers like +asset_path+ are available in your CSS rules:
+The asset pipeline automatically evaluates ERB. This means that if you add an +erb+ extension to a CSS asset (for example, +application.css.erb+), then helpers like +asset_path+ are available in your CSS rules:
<plain>
.class { background-image: url(<%= asset_path 'image.png' %>) }
@@ -194,7 +248,7 @@ $('#logo').attr({
This writes the path to the particular asset being referenced.
-Similarly, you can use the +asset_path+ helper in CoffeeScript files with +erb+ extension (eg. +application.js.coffee.erb+):
+Similarly, you can use the +asset_path+ helper in CoffeeScript files with +erb+ extension (e.g., +application.js.coffee.erb+):
<plain>
$('#logo').attr src: "<%= asset_path('logo.png') %>"
@@ -202,9 +256,9 @@ $('#logo').attr src: "<%= asset_path('logo.png') %>"
h4. Manifest Files and Directives
-Sprockets uses manifest files to determine which assets to include and serve. These manifest files contain _directives_ -- instructions that tell Sprockets which files to require in order to build a single CSS or JavaScript file. With these directives, Sprockets loads the files specified, processes them if necessary, concatenates them into one single file and then compresses them (if +Rails.application.config.assets.compress+ is true). By serving one file rather than many, the load time of pages are greatly reduced as there are fewer requests to make.
+Sprockets uses manifest files to determine which assets to include and serve. These manifest files contain _directives_ -- instructions that tell Sprockets which files to require in order to build a single CSS or JavaScript file. With these directives, Sprockets loads the files specified, processes them if necessary, concatenates them into one single file and then compresses them (if +Rails.application.config.assets.compress+ is true). By serving one file rather than many, the load time of pages can be greatly reduced because the browser makes fewer requests.
-For example, in the default Rails application there's a +app/assets/javascripts/application.js+ file which contains the following lines:
+For example, a new Rails application includes a default +app/assets/javascripts/application.js+ file which contains the following lines:
<plain>
// ...
@@ -217,11 +271,11 @@ In JavaScript files, the directives begin with +//=+. In this case, the file is
NOTE. In Rails 3.1 the +jquery-rails+ gem provides the +jquery.js+ and +jquery_ujs.js+ files via the asset pipeline. You won't see them in the application tree.
-The +require_tree+ directive tells Sprockets to recursively include _all_ JavaScript files in this directory into the output. Only a path relative to the manifest file can be specified. There is also a +require_directory+ directive which includes all JavaScript files only in the directory specified (no nesting).
+The +require_tree+ directive tells Sprockets to recursively include _all_ JavaScript files in the specified directory into the output. These paths must be specified relative to the manifest file. You can also use the +require_directory+ directive which includes all JavaScript files only in the directory specified, without recursion.
-Directives are processed top to bottom, but the order in which files are included by +require_tree+ is unspecified. You should not rely on any particular order among those. If you need to ensure some particular JavaScript ends up above some other, require it before in the manifest. Note that the family of +require+ directives prevents files from being included twice in the output.
+Directives are processed top to bottom, but the order in which files are included by +require_tree+ is unspecified. You should not rely on any particular order among those. If you need to ensure some particular JavaScript ends up above some other in the concatenated file, require the prerequisite file first in the manifest. Note that the family of +require+ directives prevents files from being included twice in the output.
-There's also a default +app/assets/stylesheets/application.css+ file which contains these lines:
+Rails also creates a default +app/assets/stylesheets/application.css+ file which contains these lines:
<plain>
/* ...
@@ -230,15 +284,15 @@ There's also a default +app/assets/stylesheets/application.css+ file which conta
*/
</plain>
-The directives that work in the JavaScript files also work in stylesheets, obviously including stylesheets rather than JavaScript files. The +require_tree+ directive here works the same way as the JavaScript one, requiring all stylesheets from the current directory.
+The directives that work in the JavaScript files also work in stylesheets (though obviously including stylesheets rather than JavaScript files). The +require_tree+ directive in a CSS manifest works the same way as the JavaScript one, requiring all stylesheets from the current directory.
In this example +require_self+ is used. This puts the CSS contained within the file (if any) at the precise location of the +require_self+ call. If +require_self+ is called more than once, only the last call is respected.
-NOTE. If you want to use multiple Sass files, use the "Sass +@import+ rule":http://sass-lang.com/docs/yardoc/file.SASS_REFERENCE.html#import instead of the Sprockets directives. Using Sprockets directives all Sass files exist within their own scope, making variables or mixins only available within the document they were defined in.
+NOTE. If you want to use multiple Sass files, you should generally use the "Sass +@import+ rule":http://sass-lang.com/docs/yardoc/file.SASS_REFERENCE.html#import instead of these Sprockets directives. Using Sprockets directives all Sass files exist within their own scope, making variables or mixins only available within the document they were defined in.
You can have as many manifest files as you need. For example the +admin.css+ and +admin.js+ manifest could contain the JS and CSS files that are used for the admin section of an application.
-The same remarks about ordering made above apply. In particular, you can specify individual files and they are compiled in the order specified:
+The same remarks about ordering made above apply. In particular, you can specify individual files and they are compiled in the order specified. For example, you might concatenate three CSS files together this way:
<plain>
/* ...
@@ -253,15 +307,15 @@ h4. Preprocessing
The file extensions used on an asset determine what preprocessing is applied. When a controller or a scaffold is generated with the default Rails gemset, a CoffeeScript file and a SCSS file are generated in place of a regular JavaScript and CSS file. The example used before was a controller called "projects", which generated an +app/assets/javascripts/projects.js.coffee+ and an +app/assets/stylesheets/projects.css.scss+ file.
-When these files are requested, they are processed by the processors provided by the +coffee-script+ and +sass-rails+ gems and then sent back to the browser as JavaScript and CSS respectively.
+When these files are requested, they are processed by the processors provided by the +coffee-script+ and +sass+ gems and then sent back to the browser as JavaScript and CSS respectively.
-Additional layers of preprocessing can be requested by adding other extensions, where each extension is processed in a right-to-left manner. These should be used in the order the processing should be applied. For example, a stylesheet called +app/assets/stylesheets/projects.css.scss.erb+ is first processed as ERB, then SCSS and finally served as CSS. The same applies to a JavaScript file -- +app/assets/javascripts/projects.js.coffee.erb+ is processed as ERB, CoffeeScript, and served as JavaScript.
+Additional layers of preprocessing can be requested by adding other extensions, where each extension is processed in a right-to-left manner. These should be used in the order the processing should be applied. For example, a stylesheet called +app/assets/stylesheets/projects.css.scss.erb+ is first processed as ERB, then SCSS, and finally served as CSS. The same applies to a JavaScript file -- +app/assets/javascripts/projects.js.coffee.erb+ is processed as ERB, then CoffeeScript, and served as JavaScript.
Keep in mind that the order of these preprocessors is important. For example, if you called your JavaScript file +app/assets/javascripts/projects.js.erb.coffee+ then it would be processed with the CoffeeScript interpreter first, which wouldn't understand ERB and therefore you would run into problems.
h3. In Development
-In development mode assets are served as separate files in the order they are specified in the manifest file.
+In development mode, assets are served as separate files in the order they are specified in the manifest file.
This manifest +app/assets/javascripts/application.js+:
@@ -289,7 +343,7 @@ You can turn off debug mode by updating +config/environments/development.rb+ to
config.assets.debug = false
</ruby>
-When debug mode is off Sprockets concatenates and runs the necessary preprocessors on all files. With debug mode turned off the manifest above would generate instead:
+When debug mode is off, Sprockets concatenates and runs the necessary preprocessors on all files. With debug mode turned off the manifest above would generate instead:
<html>
<script src="/assets/application.js" type="text/javascript"></script>
@@ -312,7 +366,7 @@ You could potentially also enable compression in development mode as a sanity ch
h3. In Production
-In the production environment Rails uses the fingerprinting scheme outlined above. By default it is assumed that assets have been precompiled and will be served as static assets by your web server.
+In the production environment Rails uses the fingerprinting scheme outlined above. By default Rails assumes that assets have been precompiled and will be served as static assets by your web server.
During the precompilation phase an MD5 is generated from the contents of the compiled files, and inserted into the filenames as they are written to disc. These fingerprinted names are used by the Rails helpers in place of the manifest name.
@@ -330,7 +384,7 @@ generates something like this:
<link href="/assets/application-4dd5b109ee3439da54f5bdfd78a80473.css" media="screen" rel="stylesheet" type="text/css" />
</html>
-The fingerprinting behavior is controlled by the setting of +config.assets.digest+ setting in Rails (which is +true+ for production, +false+ for everything else).
+The fingerprinting behavior is controlled by the setting of +config.assets.digest+ setting in Rails (which defaults to +true+ for production and +false+ for everything else).
NOTE: Under normal circumstances the default option should not be changed. If there are no digests in the filenames, and far-future headers are set, remote clients will never know to refetch the files when their content changes.
@@ -338,9 +392,9 @@ h4. Precompiling Assets
Rails comes bundled with a rake task to compile the asset manifests and other files in the pipeline to the disk.
-Compiled assets are written to the location specified in +config.assets.prefix+. The default setting will use the +public/assets+ directory.
+Compiled assets are written to the location specified in +config.assets.prefix+. By default, this is the +public/assets+ directory.
-You must use this task either during deployment or locally if you do not have write access to your production filesystem.
+You can call this task on the server during deployment to create compiled versions of your assets directly on the server. If you do not have write access to your production file system, you can call this task locally and then deploy the compiled assets.
The rake task is:
@@ -357,7 +411,7 @@ test +rake assets:precompile+ locally before deploying. It may expose bugs where
your assets reference application objects or methods, since those are still
in scope in development mode regardless of the value of this flag.
-Capistrano (v2.8.0 and above) has a recipe to handle this in deployment. Add the following line to +Capfile+:
+Capistrano (v2.8.0 and above) includes a recipe to handle this in deployment. Add the following line to +Capfile+:
<erb>
load 'deploy/assets'
@@ -369,10 +423,10 @@ It is important that this folder is shared between deployments so that remotely
NOTE. If you are precompiling your assets locally, you can use +bundle install --without assets+ on the server to avoid installing the assets gems (the gems in the assets group in the Gemfile).
-The default matcher for compiling files includes +application.js+, +application.css+ and all files that do not end in +js+ or +css+:
+The default matcher for compiling files includes +application.js+, +application.css+ and all non-JS/CSS files (i.e., +.coffee+ and +.scss+ files are *not* automatically included as they compile to JS/CSS):
<ruby>
-[ /\w<plus>\.(?!js|css).<plus>/, /application.(css|js)$/ ]
+[ Proc.new{ |path| !File.extname(path).in?(['.js', '.css']) }, /application.(css|js)$/ ]
</ruby>
If you have other manifests or individual stylesheets and JavaScript files to include, you can add them to the +precompile+ array:
@@ -381,7 +435,7 @@ If you have other manifests or individual stylesheets and JavaScript files to in
config.assets.precompile += ['admin.js', 'admin.css', 'swfObject.js']
</erb>
-The rake task also generates a +manifest.yml+ that contains a list with all your assets and their respective fingerprints. This is used by the Rails helper methods and avoids handing the mapping requests back to Sprockets. A typical manifest file looks like:
+The rake task also generates a +manifest.yml+ that contains a list with all your assets and their respective fingerprints. This is used by the Rails helper methods to avoid handing the mapping requests back to Sprockets. A typical manifest file looks like:
<plain>
---
@@ -404,16 +458,12 @@ NOTE: If there are missing precompiled files in production you will get an <tt>S
h5. Server Configuration
-Precompiled assets exist on the filesystem and are served directly by your webserver. They do not have far-future headers by default, so to get the benefit of fingerprinting you'll have to update your server configuration to add them.
+Precompiled assets exist on the filesystem and are served directly by your web server. They do not have far-future headers by default, so to get the benefit of fingerprinting you'll have to update your server configuration to add them.
For Apache:
<plain>
<LocationMatch "^/assets/.*$">
- # Some browsers still send conditional-GET requests if there's a
- # Last-Modified header or an ETag header even if they haven't
- # reached the expiry date sent in the Expires header.
- Header unset Last-Modified
Header unset ETag
FileETag None
# RFC says only cache for 1 year
@@ -429,16 +479,12 @@ location ~ ^/assets/ {
expires 1y;
add_header Cache-Control public;
- # Some browsers still send conditional-GET requests if there's a
- # Last-Modified header or an ETag header even if they haven't
- # reached the expiry date sent in the Expires header.
- add_header Last-Modified "";
add_header ETag "";
break;
}
</plain>
-When files are precompiled, Sprockets also creates a "gzipped":http://en.wikipedia.org/wiki/Gzip (.gz) version of your assets. Web servers are typically configured to use a moderate compression ratio as a compromise, but since precompilation happens once Sprockets uses the maximum compression ratio, thus reducing the size of the data transfer to the minimum. On the other hand, web servers can be configured to serve compressed content directly from disk, rather than deflating non-compressed files themselves.
+When files are precompiled, Sprockets also creates a "gzipped":http://en.wikipedia.org/wiki/Gzip (.gz) version of your assets. Web servers are typically configured to use a moderate compression ratio as a compromise, but since precompilation happens once, Sprockets uses the maximum compression ratio, thus reducing the size of the data transfer to the minimum. On the other hand, web servers can be configured to serve compressed content directly from disk, rather than deflating non-compressed files themselves.
Nginx is able to do this automatically enabling +gzip_static+:
@@ -459,7 +505,7 @@ This directive is available if the core module that provides this feature was co
If you're compiling nginx with Phusion Passenger you'll need to pass that option when prompted.
-Unfortunately, a robust configuration for Apache is possible but tricky, please Google around.
+A robust configuration for Apache is possible but tricky; please Google around. (Or help update this Guide if you have a good example configuration for Apache.)
h4. Live Compilation
@@ -475,9 +521,9 @@ On the first request the assets are compiled and cached as outlined in developme
Sprockets also sets the +Cache-Control+ HTTP header to +max-age=31536000+. This signals all caches between your server and the client browser that this content (the file served) can be cached for 1 year. The effect of this is to reduce the number of requests for this asset from your server; the asset has a good chance of being in the local browser cache or some intermediate cache.
-This mode uses more memory, performs poorer than the default and is not recommended.
+This mode uses more memory, performs more poorly than the default and is not recommended.
-When deploying a production application to a system without any pre-existing JavaScript runtimes, you may want to add one to your Gemfile:
+If you are deploying a production application to a system without any pre-existing JavaScript runtimes, you may want to add one to your Gemfile:
<plain>
group :production do
@@ -501,9 +547,9 @@ The +config.assets.compress+ must be set to +true+ to enable CSS compression.
h4. JavaScript Compression
-Possible options for JavaScript compression are +:closure+, +:uglifier+ and +:yui+. These require the use of the +closure-compiler+, +uglifier+ or +yui-compressor+ gems respectively.
+Possible options for JavaScript compression are +:closure+, +:uglifier+ and +:yui+. These require the use of the +closure-compiler+, +uglifier+ or +yui-compressor+ gems, respectively.
-The default Gemfile includes "uglifier":https://github.com/lautis/uglifier. This gem wraps "UglifierJS":https://github.com/mishoo/UglifyJS (written for NodeJS) in Ruby. It compresses your code by removing white space and other magical things like changing your +if+ and +else+ statements to ternary operators where possible.
+The default Gemfile includes "uglifier":https://github.com/lautis/uglifier. This gem wraps "UglifierJS":https://github.com/mishoo/UglifyJS (written for NodeJS) in Ruby. It compresses your code by removing white space. It also includes other optimizations such as changing your +if+ and +else+ statements to ternary operators where possible.
The following line invokes +uglifier+ for JavaScript compression.
@@ -511,13 +557,13 @@ The following line invokes +uglifier+ for JavaScript compression.
config.assets.js_compressor = :uglifier
</erb>
-The +config.assets.compress+ must be set to +true+ to enable JavaScript compression
+Note that +config.assets.compress+ must be set to +true+ to enable JavaScript compression
-NOTE: You will need a "ExecJS":https://github.com/sstephenson/execjs#readme supported runtime in order to use +uglifier+. If you are using Mac OS X or Windows you have installed a JavaScript runtime in your operating system. Check "ExecJS":https://github.com/sstephenson/execjs#readme documentation to know all supported JavaScript runtimes.
+NOTE: You will need an "ExecJS":https://github.com/sstephenson/execjs#readme supported runtime in order to use +uglifier+. If you are using Mac OS X or Windows you have a JavaScript runtime installed in your operating system. Check the "ExecJS":https://github.com/sstephenson/execjs#readme documentation for information on all of the supported JavaScript runtimes.
h4. Using Your Own Compressor
-The compressor config settings for CSS and JavaScript also take any Object. This object must have a +compress+ method that takes a string as the sole argument and it must return a string.
+The compressor config settings for CSS and JavaScript also take any object. This object must have a +compress+ method that takes a string as the sole argument and it must return a string.
<erb>
class Transformer
@@ -527,7 +573,7 @@ class Transformer
end
</erb>
-To enable this, pass a +new+ Object to the config option in +application.rb+:
+To enable this, pass a +new+ object to the config option in +application.rb+:
<erb>
config.assets.css_compressor = Transformer.new
@@ -544,20 +590,20 @@ This can be changed to something else:
config.assets.prefix = "/some_other_path"
</erb>
-This is a handy option if you have any existing project (pre Rails 3.1) that already uses this path or you wish to use this path for a new resource.
+This is a handy option if you are updating an existing project (pre Rails 3.1) that already uses this path or you wish to use this path for a new resource.
h4. X-Sendfile Headers
-The X-Sendfile header is a directive to the server to ignore the response from the application, and instead serve the file specified in the headers. This option is off by default, but can be enabled if your server supports it. When enabled, this passes responsibility for serving the file to the web server, which is faster.
+The X-Sendfile header is a directive to the web server to ignore the response from the application, and instead serve a specified file from disk. This option is off by default, but can be enabled if your server supports it. When enabled, this passes responsibility for serving the file to the web server, which is faster.
-Apache and nginx support this option which is enabled in <tt>config/environments/production.rb</tt>.
+Apache and nginx support this option, which can be enabled in <tt>config/environments/production.rb</tt>.
<erb>
# config.action_dispatch.x_sendfile_header = "X-Sendfile" # for apache
# config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for nginx
</erb>
-WARNING: If you are upgrading an existing application and intend to use this option, take care to paste this configuration option only into +production.rb+ (and not +application.rb+) and any other environment you define with production behavior.
+WARNING: If you are upgrading an existing application and intend to use this option, take care to paste this configuration option only into +production.rb+ and any other environments you define with production behavior (not +application.rb+).
h3. How Caching Works
@@ -577,7 +623,7 @@ TODO: Registering gems on "Tilt":https://github.com/rtomayko/tilt enabling Sproc
h3. Upgrading from Old Versions of Rails
-There are two issues when upgrading. The first is moving the files to the new locations. See the section above for guidance on the correct locations for different file types.
+There are two issues when upgrading. The first is moving the files from +public/+ to the new locations. See "Asset Organization":#asset-organization above for guidance on the correct locations for different file types.
The second is updating the various environment files with the correct default options. The following changes reflect the defaults in version 3.1.0.
@@ -627,7 +673,7 @@ config.assets.digest = true
# config.assets.precompile += %w( search.js )
</erb>
-There are no changes to +test.rb+. The defaults in the test environment are: +config.assets.compile+ is true and +config.assets.compress+, +config.assets.debug+ and +config.assets.digest+ are false.
+You should not need to change +test.rb+. The defaults in the test environment are: +config.assets.compile+ is true and +config.assets.compress+, +config.assets.debug+ and +config.assets.digest+ are false.
The following should also be added to +Gemfile+:
@@ -641,7 +687,7 @@ group :assets do
end
</plain>
-If you use the +assets+ group with Bundler, please make sure that your +config/application.rb+ has the following Bundler require statement.
+If you use the +assets+ group with Bundler, please make sure that your +config/application.rb+ has the following Bundler require statement:
<ruby>
if defined?(Bundler)
@@ -652,7 +698,7 @@ if defined?(Bundler)
end
</ruby>
-Instead of the old Rails 3.0 one
+Instead of the old Rails 3.0 version:
<ruby>
# If you have a Gemfile, require the gems listed there, including any gems
diff --git a/railties/guides/source/association_basics.textile b/railties/guides/source/association_basics.textile
index 6829eb8ef4..a55ed38d1b 100644
--- a/railties/guides/source/association_basics.textile
+++ b/railties/guides/source/association_basics.textile
@@ -1120,7 +1120,7 @@ h6(#has_many-collection-find). <tt><em>collection</em>.find(...)</tt>
The <tt><em>collection</em>.find</tt> method finds objects within the collection. It uses the same syntax and options as +ActiveRecord::Base.find+.
<ruby>
-@open_orders = @customer.orders.where(:open => 1)
+@open_orders = @customer.orders.find(1)
</ruby>
h6(#has_many-collection-where). <tt><em>collection</em>.where(...)</tt>
@@ -1234,7 +1234,7 @@ If you need to evaluate conditions dynamically at runtime, use a proc:
<ruby>
class Customer < ActiveRecord::Base
has_many :latest_orders, :class_name => "Order",
- :conditions => proc { "orders.created_at > #{10.hours.ago.to_s(:db).inspect}" }
+ :conditions => proc { ["orders.created_at > ?, 10.hours.ago] }
end
</ruby>
@@ -1242,7 +1242,7 @@ h6(#has_many-counter_sql). +: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.
-NOTE: If you specify +:finder_sql+ but not +:counter_sql+, then the counter SQL will be generated by substituting +SELECT COUNT(*) FROM+ for the +SELECT ... FROM+ clause of your +:finder_sql+ statement.
+NOTE: If you specify +:finder_sql+ but not +:counter_sql+, then the counter SQL will be generated by substituting the +SELECT ... FROM+ clause of your +:finder_sql+ statement by +SELECT COUNT(*) FROM+.
h6(#has_many-dependent). +:dependent+
@@ -1545,12 +1545,9 @@ h6(#has_and_belongs_to_many-collection-find). <tt><em>collection</em>.find(...)<
The <tt><em>collection</em>.find</tt> method finds objects within the collection. It uses the same syntax and options as +ActiveRecord::Base.find+. It also adds the additional condition that the object must be in the collection.
<ruby>
-@new_assemblies = @part.assemblies.all(
- :conditions => ["created_at > ?", 2.days.ago])
+@assembly = @part.assemblies.find(1)
</ruby>
-NOTE: Beginning with Rails 3, supplying options to the +ActiveRecord::Base.find+ method is discouraged. Use <tt><em>collection</em>.where</tt> instead when you need to pass conditions.
-
h6(#has_and_belongs_to_many-collection-where). <tt><em>collection</em>.where(...)</tt>
The <tt><em>collection</em>.where</tt> method finds objects within the collection based on the conditions supplied but the objects are loaded lazily meaning that the database is queried only when the object(s) are accessed. It also adds the additional condition that the object must be in the collection.
@@ -1669,7 +1666,7 @@ h6(#has_and_belongs_to_many-counter_sql). +: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.
-NOTE: If you specify +:finder_sql+ but not +:counter_sql+, then the counter SQL will be generated by substituting +SELECT COUNT(*) FROM+ for the +SELECT ... FROM+ clause of your +:finder_sql+ statement.
+NOTE: If you specify +:finder_sql+ but not +:counter_sql+, then the counter SQL will be generated by substituting the +SELECT ... FROM+ clause of your +:finder_sql+ statement by +SELECT COUNT(*) FROM+.
h6(#has_and_belongs_to_many-delete_sql). +:delete_sql+
diff --git a/railties/guides/source/caching_with_rails.textile b/railties/guides/source/caching_with_rails.textile
index 4273d0dd64..6419d32c13 100644
--- a/railties/guides/source/caching_with_rails.textile
+++ b/railties/guides/source/caching_with_rails.textile
@@ -64,7 +64,29 @@ end
If you want a more complicated expiration scheme, you can use cache sweepers to expire cached objects when things change. This is covered in the section on Sweepers.
-NOTE: Page caching ignores all parameters. For example +/products?page=1+ will be written out to the filesystem as +products.html+ with no reference to the +page+ parameter. Thus, if someone requests +/products?page=2+ later, they will get the cached first page. Be careful when page caching GET parameters in the URL!
+By default, page caching automatically gzips files (for example, to +products.html.gz+ if user requests +/products+) to reduce the size of data transmitted (web servers are typically configured to use a moderate compression ratio as a compromise, but since precompilation happens once, compression ratio is maximum).
+
+Nginx is able to serve compressed content directly from disk by enabling +gzip_static+:
+
+<plain>
+location / {
+ gzip_static on; # to serve pre-gzipped version
+}
+</plain>
+
+You can disable gzipping by setting +:gzip+ option to false (for example, if action returns image):
+
+<ruby>
+caches_page :image, :gzip => false
+</ruby>
+
+Or, you can set custom gzip compression level (level names are taken from +Zlib+ constants):
+
+<ruby>
+caches_page :image, :gzip => :best_speed
+</ruby>
+
+NOTE: Page caching ignores all parameters. For example +/products?page=1+ will be written out to the filesystem as +products.html+ with no reference to the +page+ parameter. Thus, if someone requests +/products?page=2+ later, they will get the cached first page. A workaround for this limitation is to include the parameters in the page's path, e.g. +/productions/page/1+.
INFO: Page caching runs in an after filter. Thus, invalid requests won't generate spurious cache entries as long as you halt them. Typically, a redirection in some before filter that checks request preconditions does the job.
@@ -72,7 +94,7 @@ h4. Action Caching
One of the issues with Page Caching is that you cannot use it for pages that require to restrict access somehow. This is where Action Caching comes in. Action Caching works like Page Caching except for the fact that the incoming web request does go from the webserver to the Rails stack and Action Pack so that before filters can be run on it before the cache is served. This allows authentication and other restriction to be run while still serving the result of the output from a cached copy.
-Clearing the cache works in the exact same way as with Page Caching.
+Clearing the cache works in a similar way to Page Caching, except you use +expire_action+ instead of +expire_page+.
Let's say you only wanted authenticated users to call actions on +ProductsController+.
@@ -293,7 +315,7 @@ Note that the cache will grow until the disk is full unless you periodically cle
h4. ActiveSupport::Cache::MemCacheStore
-This cache store uses Danga's +memcached+ server to provide a centralized cache for your application. Rails uses the bundled +memcached-client+ gem by default. This is currently the most popular cache store for production websites. It can be used to provide a single, shared cache cluster with very a high performance and redundancy.
+This cache store uses Danga's +memcached+ server to provide a centralized cache for your application. Rails uses the bundled +memcache-client+ gem by default. This is currently the most popular cache store for production websites. It can be used to provide a single, shared cache cluster with very a high performance and redundancy.
When initializing the cache, you need to specify the addresses for all memcached servers in your cluster. If none is specified, it will assume memcached is running on the local host on the default port, but this is not an ideal set up for larger sites.
@@ -332,6 +354,14 @@ caches_action :index, :expires_in => 60.seconds, :unless_exist => true
For more information about Ehcache, see "http://ehcache.org/":http://ehcache.org/ .
For more information about Ehcache for JRuby and Rails, see "http://ehcache.org/documentation/jruby.html":http://ehcache.org/documentation/jruby.html
+h4. ActiveSupport::Cache::NullStore
+
+This cache store implementation is meant to be used only in development or test environments and it never stores anything. This can be very useful in development when you have code that interacts directly with +Rails.cache+, but caching may interfere with being able to see the results of code changes. With this cache store, all +fetch+ and +read+ operations will result in a miss.
+
+<ruby>
+ActionController::Base.cache_store = :null
+</ruby>
+
h4. Custom Cache Stores
You can create your own custom cache store by simply extending +ActiveSupport::Cache::Store+ and implementing the appropriate methods. In this way, you can swap in any number of caching technologies into your Rails application.
diff --git a/railties/guides/source/command_line.textile b/railties/guides/source/command_line.textile
index 3f8643eca3..fe4a84dae9 100644
--- a/railties/guides/source/command_line.textile
+++ b/railties/guides/source/command_line.textile
@@ -36,7 +36,7 @@ WARNING: You can install the rails gem by typing +gem install rails+, if you don
<shell>
$ rails new commandsapp
create
- create README
+ create README.rdoc
create .gitignore
create Rakefile
create config.ru
@@ -45,8 +45,6 @@ $ rails new commandsapp
...
create tmp/cache
create tmp/pids
- create vendor/plugins
- create vendor/plugins/.gitkeep
</shell>
Rails will set you up with what seems like a huge amount of stuff for such a tiny command! You've got the entire Rails directory structure now with all the code you need to run our simple application right out of the box.
@@ -81,6 +79,8 @@ The server can be run on a different port using the +-p+ option. The default dev
$ rails server -e production -p 4000
</shell>
+The +-b+ option binds Rails to the specified ip, by default it is 0.0.0.0. You can run a server as a daemon by passing a +-d+ option.
+
h4. +rails generate+
The +rails generate+ command uses templates to create a whole lot of things. Running +rails generate+ by itself gives a list of available generators:
@@ -293,18 +293,6 @@ h4. +rails dbconsole+
You can also use the alias "db" to invoke the dbconsole: <tt>rails db</tt>.
-h4. +rails plugin+
-
-The +rails plugin+ command simplifies plugin management. Plugins can be installed by name or their repository URLs. You need to have Git installed if you want to install a plugin from a Git repo. The same holds for Subversion too.
-
-<shell>
-$ rails plugin install https://github.com/technoweenie/acts_as_paranoid.git
-+ ./CHANGELOG
-+ ./MIT-LICENSE
-...
-...
-</shell>
-
h4. +rails runner+
<tt>runner</tt> runs Ruby code in the context of Rails non-interactively. For instance:
@@ -379,17 +367,17 @@ h4. +about+
<shell>
$ rake about
About your application's environment
-Ruby version 1.8.7 (x86_64-linux)
+Ruby version 1.9.3 (x86_64-linux)
RubyGems version 1.3.6
Rack version 1.3
-Rails version 3.2.0.beta
+Rails version 4.0.0.beta
JavaScript Runtime Node.js (V8)
-Active Record version 3.2.0.beta
-Action Pack version 3.2.0.beta
-Active Resource version 3.2.0.beta
-Action Mailer version 3.2.0.beta
-Active Support version 3.2.0.beta
-Middleware ActionDispatch::Static, Rack::Lock, Rack::Runtime, Rack::MethodOverride, ActionDispatch::RequestId, Rails::Rack::Logger, ActionDispatch::ShowExceptions, ActionDispatch::RemoteIp, ActionDispatch::Reloader, ActionDispatch::Callbacks, ActiveRecord::ConnectionAdapters::ConnectionManagement, ActiveRecord::QueryCache, ActionDispatch::Cookies, ActionDispatch::Session::CookieStore, ActionDispatch::Flash, ActionDispatch::ParamsParser, ActionDispatch::Head, Rack::ConditionalGet, Rack::ETag, ActionDispatch::BestStandardsSupport
+Active Record version 4.0.0.beta
+Action Pack version 4.0.0.beta
+Active Resource version 4.0.0.beta
+Action Mailer version 4.0.0.beta
+Active Support version 4.0.0.beta
+Middleware ActionDispatch::Static, Rack::Lock, Rack::Runtime, Rack::MethodOverride, ActionDispatch::RequestId, Rails::Rack::Logger, ActionDispatch::ShowExceptions, ActionDispatch::DebugExceptions, ActionDispatch::RemoteIp, ActionDispatch::Reloader, ActionDispatch::Callbacks, ActiveRecord::ConnectionAdapters::ConnectionManagement, ActiveRecord::QueryCache, ActionDispatch::Cookies, ActionDispatch::Session::CookieStore, ActionDispatch::Flash, ActionDispatch::ParamsParser, ActionDispatch::Head, Rack::ConditionalGet, Rack::ETag, ActionDispatch::BestStandardsSupport
Application root /home/foobar/commandsapp
Environment development
Database adapter sqlite3
@@ -413,12 +401,10 @@ The +doc:+ namespace has the tools to generate documentation for your app, API d
* +rake doc:app+ generates documentation for your application in +doc/app+.
* +rake doc:guides+ generates Rails guides in +doc/guides+.
* +rake doc:rails+ generates API documentation for Rails in +doc/api+.
-* +rake doc:plugins+ generates API documentation for all the plugins installed in the application in +doc/plugins+.
-* +rake doc:clobber_plugins+ removes the generated documentation for all plugins.
h4. +notes+
-+rake notes+ will search through your code for comments beginning with FIXME, OPTIMIZE or TODO. The search is only done in files with extension +.builder+, +.rb+, +.rxml+, +.rhtml+ and +.erb+ for both default and custom annotations.
++rake notes+ will search through your code for comments beginning with FIXME, OPTIMIZE or TODO. The search is done in files with extension +.builder+, +.rb+, +.erb+, +.haml+ and +.slim+ for both default and custom annotations.
<shell>
$ rake notes
@@ -507,8 +493,8 @@ $ rails new . --git --database=postgresql
create tmp/pids
create Rakefile
add 'Rakefile'
- create README
-add 'README'
+ create README.rdoc
+add 'README.rdoc'
create app/controllers/application_controller.rb
add 'app/controllers/application_controller.rb'
create app/helpers/application_helper.rb
diff --git a/railties/guides/source/configuring.textile b/railties/guides/source/configuring.textile
index bb494fbd33..451235d41d 100644
--- a/railties/guides/source/configuring.textile
+++ b/railties/guides/source/configuring.textile
@@ -40,7 +40,9 @@ Rails will use that particular setting to configure Active Record.
h4. Rails General Configuration
-* +config.after_initialize+ takes a block which will be run _after_ Rails has finished initializing the application. That includes the initialization of the framework itself, plugins, engines, and all the application's initializers in +config/initializers+. Note that this block _will_ be run for rake tasks. Useful for configuring values set up by other initializers:
+These configuration methods are to be called on a +Rails::Railtie+ object, such as a subclass of +Rails::Engine+ or +Rails::Application+.
+
+* +config.after_initialize+ takes a block which will be run _after_ Rails has finished initializing the application. That includes the initialization of the framework itself, engines, and all the application's initializers in +config/initializers+. Note that this block _will_ be run for rake tasks. Useful for configuring values set up by other initializers:
<ruby>
config.after_initialize do
@@ -80,21 +82,25 @@ NOTE. The +config.asset_path+ configuration is ignored if the asset pipeline is
* +config.encoding+ sets up the application-wide encoding. Defaults to UTF-8.
+* +config.exceptions_app+ sets the exceptions application invoked by the ShowException middleware when an exception happens. Defaults to +ActionDispatch::PublicExceptions.new(Rails.public_path)+.
+
+* +config.file_watcher+ the class used to detect file updates in the filesystem when +config.reload_classes_only_on_change+ is true. Must conform to +ActiveSupport::FileUpdateChecker+ API.
+
* +config.filter_parameters+ used for filtering out the parameters that you don't want shown in the logs, such as passwords or credit card numbers.
* +config.force_ssl+ forces all requests to be under HTTPS protocol by using +Rack::SSL+ middleware.
* +config.log_level+ defines the verbosity of the Rails logger. This option defaults to +:debug+ for all modes except production, where it defaults to +:info+.
+* +config.log_tags+ accepts a list of methods that respond to +request+ object. This makes it easy to tag log lines with debug information like subdomain and request id -- both very helpful in debugging multi-user production applications.
+
* +config.logger+ accepts a logger conforming to the interface of Log4r or the default Ruby +Logger+ class. Defaults to an instance of +ActiveSupport::BufferedLogger+, with auto flushing off in production mode.
* +config.middleware+ allows you to configure the application's middleware. This is covered in depth in the "Configuring Middleware":#configuring-middleware section below.
-* +config.plugins+ accepts the list of plugins to load. The default is +nil+ in which case all plugins will be loaded. If this is set to +[]+, no plugins will be loaded. Otherwise, plugins will be loaded in the order specified. This option lets you enforce some particular loading order, useful when dependencies between plugins require it. For that use case, put first the plugins you want to be loaded in a certain order, and then the special symbol +:all+ to have the rest loaded without the need to specify them.
-
* +config.preload_frameworks+ enables or disables preloading all frameworks at startup. Enabled by +config.threadsafe!+. Defaults to +nil+, so is disabled.
-* +config.reload_plugins+ enables or disables plugin reloading. Defaults to false.
+* +config.reload_classes_only_on_change+ enables or disables reloading of classes only when tracked files change. By default tracks everything on autoload paths and is set to true. If +config.cache_classes+ is true, this option is ignored.
* +config.secret_token+ used for specifying a key which allows sessions for the application to be verified against a known secure key to prevent tampering. Applications get +config.secret_token+ initialized to a random key in +config/initializers/secret_token.rb+.
@@ -116,6 +122,17 @@ WARNING: Threadsafe operation is incompatible with the normal workings of develo
* +config.whiny_nils+ enables or disables warnings when a certain set of methods are invoked on +nil+ and it does not respond to them. Defaults to true in development and test environments.
+* +config.console+ allows you to set class that will be used as console you run +rails console+. It's best to run it in +console+ block:
+
+<ruby>
+console do
+ # this block is called only when running console,
+ # so we can safely require pry here
+ require "pry"
+ config.console = Pry
+end
+</ruby>
+
h4. Configuring Assets
Rails 3.1, by default, is set up to use the +sprockets+ gem to manage assets within an application. This gem concatenates and compresses assets in order to make serving them much less painful.
@@ -146,6 +163,7 @@ Rails 3.1, by default, is set up to use the +sprockets+ gem to manage assets wit
* +config.assets.compile+ is a boolean that can be used to turn on live Sprockets compilation in production.
+* +config.assets.logger+ accepts a logger conforming to the interface of Log4r or the default Ruby +Logger+ class. Defaults to the same configured at +config.logger+. Setting +config.assets.logger+ to false will turn off served assets logging.
h4. Configuring Generators
@@ -186,6 +204,7 @@ Every Rails application comes with a standard set of middleware which it uses in
* +Rack::Runtime+ sets an +X-Runtime+ header, containing the time (in seconds) taken to execute the request.
* +Rails::Rack::Logger+ notifies the logs that the request has began. After request is complete, flushes all the logs.
* +ActionDispatch::ShowExceptions+ rescues any exception returned by the application and renders nice exception pages if the request is local or if +config.consider_all_requests_local+ is set to +true+. If +config.action_dispatch.show_exceptions+ is set to +false+, exceptions will be raised regardless.
+* +ActionDispatch::RequestId+ makes a unique X-Request-Id header available to the response and enables the +ActionDispatch::Request#uuid+ method.
* +ActionDispatch::RemoteIp+ checks for IP spoofing attacks. Configurable with the +config.action_dispatch.ip_spoofing_check+ and +config.action_dispatch.trusted_proxies+ settings.
* +Rack::Sendfile+ intercepts responses whose body is being served from a file and replaces it with a server specific X-Sendfile header. Configurable with +config.action_dispatch.x_sendfile_header+.
* +ActionDispatch::Callbacks+ runs the prepare callbacks before serving the request.
@@ -261,6 +280,12 @@ h4. Configuring Active Record
* +config.active_record.whitelist_attributes+ will create an empty whitelist of attributes available for mass-assignment security for all models in your app.
+* +config.active_record.identity_map+ controls whether the identity map is enabled, and is false by default.
+
+* +config.active_record.auto_explain_threshold_in_seconds+ configures the threshold for automatic EXPLAINs (+nil+ disables this feature). Queries exceeding the threshold get their query plan logged. Default is 0.5 in development mode.
+
+* +config.active_record.dependent_restrict_raises+ will control the behavior when an object with a <tt>:dependent => :restrict</tt> association is deleted. Setting this to false will prevent +DeleteRestrictionError+ from being raised and instead will add an error on the model object. Defaults to false in the development mode.
+
The MySQL adapter adds one additional configuration option:
* +ActiveRecord::ConnectionAdapters::MysqlAdapter.emulate_booleans+ controls whether Active Record will consider all +tinyint(1)+ columns in a MySQL database to be booleans and is true by default.
@@ -331,7 +356,7 @@ Proc.new { |html_tag, instance| %Q(<div class="field_with_errors">#{html_tag}</d
* +config.action_view.default_form_builder+ tells Rails which form builder to use by default. The default is +ActionView::Helpers::FormBuilder+.
-* +config.action_view.logger+ accepts a logger conforming to the interface of Log4r or the default Ruby Logger class, which is then used to log information from Action Mailer. Set to +nil+ to disable logging.
+* +config.action_view.logger+ accepts a logger conforming to the interface of Log4r or the default Ruby Logger class, which is then used to log information from Action View. Set to +nil+ to disable logging.
* +config.action_view.erb_trim_mode+ gives the trim mode to be used by ERB. It defaults to +'-'+. See the "ERB documentation":http://www.ruby-doc.org/stdlib/libdoc/erb/rdoc/ for more information.
@@ -447,7 +472,7 @@ Some parts of Rails can also be configured externally by supplying environment v
h3. Using Initializer Files
-After loading the framework and any gems and plugins in your application, Rails turns to loading initializers. An initializer is any Ruby file stored under +config/initializers+ in your application. You can use initializers to hold configuration settings that should be made after all of the frameworks, plugins and gems are loaded, such as options to configure settings for these parts.
+After loading the framework and any gems in your application, Rails turns to loading initializers. An initializer is any Ruby file stored under +config/initializers+ in your application. You can use initializers to hold configuration settings that should be made after all of the frameworks and gems are loaded, such as options to configure settings for these parts.
NOTE: You can use subfolders to organize your initializers if you like, because Rails will look into the whole file hierarchy from the initializers folder on down.
@@ -522,7 +547,7 @@ Serves as a placeholder so that +:load_environment_config+ can be defined to run
*+initialize_logger+* Initializes the logger (an +ActiveSupport::BufferedLogger+ object) for the application and makes it accessible at +Rails.logger+, provided that no initializer inserted before this point has defined +Rails.logger+.
-*+initialize_cache+* If +RAILS_CACHE+ isn't set yet, initializes the cache by referencing the value in +config.cache_store+ and stores the outcome as +RAILS_CACHE+. If this object responds to the +middleware+ method, its middleware is inserted before +Rack::Runtime+ in the middleware stack.
+*+initialize_cache+* If +Rails.cache+ isn't set yet, initializes the cache by referencing the value in +config.cache_store+ and stores the outcome as +Rails.cache+. If this object responds to the +middleware+ method, its middleware is inserted before +Rack::Runtime+ in the middleware stack.
*+set_clear_dependencies_hook+* Provides a hook for +active_record.set_dispatch_hooks+ to use, which will run before this initializer. This initializer -- which runs only if +cache_classes+ is set to +false+ -- uses +ActionDispatch::Callbacks.after+ to remove the constants which have been referenced during the request from the object space so that they will be reloaded during the following request.
@@ -560,7 +585,7 @@ The error occurred while evaluating nil.each
*+action_controller.logger+* Sets +ActionController::Base.logger+ -- if it's not already set -- to +Rails.logger+.
-*+action_controller.initialize_framework_caches+* Sets +ActionController::Base.cache_store+ -- if it's not already set -- to +RAILS_CACHE+.
+*+action_controller.initialize_framework_caches+* Sets +ActionController::Base.cache_store+ -- if it's not already set -- to +Rails.cache+.
*+action_controller.set_configs+* Sets up Action Controller by using the settings in +config.action_controller+ by +send+'ing the method names as setters to +ActionController::Base+ and passing the values through.
@@ -602,7 +627,7 @@ The error occurred while evaluating nil.each
*+prepend_helpers_path+* Adds the directory +app/helpers+ from the application, railties and engines to the lookup path for helpers for the application.
-*+load_config_initializers+* Loads all Ruby files from +config/initializers+ in the application, railties and engines. The files in this directory can be used to hold configuration settings that should be made after all of the frameworks and plugins are loaded.
+*+load_config_initializers+* Loads all Ruby files from +config/initializers+ in the application, railties and engines. The files in this directory can be used to hold configuration settings that should be made after all of the frameworks are loaded.
*+engines_blank_point+* Provides a point-in-initialization to hook into if you wish to do anything before engines are loaded. After this point, all railtie and engine initializers are ran.
diff --git a/railties/guides/source/contributing_to_ruby_on_rails.textile b/railties/guides/source/contributing_to_ruby_on_rails.textile
index 5848172510..aac5e13978 100644
--- a/railties/guides/source/contributing_to_ruby_on_rails.textile
+++ b/railties/guides/source/contributing_to_ruby_on_rails.textile
@@ -87,21 +87,21 @@ $ bundle install --without db
This command will install all dependencies except the MySQL and PostgreSQL Ruby drivers. We will come back at these soon. With dependencies installed, you can run the test suite with:
<shell>
-$ rake test
+$ bundle exec rake test
</shell>
You can also run tests for a specific framework, like Action Pack, by going into its directory and executing the same command:
<shell>
$ cd actionpack
-$ rake test
+$ bundle exec rake test
</shell>
If you want to run tests from the specific directory use the +TEST_DIR+ environment variable. For example, this will run tests inside +railties/test/generators+ directory only:
<shell>
$ cd railties
-$ TEST_DIR=generators rake test
+$ TEST_DIR=generators bundle exec rake test
</shell>
h4. Warnings
@@ -111,7 +111,7 @@ The test suite runs with warnings enabled. Ideally Ruby on Rails should issue no
As of this writing they are specially noisy with Ruby 1.9. If you are sure about what you are doing and would like to have a more clear output, there's a way to override the flag:
<shell>
-$ RUBYOPT=-W0 rake test
+$ RUBYOPT=-W0 bundle exec rake test
</shell>
h4. Testing Active Record
@@ -130,7 +130,7 @@ The gem +sqlite3-ruby+ does not belong to the "db" group indeed, if you followed
<shell>
$ cd activerecord
-$ rake test_sqlite3
+$ bundle exec rake test_sqlite3
</shell>
h5. MySQL and PostgreSQL
@@ -195,12 +195,12 @@ test_postgresql
respectively. As we mentioned before
<shell>
-$ rake test
+$ bundle exec rake test
</shell>
will now run the four of them in turn.
-You can also invoke +test_jdbcmysql+, +test_jdbcsqlite3+ or +test_jdbcpostgresql+. Check out the file +activerecord/RUNNING_UNIT_TESTS+ for information on running more targeted database tests, or the file +ci/ci_build.rb+ to see the test suite that the continuous integration server runs.
+You can also invoke +test_jdbcmysql+, +test_jdbcsqlite3+ or +test_jdbcpostgresql+. Check out the file +activerecord/RUNNING_UNIT_TESTS+ for information on running more targeted database tests, or the file +ci/travis.rb+ to see the test suite that the continuous integration server runs.
h4. Older versions of Ruby on Rails
@@ -215,7 +215,7 @@ TIP: You may want to "put your git branch name in your shell prompt":http://qugs
h3. Helping to Resolve Existing Issues
-As a next step beyond reporting issues, you can help the core team resolve existing issues. If you check the "Everyone's Issues":https://github.com/rails/rails/issues?sort=created&direction=desc&state=open&page=1 list in GitHub Issues, you'll find lots of issues already requiring attention. What can you do for these? Quite a bit, actually:
+As a next step beyond reporting issues, you can help the core team resolve existing issues. If you check the "Everyone's Issues":https://github.com/rails/rails/issues list in GitHub Issues, you'll find lots of issues already requiring attention. What can you do for these? Quite a bit, actually:
h4. Verifying Bug Reports
@@ -271,6 +271,8 @@ When working with documentation, please take into account the "API Documentation
NOTE: As explained earlier, ordinary code patches should have proper documentation coverage. docrails is only used for isolated documentation improvements.
+NOTE: To help our CI servers you can add [ci skip] tag to your documentation commit message to skip build on that commit. Please remember to use it for commits containing only documentation changes.
+
WARNING: docrails has a very strict policy: no code can be touched whatsoever, no matter how trivial or small the change. Only RDoc and guides can be edited via docrails. Also, CHANGELOGs should never be edited in docrails.
h3. Contributing to the Rails Code
@@ -307,7 +309,7 @@ Rails follows a simple set of coding style conventions.
* Two spaces, no tabs.
* No trailing whitespace. Blank lines should not have any space.
-* Indent after private/protected.
+* Outdent private/protected from method definitions. Same indentation as the class/module.
* Prefer +&amp;&amp;+/+||+ over +and+/+or+.
* Prefer class << self block over self.method for class methods.
* +MyClass.my_method(my_arg)+ not +my_method( my_arg )+ or +my_method my_arg+.
@@ -336,7 +338,7 @@ It’s pretty likely that other changes to master have happened while you were w
<shell>
$ git checkout master
-$ git pull
+$ git pull --rebase
</shell>
Now reapply your patch on top of the latest changes:
@@ -380,9 +382,9 @@ Now you need to get other people to look at your patch, just as you've looked at
h4. Iterate as Necessary
-It’s entirely possible that the feedback you get will suggest changes. Don’t get discouraged: the whole point of contributing to an active open source project is to tap into community knowledge. If people are encouraging you to tweak your code, then it’s worth making the tweaks and resubmitting. If the feedback is that your code doesn’t belong in the core, you might still think about releasing it as a plugin.
+It’s entirely possible that the feedback you get will suggest changes. Don’t get discouraged: the whole point of contributing to an active open source project is to tap into community knowledge. If people are encouraging you to tweak your code, then it’s worth making the tweaks and resubmitting. If the feedback is that your code doesn’t belong in the core, you might still think about releasing it as a gem.
-And then...think about your next contribution!
+And then ... think about your next contribution!
h3. Rails Contributors
diff --git a/railties/guides/source/debugging_rails_applications.textile b/railties/guides/source/debugging_rails_applications.textile
index 3552c68418..57c7786636 100644
--- a/railties/guides/source/debugging_rails_applications.textile
+++ b/railties/guides/source/debugging_rails_applications.textile
@@ -465,7 +465,7 @@ Now you should know where you are in the running trace and be able to print the
Use +step+ (abbreviated +s+) to continue running your program until the next logical stopping point and return control to ruby-debug.
-TIP: You can also use +step+ _n_+ and +step- _n_+ to move forward or backward _n_ steps respectively.
+TIP: You can also use <tt>step<plus> n</tt> and <tt>step- n</tt> to move forward or backward +n+ steps respectively.
You may also use +next+ which is similar to step, but function or method calls that appear within the line of code are executed without stopping. As with step, you may use plus sign to move _n_ steps.
diff --git a/railties/guides/source/documents.yaml b/railties/guides/source/documents.yaml
new file mode 100644
index 0000000000..6a47959c3d
--- /dev/null
+++ b/railties/guides/source/documents.yaml
@@ -0,0 +1,157 @@
+-
+ name: Start Here
+ documents:
+ -
+ name: Getting Started with Rails
+ url: getting_started.html
+ description: Everything you need to know to install Rails and create your first application.
+-
+ name: Models
+ documents:
+ -
+ name: Rails Database Migrations
+ url: migrations.html
+ description: This guide covers how you can use Active Record migrations to alter your database in a structured and organized manner.
+ -
+ name: Active Record Validations and Callbacks
+ url: active_record_validations_callbacks.html
+ description: This guide covers how you can use Active Record validations and callbacks.
+ -
+ name: Active Record Associations
+ url: association_basics.html
+ description: This guide covers all the associations provided by Active Record.
+ -
+ name: Active Record Query Interface
+ url: active_record_querying.html
+ description: This guide covers the database query interface provided by Active Record.
+-
+ name: Views
+ documents:
+ -
+ name: Layouts and Rendering in Rails
+ url: layouts_and_rendering.html
+ description: This guide covers the basic layout features of Action Controller and Action View, including rendering and redirecting, using content_for blocks, and working with partials.
+ -
+ name: Action View Form Helpers
+ url: form_helpers.html
+ description: Guide to using built-in Form helpers.
+-
+ name: Controllers
+ documents:
+ -
+ name: Action Controller Overview
+ url: action_controller_overview.html
+ description: This guide covers how controllers work and how they fit into the request cycle in your application. It includes sessions, filters, and cookies, data streaming, and dealing with exceptions raised by a request, among other topics.
+ -
+ name: Rails Routing from the Outside In
+ url: routing.html
+ description: This guide covers the user-facing features of Rails routing. If you want to understand how to use routing in your own Rails applications, start here.
+-
+ name: Digging Deeper
+ documents:
+ -
+ name: Active Support Core Extensions
+ url: active_support_core_extensions.html
+ description: This guide documents the Ruby core extensions defined in Active Support.
+ -
+ name: Rails Internationalization API
+ url: i18n.html
+ description: This guide covers how to add internationalization to your applications. Your application will be able to translate content to different languages, change pluralization rules, use correct date formats for each country and so on.
+ -
+ name: Action Mailer Basics
+ url: action_mailer_basics.html
+ work_in_progress: true
+ description: This guide describes how to use Action Mailer to send and receive emails.
+ -
+ name: Testing Rails Applications
+ url: testing.html
+ work_in_progress: true
+ description: This is a rather comprehensive guide to doing both unit and functional tests in Rails. It covers everything from 'What is a test?' to the testing APIs. Enjoy.
+ -
+ name: Securing Rails Applications
+ url: security.html
+ description: This guide describes common security problems in web applications and how to avoid them with Rails.
+ -
+ name: Debugging Rails Applications
+ url: debugging_rails_applications.html
+ description: This guide describes how to debug Rails applications. It covers the different ways of achieving this and how to understand what is happening "behind the scenes" of your code.
+ -
+ name: Performance Testing Rails Applications
+ url: performance_testing.html
+ description: This guide covers the various ways of performance testing a Ruby on Rails application.
+ -
+ name: Configuring Rails Applications
+ url: configuring.html
+ description: This guide covers the basic configuration settings for a Rails application.
+ -
+ name: Rails Command Line Tools and Rake Tasks
+ url: command_line.html
+ description: This guide covers the command line tools and rake tasks provided by Rails.
+ -
+ name: Caching with Rails
+ work_in_progress: true
+ url: caching_with_rails.html
+ description: Various caching techniques provided by Rails.
+ -
+ name: Asset Pipeline
+ url: asset_pipeline.html
+ description: This guide documents the asset pipeline.
+ -
+ name: The Rails Initialization Process
+ work_in_progress: true
+ url: initialization.html
+ description: This guide explains the internals of the Rails initialization process as of Rails 3.1
+-
+ name: Extending Rails
+ documents:
+ -
+ name: The Basics of Creating Rails Plugins
+ work_in_progress: true
+ url: plugins.html
+ description: This guide covers how to build a plugin to extend the functionality of Rails.
+ -
+ name: Rails on Rack
+ url: rails_on_rack.html
+ description: This guide covers Rails integration with Rack and interfacing with other Rack components.
+ -
+ name: Creating and Customizing Rails Generators
+ url: generators.html
+ description: This guide covers the process of adding a brand new generator to your extension or providing an alternative to an element of a built-in Rails generator (such as providing alternative test stubs for the scaffold generator).
+-
+ name: Contributing to Ruby on Rails
+ documents:
+ -
+ name: Contributing to Ruby on Rails
+ url: contributing_to_ruby_on_rails.html
+ description: Rails is not 'somebody else's framework.' This guide covers a variety of ways that you can get involved in the ongoing development of Rails.
+ -
+ name: API Documentation Guidelines
+ url: api_documentation_guidelines.html
+ description: This guide documents the Ruby on Rails API documentation guidelines.
+ -
+ name: Ruby on Rails Guides Guidelines
+ url: ruby_on_rails_guides_guidelines.html
+ description: This guide documents the Ruby on Rails guides guidelines.
+-
+ name: Release Notes
+ documents:
+ -
+ name: Ruby on Rails 3.2 Release Notes
+ url: 3_2_release_notes.html
+ description: Release notes for Rails 3.2.
+ -
+ name: Ruby on Rails 3.1 Release Notes
+ url: 3_1_release_notes.html
+ description: Release notes for Rails 3.1.
+ -
+ name: Ruby on Rails 3.0 Release Notes
+ url: 3_0_release_notes.html
+ description: Release notes for Rails 3.0.
+ -
+ name: Ruby on Rails 2.3 Release Notes
+ url: 2_3_release_notes.html
+ description: Release notes for Rails 2.3.
+ -
+ name: Ruby on Rails 2.2 Release Notes
+ url: 2_2_release_notes.html
+ description: Release notes for Rails 2.2.
diff --git a/railties/guides/source/engines.textile b/railties/guides/source/engines.textile
index da56f3d0ed..694b36bea1 100644
--- a/railties/guides/source/engines.textile
+++ b/railties/guides/source/engines.textile
@@ -506,6 +506,10 @@ Now instead of the ugly Ruby object output the author's name will be displayed.
h4. Configuring an engine
+This section covers firstly how you can make the +user_class+ setting of the Blorgh engine configurable, followed by general configuration tips for the engine.
+
+h5. Setting configuration settings in the application
+
The next step is to make the class that represents a +User+ in the application customizable for the engine. This is because, as explained before, that class may not always be +User+. To make this customizable, the engine will have a configuration setting called +user_class+ that will be used to specify what the class representing users is inside the application.
To define this configuration setting, you should use a +mattr_accessor+ inside the +Blorgh+ module for the engine, located at +lib/blorgh.rb+ inside the engine. Inside this module, put this line:
@@ -542,6 +546,14 @@ Go ahead and try to create a new post. You will see that it works exactly in the
There are now no strict dependencies on what the class is, only what the class's API must be. The engine simply requires this class to define a +find_or_create_by_name+ method which returns an object of that class to be associated with a post when it's created.
+h5. General engine configuration
+
+Within an engine, there may come a time where you wish to use things such as initializers, internationalization or other configuration options. The great news is that these things are entirely possible because a Rails engine shares much the same functionality as a Rails application. In fact, a Rails application's functionality is actually a superset of what is provided by engines!
+
+If you wish to use initializers (code that should run before the engine is loaded), the best place for them is the +config/initializers+ folder. This directory's functionality is explained in the "Initializers section":http://guides.rubyonrails.org/configuring.html#initializers of the Configuring guide.
+
+For locales, simply place the locale files in the +config/locales+ directory, just like you would in an application.
+
h3. Extending engine functionality
This section looks at overriding or adding functionality to the views, controllers and models provided by an engine.
diff --git a/railties/guides/source/form_helpers.textile b/railties/guides/source/form_helpers.textile
index 821bb305f6..2de4d49cf2 100644
--- a/railties/guides/source/form_helpers.textile
+++ b/railties/guides/source/form_helpers.textile
@@ -150,7 +150,7 @@ NOTE: Always use labels for checkbox and radio buttons. They associate text with
h4. Other Helpers of Interest
-Other form controls worth mentioning are textareas, password fields, hidden fields, search fields, telephone fields, URL fields and email fields:
+Other form controls worth mentioning are textareas, password fields, hidden fields, search fields, telephone fields, date fields, URL fields and email fields:
<erb>
<%= text_area_tag(:message, "Hi, nice site", :size => "24x6") %>
@@ -158,6 +158,7 @@ Other form controls worth mentioning are textareas, password fields, hidden fiel
<%= hidden_field_tag(:parent_id, "5") %>
<%= search_field(:user, :name) %>
<%= telephone_field(:user, :phone) %>
+<%= date_field(:user, :born_on) %>
<%= url_field(:user, :homepage) %>
<%= email_field(:user, :address) %>
</erb>
@@ -170,13 +171,14 @@ Output:
<input id="parent_id" name="parent_id" type="hidden" value="5" />
<input id="user_name" name="user[name]" size="30" type="search" />
<input id="user_phone" name="user[phone]" size="30" type="tel" />
+<input id="user_born_on" name="user[born_on]" type="date" />
<input id="user_homepage" size="30" name="user[homepage]" type="url" />
<input id="user_address" size="30" name="user[address]" type="email" />
</html>
Hidden inputs are not shown to the user but instead hold data like any textual input. Values inside them can be changed with JavaScript.
-IMPORTANT: The search, telephone, URL, and email inputs are HTML5 controls. If you require your app to have a consistent experience in older browsers, you will need an HTML5 polyfill (provided by CSS and/or JavaScript). There is definitely "no shortage of solutions for this":https://github.com/Modernizr/Modernizr/wiki/HTML5-Cross-Browser-Polyfills, although a couple of popular tools at the moment are "Modernizr":http://www.modernizr.com/ and "yepnope":http://yepnopejs.com/, which provide a simple way to add functionality based on the presence of detected HTML5 features.
+IMPORTANT: The search, telephone, date, URL, and email inputs are HTML5 controls. If you require your app to have a consistent experience in older browsers, you will need an HTML5 polyfill (provided by CSS and/or JavaScript). There is definitely "no shortage of solutions for this":https://github.com/Modernizr/Modernizr/wiki/HTML5-Cross-Browser-Polyfills, although a couple of popular tools at the moment are "Modernizr":http://www.modernizr.com/ and "yepnope":http://yepnopejs.com/, which provide a simple way to add functionality based on the presence of detected HTML5 features.
TIP: If you're using password input fields (for any purpose), you might want to configure your application to prevent those parameters from being logged. You can learn about this in the "Security Guide":security.html#logging.
@@ -229,7 +231,7 @@ The corresponding view +app/views/articles/new.html.erb+ using +form_for+ looks
There are a few things to note here:
# +@article+ is the actual object being edited.
-# There is a single hash of options. Routing options are passed in the +:url+ hash, HTML options are passed in the +:html+ hash.
+# There is a single hash of options. Routing options are passed in the +:url+ hash, HTML options are passed in the +:html+ hash. Also you can provide a +:namespace+ option for your form to ensure uniqueness of id attributes on form elements. The namespace attribute will be prefixed with underscore on the generated HTML id.
# The +form_for+ method yields a *form builder* object (the +f+ variable).
# Methods to create form controls are called *on* the form builder object +f+
@@ -467,7 +469,7 @@ Rails _used_ to have a +country_select+ helper for choosing countries, but this
h3. Using Date and Time Form Helpers
-The date and time helpers differ from all the other form helpers in two important respects:
+You can choose not to use the form helpers generating HTML5 date input fields and use the alternative date and time helpers. These date and time helpers differ from all the other form helpers in two important respects:
# Dates and times are not representable by a single input element. Instead you have several, one for each component (year, month, day etc.) and so there is no single value in your +params+ hash with your date or time.
# Other helpers use the +_tag+ suffix to indicate whether a helper is a barebones helper or one that operates on model objects. With dates and times, +select_date+, +select_time+ and +select_datetime+ are the barebones helpers, +date_select+, +time_select+ and +datetime_select+ are the equivalent model object helpers.
@@ -630,10 +632,10 @@ action for a Person model, +params[:model]+ would usually be a hash of all the a
Fundamentally HTML forms don't know about any sort of structured data, all they generate is name–value pairs, where pairs are just plain strings. The arrays and hashes you see in your application are the result of some parameter naming conventions that Rails uses.
-TIP: You may find you can try out examples in this section faster by using the console to directly invoke Rails' parameter parser. For example,
+TIP: You may find you can try out examples in this section faster by using the console to directly invoke Racks' parameter parser. For example,
<ruby>
-ActionController::UrlEncodedPairParser.parse_query_parameters "name=fred&phone=0123456789"
+Rack::Utils.parse_query "name=fred&phone=0123456789"
# => {"name"=>"fred", "phone"=>"0123456789"}
</ruby>
@@ -754,7 +756,7 @@ produces exactly the same output as the previous example.
h3. Forms to external resources
-If you need to post some data to an external resource it is still great to build your from using rails form helpers. But sometimes you need to set an +authenticity_token+ for this resource. You can do it by passing an +:authenticity_token => 'your_external_token'+ parameter to the +form_tag+ options:
+If you need to post some data to an external resource it is still great to build your form using rails form helpers. But sometimes you need to set an +authenticity_token+ for this resource. You can do it by passing an +:authenticity_token => 'your_external_token'+ parameter to the +form_tag+ options:
<erb>
<%= form_tag 'http://farfar.away/form', :authenticity_token => 'external_token') do %>
diff --git a/railties/guides/source/generators.textile b/railties/guides/source/generators.textile
index 7a863ccbc7..920ff997ae 100644
--- a/railties/guides/source/generators.textile
+++ b/railties/guides/source/generators.textile
@@ -48,7 +48,7 @@ end
NOTE: +create_file+ is a method provided by +Thor::Actions+. Documentation for +create_file+ and other Thor methods can be found in "Thor's documentation":http://rdoc.info/github/wycats/thor/master/Thor/Actions.html
-Our new generator is quite simple: it inherits from +Rails::Generators::Base+ and has one method definition. Each public method in the generator is executed when a generator is invoked. Finally, we invoke the +create_file+ method that will create a file at the given destination with the given content. If you are familiar with the Rails Application Templates API, you'll feel right at home with the new generators API.
+Our new generator is quite simple: it inherits from +Rails::Generators::Base+ and has one method definition. When a generator is invoked, each public method in the generator is executed sequentially in the order that it is defined. Finally, we invoke the +create_file+ method that will create a file at the given destination with the given content. If you are familiar with the Rails Application Templates API, you'll feel right at home with the new generators API.
To invoke our new generator, we just need to do:
@@ -406,22 +406,6 @@ The following are methods available for both generators and templates for Rails.
NOTE: Methods provided by Thor are not covered this guide and can be found in "Thor's documentation":http://rdoc.info/github/wycats/thor/master/Thor/Actions.html
-h4. +plugin+
-
-+plugin+ will install a plugin into the current application.
-
-<ruby>
-plugin("dynamic-form", :git => "git://github.com/rails/dynamic-form.git")
-</ruby>
-
-Available options are:
-
-* +:git+ - Takes the path to the git repository where this plugin can be found.
-* +:branch+ - The name of the branch of the git repository where the plugin is found.
-* +:submodule+ - Set to +true+ for the plugin to be installed as a submodule. Defaults to +false+.
-* +:svn+ - Takes the path to the svn repository where this plugin can be found.
-* +:revision+ - The revision of the plugin in an SVN repository.
-
h4. +gem+
Specifies a gem dependency of the application.
diff --git a/railties/guides/source/getting_started.textile b/railties/guides/source/getting_started.textile
index bf6104b96b..bed14ef6a8 100644
--- a/railties/guides/source/getting_started.textile
+++ b/railties/guides/source/getting_started.textile
@@ -41,11 +41,12 @@ internet for learning Ruby, including:
* "Programming Ruby":http://www.ruby-doc.org/docs/ProgrammingRuby/
* "Why's (Poignant) Guide to Ruby":http://mislav.uniqpath.com/poignant-guide/
-Also, the example code for this guide is available in the rails github:https://github.com/rails/rails repository
-in rails/railties/guides/code/getting_started.
-
h3. What is Rails?
+TIP: This section goes into the background and philosophy of the Rails framework
+in detail. You can safely skip this section and come back to it at a later time.
+Section 3 starts you on the path to creating your first Rails application.
+
Rails is a web application development framework written in the Ruby language.
It is designed to make programming web applications easier by making assumptions
about what every developer needs to get started. It allows you to write less
@@ -215,7 +216,11 @@ Ian Robinson
h3. Creating a New Rails Project
-If you follow this guide, you'll create a Rails project called <tt>blog</tt>, a
+The best way to use this guide is to follow each step as it happens, no code or
+step needed to make this example application has been left out, so you can
+literally follow along step by step. You can get the complete code "here":https://github.com/lifo/docrails/tree/master/railties/guides/code/getting_started.
+
+By following along with this guide, you'll create a Rails project called <tt>blog</tt>, a
(very) simple weblog. Before you can start building the application, you need to
make sure that you have Rails itself installed.
@@ -233,13 +238,16 @@ Usually run this as the root user:
TIP. If you're working on Windows, you can quickly install Ruby and Rails with
"Rails Installer":http://railsinstaller.org.
-h4. Creating the Blog Application
+To verify that you have everything installed correctly, you should be able to run
+the following:
-The best way to use this guide is to follow each step as it happens, no code or
-step needed to make this example application has been left out, so you can
-literally follow along step by step. If you need to see the completed code, you
-can download it from "Getting Started
-Code":https://github.com/mikel/getting-started-code.
+<shell>
+$ rails --version
+</shell>
+
+If it says something like "Rails 3.1.3" you are ready to continue.
+
+h4. Creating the Blog Application
To begin, open a terminal, navigate to a folder where you have rights to create
files, and type:
@@ -261,41 +269,50 @@ directly in that application:
$ cd blog
</shell>
-In any case, Rails will create a folder in your working directory called
-<tt>blog</tt>. Open up that folder and explore its contents. Most of the work in
+The 'rails new blog' command we ran above created a folder in your working directory
+called <tt>blog</tt>. The <tt>blog</tt> folder has a number of auto-generated folders
+that make up the structure of a Rails application. Most of the work in
this tutorial will happen in the <tt>app/</tt> folder, but here's a basic
-rundown on the function of each folder that Rails creates in a new application
-by default:
+rundown on the function of each of the files and folders that Rails created by default:
|_.File/Folder|_.Purpose|
-|Gemfile|This file allows you to specify what gem dependencies are needed for your Rails application. See section on Bundler, below.|
-|README|This is a brief instruction manual for your application. You should edit this file to tell others what your application does, how to set it up, and so on.|
-|Rakefile|This file locates and loads tasks that can be run from the command line. The task definitions are defined throughout the components of Rails. Rather than changing Rakefile, you should add your own tasks by adding files to the lib/tasks directory of your application.|
|app/|Contains the controllers, models, views and assets for your application. You'll focus on this folder for the remainder of this guide.|
-|config/|Configure your application's runtime rules, routes, database, and more.|
+|config/|Configure your application's runtime rules, routes, database, and more. This is covered in more detail in "Configuring Rails Applications":configuring.html|
|config.ru|Rack configuration for Rack based servers used to start the application.|
-|db/|Shows your current database schema, as well as the database migrations. You'll learn about migrations shortly.|
+|db/|Contains your current database schema, as well as the database migrations.|
|doc/|In-depth documentation for your application.|
-|lib/|Extended modules for your application (not covered in this guide).|
+|Gemfile<BR />Gemfile.lock|These files allow you to specify what gem dependencies are needed for your Rails application.|
+|lib/|Extended modules for your application.|
|log/|Application log files.|
|public/|The only folder seen to the world as-is. Contains the static files and compiled assets.|
+|Rakefile|This file locates and loads tasks that can be run from the command line. The task definitions are defined throughout the components of Rails. Rather than changing Rakefile, you should add your own tasks by adding files to the lib/tasks directory of your application.|
+|README.rdoc|This is a brief instruction manual for your application. You should edit this file to tell others what your application does, how to set it up, and so on.|
|script/|Contains the rails script that starts your app and can contain other scripts you use to deploy or run your application.|
|test/|Unit tests, fixtures, and other test apparatus. These are covered in "Testing Rails Applications":testing.html|
|tmp/|Temporary files|
-|vendor/|A place for all third-party code. In a typical Rails application, this includes Ruby Gems, the Rails source code (if you install it into your project) and plugins containing additional prepackaged functionality.|
+|vendor/|A place for all third-party code. In a typical Rails application, this includes Ruby Gems and the Rails source code (if you optionally install it into your project).|
h4. Configuring a Database
Just about every Rails application will interact with a database. The database
to use is specified in a configuration file, +config/database.yml+. If you open
this file in a new Rails application, you'll see a default database
-configuration using SQLite3. The file contains sections for three different
+configured to use SQLite3. The file contains sections for three different
environments in which Rails can run by default:
-* The +development+ environment is used on your development computer as you interact manually with the application.
-* The +test+ environment is used to run automated tests.
+* The +development+ environment is used on your development/local computer as you interact
+manually with the application.
+* The +test+ environment is used when running automated tests.
* The +production+ environment is used when you deploy your application for the world to use.
+TIP: You don't have to update the database configurations manually. If you look at the
+options of the application generator, you will see that one of the options
+is named <tt>--database</tt>. This option allows you to choose an adapter from a
+list of the most used relational databases. You can even run the generator
+repeatedly: <tt>cd .. && rails new blog --database=mysql</tt>. When you confirm the overwriting
+ of the +config/database.yml+ file, your application will be configured for MySQL
+instead of SQLite. Detailed examples of the common database connections are below.
+
h5. Configuring an SQLite3 Database
Rails comes with built-in support for "SQLite3":http://www.sqlite.org, which is
@@ -399,14 +416,6 @@ development:
Change the username and password in the +development+ section as appropriate.
-TIP: You don't have to update the database configurations manually. If you look at the
-options of the application generator, you will see that one of the options
-is named <tt>--database</tt>. This option allows you to choose an adapter from a
-list of the most used relational databases. You can even run the generator
-repeatedly: <tt>cd .. && rails new blog --database=mysql</tt>. When you confirm the overwriting
- of the +config/database.yml+ file, your application will be configured for MySQL
-instead of SQLite.
-
h4. Creating the Database
Now that you have your database configured, it's time to have Rails create an
@@ -438,6 +447,14 @@ start a web server on your development machine. You can do this by running:
$ rails server
</shell>
+TIP: Compiling CoffeeScript to JavaScript requires a JavaScript runtime and
+the absence of a runtime will give you an +execjs+ error. Usually Mac OS X
+and Windows come with a JavaScript runtime installed. Rails adds the +therubyracer+ gem
+to Gemfile in a commented line for new apps and you can uncomment if you need it.
++therubyrhino+ is the recommended runtime for JRuby users and is added by default
+to Gemfile in apps generated under JRuby. You can investigate about all the
+supported runtimes at "ExecJS":https://github.com/sstephenson/execjs#readme.
+
This will fire up an instance of the WEBrick web server by default (Rails can
also use several other web servers). To see your application in action, open a
browser window and navigate to "http://localhost:3000":http://localhost:3000.
@@ -480,7 +497,7 @@ Open this file in your text editor and edit it to contain a single line of code:
h4. Setting the Application Home Page
Now that we have made the controller and view, we need to tell Rails when we
-want "Hello Rails" to show up. In our case, we want it to show up when we
+want "Hello Rails!" to show up. In our case, we want it to show up when we
navigate to the root URL of our site,
"http://localhost:3000":http://localhost:3000, instead of the "Welcome Aboard"
smoke test.
@@ -501,8 +518,7 @@ file_ which holds entries in a special DSL (domain-specific language) that tells
Rails how to connect incoming requests to controllers and actions. This file
contains many sample routes on commented lines, and one of them actually shows
you how to connect the root of your site to a specific controller and action.
-Find the line beginning with +root :to+, uncomment it and change it like the
-following:
+Find the line beginning with +root :to+ and uncomment it. It should look something like the following:
<ruby>
Blog::Application.routes.draw do
@@ -530,7 +546,7 @@ resource in a single operation, scaffolding is the tool for the job.
h3. Creating a Resource
-In the case of the blog application, you can start by generating a scaffolded
+In the case of the blog application, you can start by generating a scaffold for the
Post resource: this will represent a single blog posting. To do this, enter this
command in your terminal:
@@ -544,21 +560,21 @@ folders, and edit <tt>config/routes.rb</tt>. Here's a quick overview of what it
|_.File |_.Purpose|
|db/migrate/20100207214725_create_posts.rb |Migration to create the posts table in your database (your name will include a different timestamp)|
|app/models/post.rb |The Post model|
-|test/fixtures/posts.yml |Dummy posts for use in testing|
+|test/unit/post_test.rb |Unit testing harness for the posts model|
+|test/fixtures/posts.yml |Sample posts for use in testing|
+|config/routes.rb |Edited to include routing information for posts|
|app/controllers/posts_controller.rb |The Posts controller|
|app/views/posts/index.html.erb |A view to display an index of all posts |
|app/views/posts/edit.html.erb |A view to edit an existing post|
|app/views/posts/show.html.erb |A view to display a single post|
|app/views/posts/new.html.erb |A view to create a new post|
|app/views/posts/_form.html.erb |A partial to control the overall look and feel of the form used in edit and new views|
-|app/helpers/posts_helper.rb |Helper functions to be used from the post views|
-|app/assets/stylesheets/scaffolds.css.scss |Cascading style sheet to make the scaffolded views look better|
-|app/assets/stylesheets/posts.css.scss |Cascading style sheet for the posts controller|
-|app/assets/javascripts/posts.js.coffee |CoffeeScript for the posts controller|
-|test/unit/post_test.rb |Unit testing harness for the posts model|
|test/functional/posts_controller_test.rb |Functional testing harness for the posts controller|
+|app/helpers/posts_helper.rb |Helper functions to be used from the post views|
|test/unit/helpers/posts_helper_test.rb |Unit testing harness for the posts helper|
-|config/routes.rb |Edited to include routing information for posts|
+|app/assets/javascripts/posts.js.coffee |CoffeeScript for the posts controller|
+|app/assets/stylesheets/posts.css.scss |Cascading style sheet for the posts controller|
+|app/assets/stylesheets/scaffolds.css.scss |Cascading style sheet to make the scaffolded views look better|
NOTE. While scaffolding will get you up and running quickly, the code it
generates is unlikely to be a perfect fit for your application. You'll most
@@ -596,11 +612,11 @@ end
</ruby>
The above migration creates a method named +change+ which will be called when you
-run this migration. The action defined in that method is also reversible, which
+run this migration. The action defined in this method is also reversible, which
means Rails knows how to reverse the change made by this migration, in case you
-want to reverse it at later date. By default, when you run this migration it
-creates a +posts+ table with two string columns and a text column. It also
-creates two timestamp fields to track record creation and updating. More
+want to reverse it later. When you run this migration it will create a
++posts+ table with two string columns and a text column. It also creates two
+timestamp fields to allow Rails to track post creation and update times. More
information about Rails migrations can be found in the "Rails Database
Migrations":migrations.html guide.
@@ -620,7 +636,7 @@ table.
== CreatePosts: migrated (0.0020s) ===========================================
</shell>
-NOTE. Because by default you're working in the development environment, this
+NOTE. Because you're working in the development environment by default, this
command will apply to the database defined in the +development+ section of your
+config/database.yml+ file. If you would like to execute migrations in another
environment, for instance in production, you must explicitly pass it when
@@ -691,7 +707,8 @@ end
These changes will ensure that all posts have a name and a title, and that the
title is at least five characters long. Rails can validate a variety of
conditions in a model, including the presence or uniqueness of columns, their
-format, and the existence of associated objects.
+format, and the existence of associated objects. Validations are covered in detail
+in "Active Record Validations and Callbacks":active_record_validations_callbacks.html#validations-overview
h4. Using the Console
@@ -716,10 +733,8 @@ After the console loads, you can use it to work with your application's models:
updated_at: nil>
>> p.save
=> false
->> p.errors
-=> #<OrderedHash { :title=>["can't be blank",
- "is too short (minimum is 5 characters)"],
- :name=>["can't be blank"] }>
+>> p.errors.full_messages
+=> ["Name can't be blank", "Title can't be blank", "Title is too short (minimum is 5 characters)"]
</shell>
This code shows creating a new +Post+ instance, attempting to save it and
@@ -729,13 +744,14 @@ inspecting the +errors+ of the post.
When you're finished, type +exit+ and hit +return+ to exit the console.
TIP: Unlike the development web server, the console does not automatically load
-your code afresh for each line. If you make changes to your models while the
-console is open, type +reload!+ at the console prompt to load them.
+your code afresh for each line. If you make changes to your models (in your editor)
+while the console is open, type +reload!+ at the console prompt to load them.
h4. Listing All Posts
-The easiest place to start looking at functionality is with the code that lists
-all posts. Open the file +app/controllers/posts_controller.rb+ and look at the
+Let's dive into the Rails code a little deeper to see how the application is
+showing us the list of Posts. Open the file
++app/controllers/posts_controller.rb+ and look at the
+index+ action:
<ruby>
@@ -749,9 +765,8 @@ def index
end
</ruby>
-+Post.all+ calls the +Post+ model to return all of the posts currently in the
-database. The result of this call is an array of posts that we store in an
-instance variable called +@posts+.
++Post.all+ returns all of the posts currently in the database as an array
+of +Post+ records that we store in an instance variable called +@posts+.
TIP: For more information on finding records with Active Record, see "Active
Record Query Interface":active_record_querying.html.
@@ -802,8 +817,7 @@ and links. A few things to note in the view:
NOTE. In previous versions of Rails, you had to use +&lt;%=h post.name %&gt;+ so
that any HTML would be escaped before being inserted into the page. In Rails
-3.0, this is now the default. To get unescaped HTML, you now use +&lt;%= raw
-post.name %&gt;+.
+3 and above, this is now the default. To get unescaped HTML, you now use <tt>&lt;%= raw post.name %&gt;</tt>.
TIP: For more details on the rendering process, see "Layouts and Rendering in
Rails":layouts_and_rendering.html.
@@ -816,9 +830,10 @@ Rails renders a view to the browser, it does so by putting the view's HTML into
a layout's HTML. In previous versions of Rails, the +rails generate scaffold+
command would automatically create a controller specific layout, like
+app/views/layouts/posts.html.erb+, for the posts controller. However this has
-been changed in Rails 3.0. An application specific +layout+ is used for all the
+been changed in Rails 3. An application specific +layout+ is used for all the
controllers and can be found in +app/views/layouts/application.html.erb+. Open
-this layout in your editor and modify the +body+ tag:
+this layout in your editor and modify the +body+ tag to include the style directive
+below:
<erb>
<!DOCTYPE html>
@@ -829,7 +844,7 @@ this layout in your editor and modify the +body+ tag:
<%= javascript_include_tag "application" %>
<%= csrf_meta_tags %>
</head>
-<body style="background: #EEEEEE;">
+<body style="background-color: #EEEEEE;">
<%= yield %>
@@ -838,7 +853,7 @@ this layout in your editor and modify the +body+ tag:
</erb>
Now when you refresh the +/posts+ page, you'll see a gray background to the
-page. This same gray background will be used throughout all the views for posts.
+page. This same gray background will be used throughout all the views.
h4. Creating New Posts
@@ -996,10 +1011,10 @@ end
The +show+ action uses +Post.find+ to search for a single record in the database
by its id value. After finding the record, Rails displays it by using
-+show.html.erb+:
++app/views/posts/show.html.erb+:
<erb>
-<p class="notice"><%= notice %></p>
+<p id="notice"><%= notice %></p>
<p>
<b>Name:</b>
@@ -1060,7 +1075,7 @@ def update
if @post.update_attributes(params[:post])
format.html { redirect_to(@post,
:notice => 'Post was successfully updated.') }
- format.json { render :json => {}, :status => :ok }
+ format.json { head :no_content }
else
format.html { render :action => "edit" }
format.json { render :json => @post.errors,
@@ -1089,7 +1104,7 @@ def destroy
respond_to do |format|
format.html { redirect_to posts_url }
- format.json { head :ok }
+ format.json { head :no_content }
end
end
</ruby>
@@ -1101,7 +1116,7 @@ the controller.
h3. Adding a Second Model
-Now that you've seen how a model built with scaffolding looks like, it's time to
+Now that you've seen what a model built with scaffolding looks like, it's time to
add a second model to the application. The second model will handle comments on
blog posts.
@@ -1120,9 +1135,11 @@ $ rails generate model Comment commenter:string body:text post:references
This command will generate four files:
-* +app/models/comment.rb+ - The model.
-* +db/migrate/20100207235629_create_comments.rb+ - The migration.
-* +test/unit/comment_test.rb+ and +test/fixtures/comments.yml+ - The test harness.
+|_.File |_.Purpose|
+|db/migrate/20100207235629_create_comments.rb | Migration to create the comments table in your database (your name will include a different timestamp) |
+| app/models/comment.rb | The Comment model |
+| test/unit/comment_test.rb | Unit testing harness for the comments model |
+| test/fixtures/comments.yml | Sample comments for use in testing |
First, take a look at +comment.rb+:
@@ -1169,8 +1186,10 @@ run against the current database, so in this case you will just see:
<shell>
== CreateComments: migrating =================================================
-- create_table(:comments)
- -> 0.0017s
-== CreateComments: migrated (0.0018s) ========================================
+ -> 0.0008s
+-- add_index(:comments, :post_id)
+ -> 0.0003s
+== CreateComments: migrated (0.0012s) ========================================
</shell>
h4. Associating Models
@@ -1243,13 +1262,14 @@ $ rails generate controller Comments
This creates six files and one empty directory:
-* +app/controllers/comments_controller.rb+ - The controller.
-* +app/helpers/comments_helper.rb+ - A view helper file.
-* +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.
-* +app/views/comments/+ - Views of the controller are stored here.
-* +app/assets/stylesheets/comment.css.scss+ - Cascading style sheet for the controller.
-* +app/assets/javascripts/comment.js.coffee+ - CoffeeScript for the controller.
+|_.File/Directory |_.Purpose |
+| app/controllers/comments_controller.rb | The Comments controller |
+| app/views/comments/ | Views of the controller are stored here |
+| test/functional/comments_controller_test.rb | The functional tests for the controller |
+| app/helpers/comments_helper.rb | A view helper file |
+| test/unit/helpers/comments_helper_test.rb | The unit tests for the helper |
+| app/assets/javascripts/comment.js.coffee | CoffeeScript for the controller |
+| app/assets/stylesheets/comment.css.scss | Cascading style sheet for the controller |
Like with any blog, our readers will create their comments directly after
reading the post, and once they have added their comment, will be sent back to
@@ -1261,7 +1281,7 @@ So first, we'll wire up the Post show template
(+/app/views/posts/show.html.erb+) to let us make a new comment:
<erb>
-<p class="notice"><%= notice %></p>
+<p id="notice"><%= notice %></p>
<p>
<b>Name:</b>
@@ -1327,7 +1347,7 @@ template. This is where we want the comment to show, so let's add that to the
+app/views/posts/show.html.erb+.
<erb>
-<p class="notice"><%= notice %></p>
+<p id="notice"><%= notice %></p>
<p>
<b>Name:</b>
@@ -1409,7 +1429,7 @@ Then you can change +app/views/posts/show.html.erb+ to look like the
following:
<erb>
-<p class="notice"><%= notice %></p>
+<p id="notice"><%= notice %></p>
<p>
<b>Name:</b>
@@ -1480,7 +1500,7 @@ create a file +app/views/comments/_form.html.erb+ containing:
Then you make the +app/views/posts/show.html.erb+ look like the following:
<erb>
-<p class="notice"><%= notice %></p>
+<p id="notice"><%= notice %></p>
<p>
<b>Name:</b>
@@ -1648,7 +1668,7 @@ right in the form where you create the post. First, create a new model to hold
the tags:
<shell>
-$ rails generate model tag name:string post:references
+$ rails generate model Tag name:string post:references
</shell>
Again, run the migration to create the database table:
@@ -1675,10 +1695,10 @@ class Post < ActiveRecord::Base
end
</ruby>
-The +:allow_destroy+ option on the nested attribute declaration tells Rails to
-display a "remove" checkbox on the view that you'll build shortly. The
-+:reject_if+ option prevents saving new tags that do not have any attributes
-filled in.
+The +:allow_destroy+ option tells Rails to enable destroying tags through the
+nested attributes (you'll handle that by displaying a "remove" checkbox on the
+view that you'll build shortly). The +:reject_if+ option prevents saving new
+tags that do not have any attributes filled in.
We will modify +views/posts/_form.html.erb+ to render a partial to make a tag:
@@ -1751,7 +1771,7 @@ Finally, we will edit the <tt>app/views/posts/show.html.erb</tt> template to
show our tags.
<erb>
-<p class="notice"><%= notice %></p>
+<p id="notice"><%= notice %></p>
<p>
<b>Name:</b>
@@ -1811,7 +1831,7 @@ Now you can edit the view in <tt>app/views/posts/show.html.erb</tt> to look like
this:
<erb>
-<p class="notice"><%= notice %></p>
+<p id="notice"><%= notice %></p>
<p>
<b>Name:</b>
@@ -1855,7 +1875,6 @@ free to consult these support resources:
* The "Ruby on Rails Tutorial":http://railstutorial.org/book
* The "Ruby on Rails mailing list":http://groups.google.com/group/rubyonrails-talk
* The "#rubyonrails":irc://irc.freenode.net/#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 2d4cc13571..25201888e7 100644
--- a/railties/guides/source/i18n.textile
+++ b/railties/guides/source/i18n.textile
@@ -231,7 +231,7 @@ end
Now, when you call the +books_path+ method you should get +"/en/books"+ (for the default locale). An URL like +http://localhost:3001/nl/books+ should load the Netherlands locale, then, and following calls to +books_path+ should return +"/nl/books"+ (because the locale changed).
-If you don't want to force the use of a locale in your routes you can use an optional path scope (donated by the use brackets) like so:
+If you don't want to force the use of a locale in your routes you can use an optional path scope (denoted by the parentheses) like so:
<ruby>
# config/routes.rb
@@ -819,13 +819,13 @@ h5. Action View Helper Methods
* The +number_to_currency+, +number_with_precision+, +number_to_percentage+, +number_with_delimiter+, and +number_to_human_size+ helpers use the number format settings located in the "number":https://github.com/rails/rails/blob/master/actionpack/lib/action_view/locale/en.yml#L2 scope.
-h5. Active Record Methods
+h5. Active Model Methods
* +model_name.human+ and +human_attribute_name+ use translations for model names and attribute names if available in the "activerecord.models":https://github.com/rails/rails/blob/master/activerecord/lib/active_record/locale/en.yml#L29 scope. They also support translations for inherited class names (e.g. for use with STI) as explained above in "Error message scopes".
-* +ActiveRecord::Errors#generate_message+ (which is used by Active Record validations but may also be used manually) uses +model_name.human+ and +human_attribute_name+ (see above). It also translates the error message and supports translations for inherited class names as explained above in "Error message scopes".
+* +ActiveModel::Errors#generate_message+ (which is used by Active Model validations but may also be used manually) uses +model_name.human+ and +human_attribute_name+ (see above). It also translates the error message and supports translations for inherited class names as explained above in "Error message scopes".
-*+ ActiveRecord::Errors#full_messages+ prepends the attribute name to the error message using a separator that will be looked up from "activerecord.errors.format.separator":https://github.com/rails/rails/blob/master/actionpack/lib/action_view/locale/en.yml#L91 (and which defaults to +'&nbsp;'+).
+* +ActiveModel::Errors#full_messages+ prepends the attribute name to the error message using a separator that will be looked up from "errors.format":https://github.com/rails/rails/blob/master/activemodel/lib/active_model/locale/en.yml#L4 (and which defaults to +"%{attribute} %{message}"+).
h5. Active Support Methods
diff --git a/railties/guides/source/index.html.erb b/railties/guides/source/index.html.erb
index c9a8c4fa5c..5439459b42 100644
--- a/railties/guides/source/index.html.erb
+++ b/railties/guides/source/index.html.erb
@@ -3,189 +3,28 @@ Ruby on Rails Guides
<% end %>
<% content_for :header_section do %>
-<h2>Ruby on Rails Guides (<%= ENV['RAILS_VERSION'] || 'edge' %>)</h2>
-
-<% if @edge %>
-<p>
- These are <b>Edge Guides</b>, based on the current
- <a href="https://github.com/rails/rails/tree/master">master branch</a>.
-</p>
-<p>
- If you are looking for the ones for the stable version please check
- <a href="http://guides.rubyonrails.org">http://guides.rubyonrails.org</a> instead.
-</p>
-<% else %>
-<p>
- These are the new guides for Rails 3. The guides for Rails 2.3 are still available
- at <a href="http://guides.rubyonrails.org/v2.3.11/">http://guides.rubyonrails.org/v2.3.11/</a>.
-</p>
-<% end %>
-<p>
- These guides are designed to make you immediately productive with Rails,
- and to help you understand how all of the pieces fit together.
-</p>
-
+<%= render 'welcome' %>
<% end %>
<% content_for :index_section do %>
<div id="subCol">
<dl>
+ <dd class="kindle">Rails Guides are also available for the <%= link_to 'Kindle', 'https://kindle.amazon.com' %>
+and <%= link_to 'Free Kindle Reading Apps', 'http://www.amazon.com/gp/kindle/kcp' %> for the iPad,
+iPhone, Mac, Android, etc. Download them from <%= link_to 'here', @mobi %>.
+ </dd>
<dd class="work-in-progress">Guides marked with this icon are currently being worked on. While they might still be useful to you, they may contain incomplete information and even errors. You can help by reviewing them and posting your comments and corrections to the author.</dd>
</dl>
</div>
<% end %>
-<h3>Start Here</h3>
-
-<dl>
-<%= guide('Getting Started with Rails', 'getting_started.html') do %>
- <p>Everything you need to know to install Rails and create your first application.</p>
-<% end %>
-</dl>
-
-<h3>Models</h3>
-
-<dl>
-<%= guide("Rails Database Migrations", 'migrations.html') do %>
- <p>This guide covers how you can use Active Record migrations to alter your database in a structured and organized manner.</p>
-<% end %>
-
-<%= guide("Active Record Validations and Callbacks", 'active_record_validations_callbacks.html') do %>
- <p>This guide covers how you can use Active Record validations and callbacks.</p>
-<% end %>
-
-<%= guide("Active Record Associations", 'association_basics.html') do %>
- <p>This guide covers all the associations provided by Active Record.</p>
-<% end %>
-
-<%= guide("Active Record Query Interface", 'active_record_querying.html') do %>
- <p>This guide covers the database query interface provided by Active Record.</p>
-<% end %>
-</dl>
-
-<h3>Views</h3>
-
-<dl>
-<%= guide("Layouts and Rendering in Rails", 'layouts_and_rendering.html') do %>
- <p>This guide covers the basic layout features of Action Controller and Action View, including rendering and redirecting, using content_for blocks, and working with partials.</p>
-<% end %>
-
-<%= guide("Action View Form Helpers", 'form_helpers.html', :work_in_progress => true) do %>
- <p>Guide to using built-in Form helpers.</p>
-<% end %>
-</dl>
-
-<h3>Controllers</h3>
-
-<dl>
-<%= guide("Action Controller Overview", 'action_controller_overview.html') do %>
- <p>This guide covers how controllers work and how they fit into the request cycle in your application. It includes sessions, filters, and cookies, data streaming, and dealing with exceptions raised by a request, among other topics.</p>
-<% end %>
-
-<%= guide("Rails Routing from the Outside In", 'routing.html') do %>
- <p>This guide covers the user-facing features of Rails routing. If you want to understand how to use routing in your own Rails applications, start here.</p>
-<% end %>
-</dl>
-
-<h3>Digging Deeper</h3>
-
-<dl>
-
-<%= guide("Active Support Core Extensions", 'active_support_core_extensions.html') do %>
- <p>This guide documents the Ruby core extensions defined in Active Support.</p>
-<% end %>
-
-<%= guide("Rails Internationalization API", 'i18n.html') do %>
- <p>This guide covers how to add internationalization to your applications. Your application will be able to translate content to different languages, change pluralization rules, use correct date formats for each country and so on.</p>
-<% end %>
-
-<%= guide("Action Mailer Basics", 'action_mailer_basics.html', :work_in_progress => true) do %>
- <p>This guide describes how to use Action Mailer to send and receive emails.</p>
-<% end %>
-
-<%= guide("Testing Rails Applications", 'testing.html', :work_in_progress => true) do %>
- <p>This is a rather comprehensive guide to doing both unit and functional tests in Rails. It covers everything from &quot;What is a test?&quot; to the testing APIs. Enjoy.</p>
-<% end %>
-
-<%= guide("Securing Rails Applications", 'security.html') do %>
- <p>This guide describes common security problems in web applications and how to avoid them with Rails.</p>
-<% end %>
-
-<%= guide("Debugging Rails Applications", 'debugging_rails_applications.html') do %>
- <p>This guide describes how to debug Rails applications. It covers the different ways of achieving this and how to understand what is happening "behind the scenes" of your code.</p>
-<% end %>
-
-<%= guide("Performance Testing Rails Applications", 'performance_testing.html') do %>
- <p>This guide covers the various ways of performance testing a Ruby on Rails application.</p>
-<% end %>
-
-<%= guide("Configuring Rails Applications", 'configuring.html') do %>
- <p>This guide covers the basic configuration settings for a Rails application.</p>
-<% end %>
-
-<%= guide("Rails Command Line Tools and Rake tasks", 'command_line.html') do %>
- <p>This guide covers the command line tools and rake tasks provided by Rails.</p>
-<% end %>
-
-<%= guide("Caching with Rails", 'caching_with_rails.html', :work_in_progress => true) do %>
- <p>Various caching techniques provided by Rails.</p>
-<% end %>
-
-<%= guide('Asset Pipeline', 'asset_pipeline.html') do %>
- <p>This guide documents the asset pipeline.</p>
-<% end %>
-</dl>
-
-<h3>Extending Rails</h3>
-
-<dl>
- <%= guide("The Basics of Creating Rails Plugins", 'plugins.html', :work_in_progress => true) do %>
- <p>This guide covers how to build a plugin to extend the functionality of Rails.</p>
- <% end %>
-
- <%= guide("Rails on Rack", 'rails_on_rack.html') do %>
- <p>This guide covers Rails integration with Rack and interfacing with other Rack components.</p>
- <% end %>
-
- <%= guide("Creating and Customizing Rails Generators", 'generators.html') do %>
- <p>This guide covers the process of adding a brand new generator to your extension
- or providing an alternative to an element of a built-in Rails generator (such as
- providing alternative test stubs for the scaffold generator).</p>
- <% end %>
-</dl>
-
-<h3>Contributing to Ruby on Rails</h3>
-
-<dl>
- <%= guide("Contributing to Ruby on Rails", 'contributing_to_ruby_on_rails.html') do %>
- <p>Rails is not &quot;somebody else's framework.&quot; This guide covers a variety of ways that you can get involved in the ongoing development of Rails.</p>
- <% end %>
-
- <%= guide('API Documentation Guidelines', 'api_documentation_guidelines.html') do %>
- <p>This guide documents the Ruby on Rails API documentation guidelines.</p>
- <% end %>
-
- <%= guide('Ruby on Rails Guides Guidelines', 'ruby_on_rails_guides_guidelines.html') do %>
- <p>This guide documents the Ruby on Rails guides guidelines.</p>
- <% end %>
-</dl>
-
-<h3>Release Notes</h3>
-
-<dl>
-<%= guide("Ruby on Rails 3.1 Release Notes", '3_1_release_notes.html') do %>
- <p>Release notes for Rails 3.1.</p>
-<% end %>
-
-<%= guide("Ruby on Rails 3.0 Release Notes", '3_0_release_notes.html') do %>
- <p>Release notes for Rails 3.0.</p>
-<% end %>
-
-<%= guide("Ruby on Rails 2.3 Release Notes", '2_3_release_notes.html') do %>
- <p>Release notes for Rails 2.3.</p>
-<% end %>
-
-<%= guide("Ruby on Rails 2.2 Release Notes", '2_2_release_notes.html') do %>
- <p>Release notes for Rails 2.2.</p>
+<% documents_by_section.each do |section| %>
+ <h3><%= section['name'] %></h3>
+ <dl>
+ <% section['documents'].each do |document| %>
+ <%= guide(document['name'], document['url'], :work_in_progress => document['work_in_progress']) do %>
+ <p><%= document['description'] %></p>
+ <% end %>
+ <% end %>
+ </dl>
<% end %>
-</dl>
diff --git a/railties/guides/source/initialization.textile b/railties/guides/source/initialization.textile
index f88405a2fd..5ae9cf0f2b 100644
--- a/railties/guides/source/initialization.textile
+++ b/railties/guides/source/initialization.textile
@@ -17,7 +17,7 @@ As of Rails 3, +script/server+ has become +rails server+. This was done to centr
h4. +bin/rails+
-The actual +rails+ command is kept in _bin/rails_ at the and goes like this:
+The actual +rails+ command is kept in _bin/rails_:
<ruby>
#!/usr/bin/env ruby
@@ -31,7 +31,7 @@ rescue LoadError
end
</ruby>
-This file will attempt to load +rails/cli+ and if it cannot find it then add the +railties/lib+ path to the load path (+$:+) and will then try to require it again.
+This file will attempt to load +rails/cli+. If it cannot find it then +railties/lib+ is added to the load path (+$:+) before retrying.
h4. +railties/lib/rails/cli.rb+
@@ -56,7 +56,7 @@ else
end
</ruby>
-The +rbconfig+ file here is out of Ruby's standard library and provides us with the +RbConfig+ class which contains useful information dependent on how Ruby was compiled. We'll see this in use in +railties/lib/rails/script_rails_loader+.
+The +rbconfig+ file from the Ruby standard library provides us with the +RbConfig+ class which contains detailed information about the Ruby environment, including how Ruby was compiled. We can see this in use in +railties/lib/rails/script_rails_loader+.
<ruby>
require 'pathname'
@@ -71,7 +71,7 @@ module Rails
end
</ruby>
-The +rails/script_rails_loader+ file uses +RbConfig::Config+ to gather up the +bin_dir+ and +ruby_install_name+ values for the configuration which will result in a path such as +/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/ruby+, which is the default path on Mac OS X. If you're running Windows the path may be something such as +C:/Ruby192/bin/ruby+. Anyway, the path on your system may be different, but the point of this is that it will point at the known ruby executable location for your install. The +RbConfig::CONFIG["EXEEXT"]+ will suffix this path with ".exe" if the script is running on Windows. This constant is used later on in +exec_script_rails!+. As for the +SCRIPT_RAILS+ constant, we'll see that when we get to the +in_rails_application?+ method.
+The +rails/script_rails_loader+ file uses +RbConfig::Config+ to obtain the +bin_dir+ and +ruby_install_name+ values for the configuration which together form the path to the Ruby interpreter. The +RbConfig::CONFIG["EXEEXT"]+ will suffix this path with ".exe" if the script is running on Windows. This constant is used later on in +exec_script_rails!+. As for the +SCRIPT_RAILS+ constant, we'll see that when we get to the +in_rails_application?+ method.
Back in +rails/cli+, the next line is this:
@@ -79,7 +79,7 @@ Back in +rails/cli+, the next line is this:
Rails::ScriptRailsLoader.exec_script_rails!
</ruby>
-This method is defined in +rails/script_rails_loader+ like this:
+This method is defined in +rails/script_rails_loader+:
<ruby>
def self.exec_script_rails!
@@ -96,7 +96,7 @@ rescue SystemCallError
end
</ruby>
-This method will first check if the current working directory (+cwd+) is a Rails application or is a subdirectory of one. The way to determine this is defined in the +in_rails_application?+ method like this:
+This method will first check if the current working directory (+cwd+) is a Rails application or a subdirectory of one. This is determined by the +in_rails_application?+ method:
<ruby>
def self.in_rails_application?
@@ -104,7 +104,7 @@ def self.in_rails_application?
end
</ruby>
-The +SCRIPT_RAILS+ constant defined earlier is used here, with +File.exists?+ checking for its presence in the current directory. If this method returns +false+, then +in_rails_application_subdirectory?+ will be used:
+The +SCRIPT_RAILS+ constant defined earlier is used here, with +File.exists?+ checking for its presence in the current directory. If this method returns +false+ then +in_rails_application_subdirectory?+ will be used:
<ruby>
def self.in_rails_application_subdirectory?(path = Pathname.new(Dir.pwd))
@@ -112,17 +112,17 @@ def self.in_rails_application_subdirectory?(path = Pathname.new(Dir.pwd))
end
</ruby>
-This climbs the directory tree until it reaches a path which contains a +script/rails+ file. If a directory is reached which contains this file then this line will run:
+This climbs the directory tree until it reaches a path which contains a +script/rails+ file. If a directory containing this file is reached then this line will run:
<ruby>
exec RUBY, SCRIPT_RAILS, *ARGV if in_rails_application?
</ruby>
-This is effectively the same as doing +ruby script/rails [arguments]+. Where +[arguments]+ at this point in time is simply "server".
+This is effectively the same as running +ruby script/rails [arguments]+, where +[arguments]+ at this point in time is simply "server".
h4. +script/rails+
-This file looks like this:
+This file is as follows:
<ruby>
APP_PATH = File.expand_path('../../config/application', __FILE__)
@@ -130,7 +130,7 @@ require File.expand_path('../../config/boot', __FILE__)
require 'rails/commands'
</ruby>
-The +APP_PATH+ constant here will be used later in +rails/commands+. The +config/boot+ file that +script/rails+ references is the +config/boot.rb+ file in our application which is responsible for loading Bundler and setting it up.
+The +APP_PATH+ constant will be used later in +rails/commands+. The +config/boot+ file referenced here is the +config/boot.rb+ file in our application which is responsible for loading Bundler and setting it up.
h4. +config/boot.rb+
@@ -525,19 +525,19 @@ silence_warnings do
end
</ruby>
-These methods can be used to silence STDERR responses and the +silence_stream+ allows you to also silence other streams. Additionally, this mixin allows you to suppress exceptions and capture streams. For more information see the "Silencing Warnings, Streams, and Exceptions":http://guides.rubyonrails.org/active_support_core_extensions.html#silencing-warnings-streams-and-exceptions section from the Active Support Core Extensions Guide.
+These methods can be used to silence STDERR responses and the +silence_stream+ allows you to also silence other streams. Additionally, this mixin allows you to suppress exceptions and capture streams. For more information see the "Silencing Warnings, Streams, and Exceptions":active_support_core_extensions.html#silencing-warnings-streams-and-exceptions section from the Active Support Core Extensions Guide.
h4. +active_support/core_ext/logger.rb+
The next file that is required is another Active Support core extension, this time to the +Logger+ class. This begins by defining the +around_[level]+ helpers for the +Logger+ class as well as other methods such as a +datetime_format+ getter and setter for the +formatter+ object tied to a +Logger+ object.
-For more information see the "Extensions to Logger":http://guides.rubyonrails.org/active_support_core_extensions.html#extensions-to-logger section from the Active Support Core Extensions Guide.
+For more information see the "Extensions to Logger":active_support_core_extensions.html#extensions-to-logger section from the Active Support Core Extensions Guide.
h4. +railties/lib/rails/application.rb+
The next file required by +railties/lib/rails.rb+ is +application.rb+. This file defines the +Rails::Application+ constant which the application's class defined in +config/application.rb+ in a standard Rails application depends on. Before the +Rails::Application+ class is defined however, there's some other files that get required first.
-The first of these is +active_support/core_ext/hash/reverse_merge+ which can be "read about in the Active Support Core Extensions guide":http://guides.rubyonrails.org/active_support_core_extensions.html#merging under the "Merging" section.
+The first of these is +active_support/core_ext/hash/reverse_merge+ which can be "read about in the Active Support Core Extensions guide":active_support_core_extensions.html#merging under the "Merging" section.
h4. +active_support/file_update_checker.rb+
@@ -575,7 +575,7 @@ Now that +rails/initializable.rb+ has finished being required from +rails/railti
h4. +railties/lib/rails/configuration.rb+
-This file defines the +Rails::Configuration+ module, containing the +MiddlewareStackProxy+ class as well as the +Generators+ class. The +MiddlewareStackProxy+ class is used for managing the middleware stack for an application, which we'll see later on. The +Generators+ class provides the functionality used for configuring what generators an application uses through the "+config.generators+ option":http://guides.rubyonrails.org/configuring.html#configuring-generators.
+This file defines the +Rails::Configuration+ module, containing the +MiddlewareStackProxy+ class as well as the +Generators+ class. The +MiddlewareStackProxy+ class is used for managing the middleware stack for an application, which we'll see later on. The +Generators+ class provides the functionality used for configuring what generators an application uses through the "+config.generators+ option":configuring.html#configuring-generators.
The first file required in this file is +activesupport/deprecation+.
@@ -598,11 +598,11 @@ This file defines the +ActiveSupport::Notifications+ module. Notifications provi
The "API documentation":http://api.rubyonrails.org/classes/ActiveSupport/Notifications.html for +ActiveSupport::Notifications+ explains the usage of this module, including the methods that it defines.
-The file required in +active_support/notifications.rb+ is +active_support/core_ext/module/delegation+ which is documented in the "Active Support Core Extensions Guide":http://guides.rubyonrails.org/active_support_core_extensions.html#method-delegation.
+The file required in +active_support/notifications.rb+ is +active_support/core_ext/module/delegation+ which is documented in the "Active Support Core Extensions Guide":active_support_core_extensions.html#method-delegation.
h4. +activesupport/core_ext/array/wrap+
-As this file comprises of a core extension, it is covered exclusively in "the Active Support Core Extensions guide":http://guides.rubyonrails.org/active_support_core_extensions.html#wrapping
+As this file comprises of a core extension, it is covered exclusively in "the Active Support Core Extensions guide":active_support_core_extensions.html#wrapping
h4. +activesupport/lib/active_support/deprecation/reporting.rb+
@@ -624,7 +624,7 @@ h4. +active_support/ordered_options+
This file is the next file required from +rails/configuration.rb+ is the file that defines +ActiveSupport::OrderedOptions+ which is used for configuration options such as +config.active_support+ and the like.
-The next file required is +active_support/core_ext/hash/deep_dup+ which is covered in "Active Support Core Extensions guide":http://guides.rubyonrails.org/active_support_core_extensions.html#deep_dup
+The next file required is +active_support/core_ext/hash/deep_dup+ which is covered in "Active Support Core Extensions guide":active_support_core_extensions.html#deep_dup
The file that is required next from is +rails/paths+
@@ -682,7 +682,7 @@ When the module from this file (+Rails::Initializable+) is included, it extends
h4. +railties/lib/rails/engine.rb+
-The next file required in +rails/engine.rb+ is +active_support/core_ext/module/delegation+ which is documented in the "Active Support Core Extensions Guide":http://guides.rubyonrails.org/active_support_core_extensions.html#method-delegation.
+The next file required in +rails/engine.rb+ is +active_support/core_ext/module/delegation+ which is documented in the "Active Support Core Extensions Guide":active_support_core_extensions.html#method-delegation.
The next two files after this are Ruby standard library files: +pathname+ and +rbconfig+. The file after these is +rails/engine/railties+.
@@ -698,7 +698,7 @@ Once this file has finished loading we jump back to +railties/lib/rails/plugin.r
h4. Back to +railties/lib/rails/plugin.rb+
-The next file required in this is a core extension from Active Support called +array/conversions+ which is covered in "this section":http://guides.rubyonrails.org/active_support_core_extensions.html#array-conversions of the Active Support Core Extensions Guide.
+The next file required in this is a core extension from Active Support called +array/conversions+ which is covered in "this section":active_support_core_extensions.html#array-conversions of the Active Support Core Extensions Guide.
Once that file has finished loading, the +Rails::Plugin+ class is defined.
@@ -817,7 +817,7 @@ def initializer(name, opts = {}, &blk)
end
</ruby>
-An initializer can be configured to run before or after another initializer, which we'll see a couple of times throughout this initialization process. Anything that inherits from +Rails::Railtie+ may also make use of the +initializer+ method, something which is covered in the "Configuration guide":[http://ryanbigg.com/guides/configuring.html#rails-railtie-initializer].
+An initializer can be configured to run before or after another initializer, which we'll see a couple of times throughout this initialization process. Anything that inherits from +Rails::Railtie+ may also make use of the +initializer+ method, something which is covered in the "Configuration guide":configuring.html#rails-railtie-initializer.
The +Initializer+ class here is defined within the +Rails::Initializable+ module and its +initialize+ method is defined to just set up a couple of variables:
diff --git a/railties/guides/source/kindle/KINDLE.md b/railties/guides/source/kindle/KINDLE.md
new file mode 100644
index 0000000000..a7d9a4e4cf
--- /dev/null
+++ b/railties/guides/source/kindle/KINDLE.md
@@ -0,0 +1,26 @@
+# Rails Guides on the Kindle
+
+
+## Synopsis
+
+ 1. Obtain `kindlegen` from the link below and put the binary in your path
+ 2. Run `KINDLE=1 rake generate_guides` to generate the guides and compile the `.mobi` file
+ 3. Copy `output/kindle/rails_guides.mobi` to your Kindle
+
+## Resources
+
+ * [StackOverflow: Kindle Periodical Format](http://stackoverflow.com/questions/5379565/kindle-periodical-format)
+ * Example Periodical [.ncx](https://gist.github.com/808c971ed087b839d462) and [.opf](https://gist.github.com/d6349aa8488eca2ee6d0)
+ * [Kindle Publishing guidelines](http://kindlegen.s3.amazonaws.com/AmazonKindlePublishingGuidelines.pdf)
+ * [KindleGen & Kindle Previewer](http://www.amazon.com/gp/feature.html?ie=UTF8&docId=1000234621)
+
+## TODO
+
+### Post release
+
+ * Integrate generated Kindle document in to published HTML guides
+ * Tweak heading styles (most docs use h3/h4/h5, which end up being smaller than the text under it)
+ * Tweak table styles (smaller text? Many of the tables are unusable on a Kindle in portrait mode)
+ * Have the HTML/XML TOC 'drill down' into the TOCs of the individual guides
+ * `.epub` generation.
+
diff --git a/railties/guides/source/kindle/copyright.html.erb b/railties/guides/source/kindle/copyright.html.erb
new file mode 100644
index 0000000000..bd51d87383
--- /dev/null
+++ b/railties/guides/source/kindle/copyright.html.erb
@@ -0,0 +1 @@
+<%= render 'license' %> \ No newline at end of file
diff --git a/railties/guides/source/kindle/layout.html.erb b/railties/guides/source/kindle/layout.html.erb
new file mode 100644
index 0000000000..f0a286210b
--- /dev/null
+++ b/railties/guides/source/kindle/layout.html.erb
@@ -0,0 +1,27 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
+
+<title><%= yield(:page_title) || 'Ruby on Rails Guides' %></title>
+
+<link rel="stylesheet" type="text/css" href="stylesheets/kindle.css" />
+
+</head>
+<body class="guide">
+
+ <% if content_for? :header_section %>
+ <%= yield :header_section %>
+ <div class="pagebreak">
+ <% end %>
+
+ <% if content_for? :index_section %>
+ <%= yield :index_section %>
+ <div class="pagebreak">
+ <% end %>
+
+ <%= yield.html_safe %>
+</body>
+</html>
diff --git a/railties/guides/source/kindle/rails_guides.opf.erb b/railties/guides/source/kindle/rails_guides.opf.erb
new file mode 100644
index 0000000000..4e07664fd0
--- /dev/null
+++ b/railties/guides/source/kindle/rails_guides.opf.erb
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<package xmlns="http://www.idpf.org/2007/opf" version="2.0" unique-identifier="RailsGuides">
+<metadata>
+ <meta name="cover" content="cover" />
+ <dc-metadata xmlns:dc="http://purl.org/dc/elements/1.1/">
+
+ <dc:title>Ruby on Rails Guides (<%= @version %>)</dc:title>
+
+ <dc:language>en-us</dc:language>
+ <dc:creator>Ruby on Rails</dc:creator>
+ <dc:publisher>Ruby on Rails</dc:publisher>
+ <dc:subject>Reference</dc:subject>
+ <dc:date><%= Time.now.strftime('%Y-%m-%d') %></dc:date>
+
+ <dc:description>These guides are designed to make you immediately productive with Rails, and to help you understand how all of the pieces fit together.</dc:description>
+ </dc-metadata>
+ <x-metadata>
+ <output content-type="application/x-mobipocket-subscription-magazine" encoding="utf-8"/>
+ </x-metadata>
+</metadata>
+
+<manifest>
+ <!-- HTML content files [mandatory] -->
+ <% documents_flat.each do |document| %>
+ <item id="<%= document['url'] %>" media-type="text/html" href="<%= document['url'] %>" />
+ <% end %>
+
+ <% %w{toc.html credits.html welcome.html copyright.html}.each do |url| %>
+ <item id="<%= url %>" media-type="text/html" href="<%= url %>" />
+ <% end %>
+
+ <item id="toc" media-type="application/x-dtbncx+xml" href="toc.ncx" />
+
+ <item id="cover" media-type="image/jpeg" href="images/rails_guides_kindle_cover.jpg"/>
+</manifest>
+
+<spine toc="toc">
+ <itemref idref="toc.html" />
+ <itemref idref="welcome.html" />
+ <itemref idref="credits.html" />
+ <itemref idref="copyright.html" />
+ <% documents_flat.each do |document| %>
+ <itemref idref="<%= document['url'] %>" />
+ <% end %>
+</spine>
+
+<guide>
+ <reference type="toc" title="Table of Contents" href="toc.html"></reference>
+</guide>
+
+</package>
diff --git a/railties/guides/source/kindle/toc.html.erb b/railties/guides/source/kindle/toc.html.erb
new file mode 100644
index 0000000000..e013797dee
--- /dev/null
+++ b/railties/guides/source/kindle/toc.html.erb
@@ -0,0 +1,24 @@
+<% content_for :page_title do %>
+Ruby on Rails Guides
+<% end %>
+
+<h1>Table of Contents</h1>
+<div id="toc">
+ <ul><li><a href="welcome.html">Welcome</a></li></ul>
+<% documents_by_section.each_with_index do |section, i| %>
+ <h3><%= "#{i + 1}." %> <%= section['name'] %></h3>
+ <ul>
+ <% section['documents'].each do |document| %>
+ <li>
+ <a href="<%= document['url'] %>"><%= document['name'] %></a>
+ <% if document['work_in_progress']%>(WIP)<% end %>
+ </li>
+ <% end %>
+ </ul>
+<% end %>
+<hr />
+<ul>
+ <li><a href="credits.html">Credits</a></li>
+ <li><a href="copyright.html">Copyright &amp; License</a></li>
+<ul>
+</div>
diff --git a/railties/guides/source/kindle/toc.ncx.erb b/railties/guides/source/kindle/toc.ncx.erb
new file mode 100644
index 0000000000..2c6d8e3bdf
--- /dev/null
+++ b/railties/guides/source/kindle/toc.ncx.erb
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE ncx PUBLIC "-//NISO//DTD ncx 2005-1//EN"
+ "http://www.daisy.org/z3986/2005/ncx-2005-1.dtd">
+
+<ncx xmlns="http://www.daisy.org/z3986/2005/ncx/" version="2005-1" xml:lang="en-US">
+<head>
+ <meta name="dtb:uid" content="RailsGuides"/>
+ <meta name="dtb:depth" content="2"/>
+ <meta name="dtb:totalPageCount" content="0"/>
+ <meta name="dtb:maxPageNumber" content="0"/>
+</head>
+<docTitle><text>Ruby on Rails Guides</text></docTitle>
+<docAuthor><text>docrails</text></docAuthor>
+<navMap>
+ <navPoint playOrder="0" class="periodical" id="periodical">
+ <navLabel>
+ <text>Table of Contents</text>
+ </navLabel>
+ <content src="toc.html"/>
+
+ <navPoint class="section" id="welcome" playOrder="1">
+ <navLabel>
+ <text>Introduction</text>
+ </navLabel>
+ <content src="welcome.html"/>
+
+ <navPoint class="article" id="welcome" playOrder="2">
+ <navLabel>
+ <text>Welcome</text>
+ </navLabel>
+ <content src="welcome.html"/>
+ </navPoint>
+ <navPoint class="article" id="credits" playOrder="3">
+ <navLabel><text>Credits</text></navLabel>
+ <content src="credits.html">
+ </navPoint>
+ <navPoint class="article" id="copyright" playOrder="4">
+ <navLabel><text>Copyright &amp; License</text></navLabel>
+ <content src="copyright.html">
+ </navPoint>
+ </navPoint>
+
+ <% play_order = 4 %>
+ <% documents_by_section.each_with_index do |section, section_no| %>
+ <navPoint class="section" id="chapter_<%= section_no + 1 %>" playOrder="<% play_order +=1 %>">
+ <navLabel>
+ <text><%= section['name'] %></text>
+ </navLabel>
+ <content src="<%=section['documents'].first['url'] %>"/>
+
+ <% section['documents'].each_with_index do |document, document_no| %>
+ <navPoint class="article" id="_<%=section_no+1%>.<%=document_no+1%>" playOrder="<%=play_order +=1 %>">
+ <navLabel>
+ <text><%= document['name'] %></text>
+ </navLabel>
+ <content src="<%=document['url'] %>"/>
+ </navPoint>
+ <% end %>
+ </navPoint>
+ <% end %>
+
+ </navPoint>
+</navMap>
+</ncx>
diff --git a/railties/guides/source/kindle/welcome.html.erb b/railties/guides/source/kindle/welcome.html.erb
new file mode 100644
index 0000000000..e30704c4e6
--- /dev/null
+++ b/railties/guides/source/kindle/welcome.html.erb
@@ -0,0 +1,5 @@
+<%= render 'welcome' %>
+
+<h3>Kindle Edition</h3>
+
+The Kindle Edition of the Rails Guides should be considered a work in progress. Feedback is really welcome, please see the "Feedback" section at the end of each guide for instructions.
diff --git a/railties/guides/source/layout.html.erb b/railties/guides/source/layout.html.erb
index 4c979888b7..35b6fc7014 100644
--- a/railties/guides/source/layout.html.erb
+++ b/railties/guides/source/layout.html.erb
@@ -38,57 +38,21 @@
<div id="header">
<div class="wrapper clearfix">
<h1><a href="index.html" title="Return to home page">Guides.rubyonrails.org</a></h1>
- <p class="hide"><a href="#mainCol">Skip navigation</a>.</p>
<ul class="nav">
<li><a href="index.html">Home</a></li>
<li class="index"><a href="index.html" onclick="guideMenu(); return false;" id="guidesMenu">Guides Index</a>
<div id="guides" class="clearfix" style="display: none;">
<hr />
- <dl class="L">
- <dt>Start Here</dt>
- <dd><a href="getting_started.html">Getting Started with Rails</a></dd>
- <dt>Models</dt>
- <dd><a href="migrations.html">Rails Database Migrations</a></dd>
- <dd><a href="active_record_validations_callbacks.html">Active Record Validations and Callbacks</a></dd>
- <dd><a href="association_basics.html">Active Record Associations</a></dd>
- <dd><a href="active_record_querying.html">Active Record Query Interface</a></dd>
- <dt>Views</dt>
- <dd><a href="layouts_and_rendering.html">Layouts and Rendering in Rails</a></dd>
- <dd><a href="form_helpers.html">Action View Form Helpers</a></dd>
- <dt>Controllers</dt>
- <dd><a href="action_controller_overview.html">Action Controller Overview</a></dd>
- <dd><a href="routing.html">Rails Routing from the Outside In</a></dd>
- </dl>
- <dl class="R">
- <dt>Digging Deeper</dt>
- <dd><a href="active_support_core_extensions.html">Active Support Core Extensions</a></dd>
- <dd><a href="i18n.html">Rails Internationalization API</a></dd>
- <dd><a href="action_mailer_basics.html">Action Mailer Basics</a></dd>
- <dd><a href="testing.html">Testing Rails Applications</a></dd>
- <dd><a href="security.html">Securing Rails Applications</a></dd>
- <dd><a href="debugging_rails_applications.html">Debugging Rails Applications</a></dd>
- <dd><a href="performance_testing.html">Performance Testing Rails Applications</a></dd>
- <dd><a href="configuring.html">Configuring Rails Applications</a></dd>
- <dd><a href="command_line.html">Rails Command Line Tools and Rake Tasks</a></dd>
- <dd><a href="caching_with_rails.html">Caching with Rails</a></dd>
- <dd><a href="asset_pipeline.html">Asset Pipeline</a></dd>
-
- <dt>Extending Rails</dt>
- <dd><a href="plugins.html">The Basics of Creating Rails Plugins</a></dd>
- <dd><a href="rails_on_rack.html">Rails on Rack</a></dd>
- <dd><a href="generators.html">Creating and Customizing Rails Generators</a></dd>
-
- <dt>Contributing to Ruby on Rails</dt>
- <dd><a href="contributing_to_ruby_on_rails.html">Contributing to Ruby on Rails</a></dd>
- <dd><a href="api_documentation_guidelines.html">API Documentation Guidelines</a></dd>
- <dd><a href="ruby_on_rails_guides_guidelines.html">Ruby on Rails Guides Guidelines</a></dd>
-
- <dt>Release Notes</dt>
- <dd><a href="3_1_release_notes.html">Ruby on Rails 3.1 Release Notes</a></dd>
- <dd><a href="3_0_release_notes.html">Ruby on Rails 3.0 Release Notes</a></dd>
- <dd><a href="2_3_release_notes.html">Ruby on Rails 2.3 Release Notes</a></dd>
- <dd><a href="2_2_release_notes.html">Ruby on Rails 2.2 Release Notes</a></dd>
- </dl>
+ <% ['L', 'R'].each do |position| %>
+ <dl class="<%= position %>">
+ <% docs_for_menu(position).each do |section| %>
+ <dt><%= section['name'] %></dt>
+ <% finished_documents(section['documents']).each do |document| %>
+ <dd><a href="<%= document['url'] %>"><%= document['name'] %></a></dd>
+ <% end %>
+ <% end %>
+ </dl>
+ <% end %>
</div>
</li>
<li><a href="contributing_to_ruby_on_rails.html">Contribute</a></li>
@@ -143,8 +107,7 @@
<hr class="hide" />
<div id="footer">
<div class="wrapper">
- <p>This work is licensed under a <a href="http://creativecommons.org/licenses/by-sa/3.0/">Creative Commons Attribution-Share Alike 3.0</a> License</p>
- <p>"Rails", "Ruby on Rails", and the Rails logo are trademarks of David Heinemeier Hansson. All rights reserved.</p>
+ <%= render 'license' %>
</div>
</div>
diff --git a/railties/guides/source/layouts_and_rendering.textile b/railties/guides/source/layouts_and_rendering.textile
index df7b9b364c..6ac9645917 100644
--- a/railties/guides/source/layouts_and_rendering.textile
+++ b/railties/guides/source/layouts_and_rendering.textile
@@ -495,7 +495,7 @@ def show
end
</ruby>
-Make sure to use +and return+ and not +&amp;&amp; return+, since +&amp;&amp; return+ will not work due to the operator precedence in the Ruby Language.
+Make sure to use +and return+ instead of +&amp;&amp; return+ because +&amp;&amp; return+ will not work due to the operator precedence in the Ruby Language.
Note that the implicit render done by ActionController detects if +render+ has been called, so the following will work without errors:
@@ -656,7 +656,7 @@ WARNING: The asset tag helpers do _not_ verify the existence of the assets at th
h5. Linking to Feeds with the +auto_discovery_link_tag+
-The +auto_discovery_link_tag+ helper builds HTML that most browsers and newsreaders can use to detect the presences of RSS or ATOM feeds. It takes the type of the link (+:rss+ or +:atom+), a hash of options that are passed through to url_for, and a hash of options for the tag:
+The +auto_discovery_link_tag+ helper builds HTML that most browsers and newsreaders can use to detect the presence of RSS or Atom feeds. It takes the type of the link (+:rss+ or +:atom+), a hash of options that are passed through to url_for, and a hash of options for the tag:
<erb>
<%= auto_discovery_link_tag(:rss, {:action => "feed"},
@@ -667,23 +667,37 @@ There are three tag options available for the +auto_discovery_link_tag+:
* +:rel+ specifies the +rel+ value in the link. The default value is "alternate".
* +:type+ specifies an explicit MIME type. Rails will generate an appropriate MIME type automatically.
-* +:title+ specifies the title of the link. The default value is the upshifted +:type+ value, for example, "ATOM" or "RSS".
+* +:title+ specifies the title of the link. The default value is the uppercased +:type+ value, for example, "ATOM" or "RSS".
h5. Linking to JavaScript Files with the +javascript_include_tag+
-The +javascript_include_tag+ helper returns an HTML +script+ tag for each source provided. Rails looks in +public/javascripts+ for these files by default, but you can specify a full path relative to the document root, or a URL, if you prefer. For example, to include +public/javascripts/main.js+:
+The +javascript_include_tag+ helper returns an HTML +script+ tag for each source provided.
+
+If you are using Rails with the "Asset Pipeline":asset_pipeline.html enabled, this helper will generate a link to +/assets/javascripts/+ rather than +public/javascripts+ which was used in earlier versions of Rails. This link is then served by the Sprockets gem, which was introduced in Rails 3.1.
+
+A JavaScript file within a Rails application or Rails engine goes in one of three locations: +app/assets+, +lib/assets+ or +vendor/assets+. These locations are explained in detail in the "Asset Organization section in the Asset Pipeline Guide":asset_pipeline.html#asset-organization
+
+You can specify a full path relative to the document root, or a URL, if you prefer. For example, to link to a JavaScript file that is inside a directory called +javascripts+ inside of one of +app/assets+, +lib/assets+ or +vendor/assets+, you would do this:
<erb>
<%= javascript_include_tag "main" %>
</erb>
-To include +public/javascripts/main.js+ and +public/javascripts/columns.js+:
+Rails will then output a +script+ tag such as this:
+
+<html>
+<script src='/assets/main.js' type="text/javascript"></script>
+</html>
+
+The request to this asset is then served by the Sprockets gem.
+
+To include multiple files such as +app/assets/javascripts/main.js+ and +app/assets/javascripts/columns.js+ at the same time:
<erb>
<%= javascript_include_tag "main", "columns" %>
</erb>
-To include +public/javascripts/main.js+ and +public/photos/columns.js+:
+To include +app/assets/javascripts/main.js+ and +app/assets/javascripts/photos/columns.js+:
<erb>
<%= javascript_include_tag "main", "/photos/columns" %>
@@ -701,15 +715,38 @@ If the application does not use the asset pipeline, the +:defaults+ option loads
<%= javascript_include_tag :defaults %>
</erb>
-And you can in any case override the expansion in <tt>config/application.rb</tt>:
+Outputting +script+ tags such as this:
+
+<html>
+<script src="/javascripts/jquery.js" type="text/javascript"></script>
+<script src="/javascripts/jquery_ujs.js" type="text/javascript"></script>
+</html>
+
+These two files for jQuery, +jquery.js+ and +jquery_ujs.js+ must be placed inside +public/javascripts+ if the application doesn't use the asset pipeline. These files can be downloaded from the "jquery-rails repository on GitHub":https://github.com/indirect/jquery-rails/tree/master/vendor/assets/javascripts
+
+WARNING: If you are using the asset pipeline, this tag will render a +script+ tag for an asset called +defaults.js+, which would not exist in your application unless you've explicitly created it.
+
+And you can in any case override the +:defaults+ expansion in <tt>config/application.rb</tt>:
<ruby>
config.action_view.javascript_expansions[:defaults] = %w(foo.js bar.js)
</ruby>
-When using <tt>:defaults</tt>, if an <tt>application.js</tt> file exists in <tt>public/javascripts</tt> it will be included as well at then end.
+You can also define new defaults:
+
+<ruby>
+config.action_view.javascript_expansions[:projects] = %w(projects.js tickets.js)
+</ruby>
+
+And use them by referencing them exactly like +:defaults+:
-Also, the +:all+ option loads every JavaScript file in +public/javascripts+:
+<erb>
+<%= javascript_include_tag :projects %>
+</erb>
+
+When using <tt>:defaults</tt>, if an <tt>application.js</tt> file exists in <tt>public/javascripts</tt> it will be included as well at the end.
+
+Also, if the asset pipeline is disabled, the +:all+ expansion loads every JavaScript file in +public/javascripts+:
<erb>
<%= javascript_include_tag :all %>
@@ -740,19 +777,23 @@ You can even use dynamic paths such as +cache/#{current_site}/main/display+.
h5. Linking to CSS Files with the +stylesheet_link_tag+
-The +stylesheet_link_tag+ helper returns an HTML +&lt;link&gt;+ tag for each source provided. Rails looks in +public/stylesheets+ for these files by default, but you can specify a full path relative to the document root, or a URL, if you prefer. For example, to include +public/stylesheets/main.css+:
+The +stylesheet_link_tag+ helper returns an HTML +&lt;link&gt;+ tag for each source provided.
+
+If you are using Rails with the "Asset Pipeline" enabled, this helper will generate a link to +/assets/stylesheets/+. This link is then processed by the Sprockets gem. A stylesheet file can be stored in one of three locations: +app/assets+, +lib/assets+ or +vendor/assets+.
+
+You can specify a full path relative to the document root, or a URL. For example, to link to a stylesheet file that is inside a directory called +stylesheets+ inside of one of +app/assets+, +lib/assets+ or +vendor/assets+, you would do this:
<erb>
<%= stylesheet_link_tag "main" %>
</erb>
-To include +public/stylesheets/main.css+ and +public/stylesheets/columns.css+:
+To include +app/assets/stylesheets/main.css+ and +app/assets/stylesheets/columns.css+:
<erb>
<%= stylesheet_link_tag "main", "columns" %>
</erb>
-To include +public/stylesheets/main.css+ and +public/photos/columns.css+:
+To include +app/assets/stylesheets/main.css+ and +app/assets/stylesheets/photos/columns.css+:
<erb>
<%= stylesheet_link_tag "main", "/photos/columns" %>
@@ -770,7 +811,7 @@ By default, the +stylesheet_link_tag+ creates links with +media="screen" rel="st
<%= stylesheet_link_tag "main_print", :media => "print" %>
</erb>
-The +all+ option links every CSS file in +public/stylesheets+:
+If the asset pipeline is disabled, the +all+ option links every CSS file in +public/stylesheets+:
<erb>
<%= stylesheet_link_tag :all %>
diff --git a/railties/guides/source/migrations.textile b/railties/guides/source/migrations.textile
index 23e36b39f9..c11f8e221b 100644
--- a/railties/guides/source/migrations.textile
+++ b/railties/guides/source/migrations.textile
@@ -1,12 +1,24 @@
h2. Migrations
-Migrations are a convenient way for you to alter your database in a structured and organized manner. You could edit fragments of SQL by hand but you would then be responsible for telling other developers that they need to go and run them. You'd also have to keep track of which changes need to be run against the production machines next time you deploy.
-
-Active Record tracks which migrations have already been run so all you have to do is update your source and run +rake db:migrate+. Active Record will work out which migrations should be run. It will also update your +db/schema.rb+ file to match the structure of your database.
-
-Migrations also allow you to describe these transformations using Ruby. The great thing about this is that (like most of Active Record's functionality) it is database independent: you don't need to worry about the precise syntax of +CREATE TABLE+ any more than you worry about variations on +SELECT *+ (you can drop down to raw SQL for database specific features). For example you could use SQLite3 in development, but MySQL in production.
-
-You'll learn all about migrations including:
+Migrations are a convenient way for you to alter your database in a structured
+and organized manner. You could edit fragments of SQL by hand but you would then
+be responsible for telling other developers that they need to go and run them.
+You'd also have to keep track of which changes need to be run against the
+production machines next time you deploy.
+
+Active Record tracks which migrations have already been run so all you have to
+do is update your source and run +rake db:migrate+. Active Record will work out
+which migrations should be run. It will also update your +db/schema.rb+ file to
+match the structure of your database.
+
+Migrations also allow you to describe these transformations using Ruby. The
+great thing about this is that (like most of Active Record's functionality) it
+is database independent: you don't need to worry about the precise syntax of
++CREATE TABLE+ any more than you worry about variations on +SELECT *+ (you can
+drop down to raw SQL for database specific features). For example you could use
+SQLite3 in development, but MySQL in production.
+
+In this guide, you'll learn all about migrations including:
* The generators you can use to create them
* The methods Active Record provides to manipulate your database
@@ -17,7 +29,8 @@ endprologue.
h3. Anatomy of a Migration
-Before we dive into the details of a migration, here are a few examples of the sorts of things you can do:
+Before we dive into the details of a migration, here are a few examples of the
+sorts of things you can do:
<ruby>
class CreateProducts < ActiveRecord::Migration
@@ -36,9 +49,15 @@ class CreateProducts < ActiveRecord::Migration
end
</ruby>
-This migration adds a table called +products+ with a string column called +name+ and a text column called +description+. A primary key column called +id+ will also be added, however since this is the default we do not need to ask for this. The timestamp columns +created_at+ and +updated_at+ which Active Record populates automatically will also be added. Reversing this migration is as simple as dropping the table.
+This migration adds a table called +products+ with a string column called +name+
+and a text column called +description+. A primary key column called +id+ will
+also be added, however since this is the default we do not need to ask for this.
+The timestamp columns +created_at+ and +updated_at+ which Active Record
+populates automatically will also be added. Reversing this migration is as
+simple as dropping the table.
-Migrations are not limited to changing the schema. You can also use them to fix bad data in the database or populate new fields:
+Migrations are not limited to changing the schema. You can also use them to fix
+bad data in the database or populate new fields:
<ruby>
class AddReceiveNewsletterToUsers < ActiveRecord::Migration
@@ -55,12 +74,18 @@ class AddReceiveNewsletterToUsers < ActiveRecord::Migration
end
</ruby>
-NOTE: Some "caveats":#using-models-in-your-migrations apply to using models in your migrations.
+NOTE: Some "caveats":#using-models-in-your-migrations apply to using models in
+your migrations.
-This migration adds a +receive_newsletter+ column to the +users+ table. We want it to default to +false+ for new users, but existing users are considered
-to have already opted in, so we use the User model to set the flag to +true+ for existing users.
+This migration adds a +receive_newsletter+ column to the +users+ table. We want
+it to default to +false+ for new users, but existing users are considered to
+have already opted in, so we use the User model to set the flag to +true+ for
+existing users.
-Rails 3.1 makes migrations smarter by providing a new <tt>change</tt> method. This method is preferred for writing constructive migrations (adding columns or tables). The migration knows how to migrate your database and reverse it when the migration is rolled back without the need to write a separate +down+ method.
+Rails 3.1 makes migrations smarter by providing a new <tt>change</tt> method.
+This method is preferred for writing constructive migrations (adding columns or
+tables). The migration knows how to migrate your database and reverse it when
+the migration is rolled back without the need to write a separate +down+ method.
<ruby>
class CreateProducts < ActiveRecord::Migration
@@ -77,64 +102,112 @@ end
h4. Migrations are Classes
-A migration is a subclass of <tt>ActiveRecord::Migration</tt> that implements two methods: +up+ (perform the required transformations) and +down+ (revert them).
+A migration is a subclass of <tt>ActiveRecord::Migration</tt> that implements
+two methods: +up+ (perform the required transformations) and +down+ (revert
+them).
-Active Record provides methods that perform common data definition tasks in a database independent way (you'll read about them in detail later):
+Active Record provides methods that perform common data definition tasks in a
+database independent way (you'll read about them in detail later):
-* +create_table+
-* +change_table+
-* +drop_table+
* +add_column+
+* +add_index+
* +change_column+
-* +rename_column+
+* +change_table+
+* +create_table+
+* +create_join_table+
+* +drop_table+
* +remove_column+
-* +add_index+
* +remove_index+
+* +rename_column+
-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+ method 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).
+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+ method 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 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.
+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 rollback
+the changes that were made by hand.
h4. What's in a Name
-Migrations are stored in files in +db/migrate+, one for each migration class. The name of the file is of the form +YYYYMMDDHHMMSS_create_products.rb+, that is to say a UTC timestamp identifying the migration followed by an underscore followed by the name of the migration. The name of the migration class (CamelCased version) should match the latter part of the file name. For example +20080906120000_create_products.rb+ should define class +CreateProducts+ and +20080906120001_add_details_to_products.rb+ should define +AddDetailsToProducts+. If you do feel the need to change the file name then you <em>have to</em> update the name of the class inside or Rails will complain about a missing class.
-
-Internally Rails only uses the migration's number (the timestamp) to identify them. Prior to Rails 2.1 the migration number started at 1 and was incremented each time a migration was generated. With multiple developers it was easy for these to clash requiring you to rollback migrations and renumber them. With Rails 2.1 this is largely avoided by using the creation time of the migration to identify them. You can revert to the old numbering scheme by adding the following line to +config/application.rb+.
+Migrations are stored as files in the +db/migrate+ directory, one for each
+migration class. The name of the file is of the form
++YYYYMMDDHHMMSS_create_products.rb+, that is to say a UTC timestamp
+identifying the migration followed by an underscore followed by the name
+of the migration. The name of the migration class (CamelCased version)
+should match the latter part of the file name. For example
++20080906120000_create_products.rb+ should define class +CreateProducts+ and
++20080906120001_add_details_to_products.rb+ should define
++AddDetailsToProducts+. If you do feel the need to change the file name then you
+<em>have to</em> update the name of the class inside or Rails will complain
+about a missing class.
+
+Internally Rails only uses the migration's number (the timestamp) to identify
+them. Prior to Rails 2.1 the migration number started at 1 and was incremented
+each time a migration was generated. With multiple developers it was easy for
+these to clash requiring you to rollback migrations and renumber them. With
+Rails 2.1+ this is largely avoided by using the creation time of the migration
+to identify them. You can revert to the old numbering scheme by adding the
+following line to +config/application.rb+.
<ruby>
config.active_record.timestamped_migrations = false
</ruby>
-The combination of timestamps and recording which migrations have been run allows Rails to handle common situations that occur with multiple developers.
+The combination of timestamps and recording which migrations have been run
+allows Rails to handle common situations that occur with multiple developers.
-For example Alice adds migrations +20080906120000+ and +20080906123000+ and Bob adds +20080906124500+ and runs it. Alice finishes her changes and checks in her migrations and Bob pulls down the latest changes. Rails knows that it has not run Alice's two migrations so +rake db:migrate+ would run them (even though Bob's migration with a later timestamp has been run), and similarly migrating down would not run their +down+ methods.
+For example Alice adds migrations +20080906120000+ and +20080906123000+ and Bob
+adds +20080906124500+ and runs it. Alice finishes her changes and checks in her
+migrations and Bob pulls down the latest changes. When Bob runs +rake db:migrate+,
+Rails knows that it has not run Alice's two migrations so it executes the +up+ method for each migration.
-Of course this is no substitution for communication within the team. For example, if Alice's migration removed a table that Bob's migration assumed to exist, then trouble would certainly strike.
+Of course this is no substitution for communication within the team. For
+example, if Alice's migration removed a table that Bob's migration assumed to
+exist, then trouble would certainly strike.
h4. Changing Migrations
-Occasionally you will make a mistake when writing a migration. If you have already run the migration then you cannot just edit the migration and run the migration again: Rails thinks it has already run the migration and so will do nothing when you run +rake db:migrate+. You must rollback the migration (for example with +rake db:rollback+), edit your migration and then run +rake db:migrate+ to run the corrected version.
+Occasionally you will make a mistake when writing a migration. If you have
+already run the migration then you cannot just edit the migration and run the
+migration again: Rails thinks it has already run the migration and so will do
+nothing when you run +rake db:migrate+. You must rollback the migration (for
+example with +rake db:rollback+), edit your migration and then run +rake db:migrate+ to run the corrected version.
-In general editing existing migrations is not a good idea: you will be creating extra work for yourself and your co-workers and cause major headaches if the existing version of the migration has already been run on production machines. Instead, you should write a new migration that performs the changes you require. Editing a freshly generated migration that has not yet been committed to source control (or, more generally, which has not been propagated beyond your development machine) is relatively harmless.
+In general editing existing migrations is not a good idea: you will be creating
+extra work for yourself and your co-workers and cause major headaches if the
+existing version of the migration has already been run on production machines.
+Instead, you should write a new migration that performs the changes you require.
+Editing a freshly generated migration that has not yet been committed to source
+control (or, more generally, which has not been propagated beyond your
+development machine) is relatively harmless.
h4. Supported Types
-Active Record supports the following types:
+Active Record supports the following database column types:
+* +:binary+
+* +:boolean+
+* +:date+
+* +:datetime+
+* +:decimal+
+* +:float+
+* +:integer+
* +:primary_key+
* +:string+
* +:text+
-* +:integer+
-* +:float+
-* +:decimal+
-* +:datetime+
-* +:timestamp+
* +:time+
-* +:date+
-* +:binary+
-* +:boolean+
+* +:timestamp+
-These will be mapped onto an appropriate underlying database type. For example, with MySQL the type +:string+ is mapped to +VARCHAR(255)+. You can create columns of types not supported by Active Record when using the non-sexy syntax, for example
+These will be mapped onto an appropriate underlying database type. For example,
+with MySQL the type +:string+ is mapped to +VARCHAR(255)+. You can create
+columns of types not supported by Active Record when using the non-sexy syntax,
+for example
<ruby>
create_table :products do |t|
@@ -148,7 +221,10 @@ h3. Creating a Migration
h4. Creating a Model
-The model and scaffold generators will create migrations appropriate for adding a new model. This migration will already contain instructions for creating the relevant table. If you tell Rails what columns you want, then statements for adding these columns will also be created. For example, running
+The model and scaffold generators will create migrations appropriate for adding
+a new model. This migration will already contain instructions for creating the
+relevant table. If you tell Rails what columns you want, then statements for
+adding these columns will also be created. For example, running
<shell>
$ rails generate model Product name:string description:text
@@ -169,12 +245,15 @@ class CreateProducts < ActiveRecord::Migration
end
</ruby>
-You can append as many column name/type pairs as you want. By default +t.timestamps+ (which creates the +updated_at+ and +created_at+ columns that
-are automatically populated by Active Record) will be added for you.
+You can append as many column name/type pairs as you want. By default, the
+generated migration will include +t.timestamps+ (which creates the
++updated_at+ and +created_at+ columns that are automatically populated
+by Active Record).
h4. Creating a Standalone Migration
-If you are creating migrations for other purposes (for example to add a column to an existing table) then you can use the migration generator:
+If you are creating migrations for other purposes (for example to add a column
+to an existing table) then you can also use the migration generator:
<shell>
$ rails generate migration AddPartNumberToProducts
@@ -189,7 +268,9 @@ class AddPartNumberToProducts < ActiveRecord::Migration
end
</ruby>
-If the migration name is of the form "AddXXXToYYY" or "RemoveXXXFromYYY" and is followed by a list of column names and types then a migration containing the appropriate +add_column+ and +remove_column+ statements will be created.
+If the migration name is of the form "AddXXXToYYY" or "RemoveXXXFromYYY" and is
+followed by a list of column names and types then a migration containing the
+appropriate +add_column+ and +remove_column+ statements will be created.
<shell>
$ rails generate migration AddPartNumberToProducts part_number:string
@@ -242,17 +323,23 @@ class AddDetailsToProducts < ActiveRecord::Migration
end
</ruby>
-As always, what has been generated for you is just a starting point. You can add or remove from it as you see fit.
+As always, what has been generated for you is just a starting point. You can add
+or remove from it as you see fit by editing the
+db/migrate/YYYYMMDDHHMMSS_add_details_to_products.rb file.
-NOTE: The generated migration file for destructive migrations will still be old-style using the +up+ and +down+ methods. This is because Rails doesn't know the original data types defined when you made the original changes.
+NOTE: The generated migration file for destructive migrations will still be
+old-style using the +up+ and +down+ methods. This is because Rails needs to know
+the original data types defined when you made the original changes.
h3. Writing a Migration
-Once you have created your migration using one of the generators it's time to get to work!
+Once you have created your migration using one of the generators it's time to
+get to work!
h4. Creating a Table
-Migration method +create_table+ will be one of your workhorses. A typical use would be
+Migration method +create_table+ will be one of your workhorses. A typical use
+would be
<ruby>
create_table :products do |t|
@@ -260,9 +347,11 @@ create_table :products do |t|
end
</ruby>
-which creates a +products+ table with a column called +name+ (and as discussed below, an implicit +id+ column).
+which creates a +products+ table with a column called +name+ (and as discussed
+below, an implicit +id+ column).
-The object yielded to the block allows you to create columns on the table. There are two ways of doing it. The first (traditional) form looks like
+The object yielded to the block allows you to create columns on the table. There
+are two ways of doing it. The first (traditional) form looks like
<ruby>
create_table :products do |t|
@@ -270,7 +359,9 @@ create_table :products do |t|
end
</ruby>
-The second form, the so called "sexy" migration, drops the somewhat redundant +column+ method. Instead, the +string+, +integer+, etc. methods create a column of that type. Subsequent parameters are the same.
+The second form, the so called "sexy" migration, drops the somewhat redundant
++column+ method. Instead, the +string+, +integer+, etc. methods create a column
+of that type. Subsequent parameters are the same.
<ruby>
create_table :products do |t|
@@ -278,7 +369,12 @@ create_table :products do |t|
end
</ruby>
-By default, +create_table+ will create a primary key called +id+. You can change the name of the primary key with the +:primary_key+ option (don't forget to update the corresponding model) or, if you don't want a primary key at all (for example for a HABTM join table), you can pass the option +:id => false+. If you need to pass database specific options you can place an SQL fragment in the +:options+ option. For example,
+By default, +create_table+ will create a primary key called +id+. You can change
+the name of the primary key with the +:primary_key+ option (don't forget to
+update the corresponding model) or, if you don't want a primary key at all (for
+example for a HABTM join table), you can pass the option +:id => false+. If you
+need to pass database specific options you can place an SQL fragment in the
++:options+ option. For example,
<ruby>
create_table :products, :options => "ENGINE=BLACKHOLE" do |t|
@@ -286,11 +382,43 @@ create_table :products, :options => "ENGINE=BLACKHOLE" do |t|
end
</ruby>
-will append +ENGINE=BLACKHOLE+ to the SQL statement used to create the table (when using MySQL, the default is +ENGINE=InnoDB+).
+will append +ENGINE=BLACKHOLE+ to the SQL statement used to create the table
+(when using MySQL, the default is +ENGINE=InnoDB+).
+
+h4. Creating a Join Table
+
+Migration method +create_join_table+ creates a HABTM join table. A typical use
+would be
+
+<ruby>
+create_join_table :products, :categories
+</ruby>
+
+which creates a +categories_products+ table with two columns called +category_id+ and +product_id+.
+These columns have the option +:null+ set to +false+ by default.
+
+You can pass the option +:table_name+ with you want to customize the table name. For example,
+
+<ruby>
+create_join_table :products, :categories, :table_name => :categorization
+</ruby>
+
+will create a +categorization+ table.
+
+By default, +create_join_table+ will create two columns with no options, but you can specify these
+options using the +:column_options+ option. For example,
+
+<ruby>
+create_join_table :products, :categories, :column_options => {:null => true}
+</ruby>
+
+will create the +product_id+ and +category_id+ with the +:null+ option as +true+.
h4. Changing Tables
-A close cousin of +create_table+ is +change_table+, used for changing existing tables. It is used in a similar fashion to +create_table+ but the object yielded to the block knows more tricks. For example
+A close cousin of +create_table+ is +change_table+, used for changing existing
+tables. It is used in a similar fashion to +create_table+ but the object yielded
+to the block knows more tricks. For example
<ruby>
change_table :products do |t|
@@ -301,28 +429,23 @@ change_table :products do |t|
end
</ruby>
-removes the +description+ and +name+ columns, creates a +part_number+ column and adds an index on it. Finally it renames the +upccode+ column. This is the same as doing
-
-<ruby>
-remove_column :products, :description
-remove_column :products, :name
-add_column :products, :part_number, :string
-add_index :products, :part_number
-rename_column :products, :upccode, :upc_code
-</ruby>
-
-You don't have to keep repeating the table name and it groups all the statements related to modifying one particular table. The individual transformation names are also shorter, for example +remove_column+ becomes just +remove+ and +add_index+ becomes just +index+.
+removes the +description+ and +name+ columns, creates a +part_number+ string
+column and adds an index on it. Finally it renames the +upccode+ column.
h4. Special Helpers
-Active Record provides some shortcuts for common functionality. It is for example very common to add both the +created_at+ and +updated_at+ columns and so there is a method that does exactly that:
+Active Record provides some shortcuts for common functionality. It is for
+example very common to add both the +created_at+ and +updated_at+ columns and so
+there is a method that does exactly that:
<ruby>
create_table :products do |t|
t.timestamps
end
</ruby>
-will create a new products table with those two columns (plus the +id+ column) whereas
+
+will create a new products table with those two columns (plus the +id+ column)
+whereas
<ruby>
change_table :products do |t|
@@ -331,7 +454,8 @@ end
</ruby>
adds those columns to an existing table.
-The other helper is called +references+ (also available as +belongs_to+). In its simplest form it just adds some readability
+Another helper is called +references+ (also available as +belongs_to+). In its
+simplest form it just adds some readability.
<ruby>
create_table :products do |t|
@@ -339,24 +463,42 @@ create_table :products do |t|
end
</ruby>
-will create a +category_id+ column of the appropriate type. Note that you pass the model name, not the column name. Active Record adds the +_id+ for you. If you have polymorphic +belongs_to+ associations then +references+ will add both of the columns required:
+will create a +category_id+ column of the appropriate type. Note that you pass
+the model name, not the column name. Active Record adds the +_id+ for you. If
+you have polymorphic +belongs_to+ associations then +references+ will add both
+of the columns required:
<ruby>
create_table :products do |t|
t.references :attachment, :polymorphic => {:default => 'Photo'}
end
</ruby>
-will add an +attachment_id+ column and a string +attachment_type+ column with a default value of 'Photo'.
-NOTE: The +references+ helper does not actually create foreign key constraints for you. You will need to use +execute+ or a plugin that adds "foreign key support":#active-record-and-referential-integrity.
+will add an +attachment_id+ column and a string +attachment_type+ column with
+a default value of 'Photo'.
-If the helpers provided by Active Record aren't enough you can use the +execute+ method to execute arbitrary SQL.
+NOTE: The +references+ helper does not actually create foreign key constraints
+for you. You will need to use +execute+ or a plugin that adds "foreign key
+support":#active-record-and-referential-integrity.
-For more details and examples of individual methods, check the API documentation, in particular the documentation for "<tt>ActiveRecord::ConnectionAdapters::SchemaStatements</tt>":http://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/SchemaStatements.html (which provides the methods available in the +up+ and +down+ methods), "<tt>ActiveRecord::ConnectionAdapters::TableDefinition</tt>":http://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/TableDefinition.html (which provides the methods available on the object yielded by +create_table+) and "<tt>ActiveRecord::ConnectionAdapters::Table</tt>":http://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/Table.html (which provides the methods available on the object yielded by +change_table+).
+If the helpers provided by Active Record aren't enough you can use the +execute+
+method to execute arbitrary SQL.
-h4. Writing Your +change+ Method
+For more details and examples of individual methods, check the API documentation,
+in particular the documentation for
+"<tt>ActiveRecord::ConnectionAdapters::SchemaStatements</tt>":http://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/SchemaStatements.html
+(which provides the methods available in the +up+ and +down+ methods),
+"<tt>ActiveRecord::ConnectionAdapters::TableDefinition</tt>":http://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/TableDefinition.html
+(which provides the methods available on the object yielded by +create_table+)
+and
+"<tt>ActiveRecord::ConnectionAdapters::Table</tt>":http://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/Table.html
+(which provides the methods available on the object yielded by +change_table+).
-The +change+ method removes the need to write both +up+ and +down+ methods in those cases that Rails know how to revert the changes automatically. Currently, the +change+ method supports only these migration definitions:
+h4. Using the +change+ Method
+
+The +change+ method removes the need to write both +up+ and +down+ methods in
+those cases that Rails know how to revert the changes automatically. Currently,
+the +change+ method supports only these migration definitions:
* +add_column+
* +add_index+
@@ -367,15 +509,20 @@ The +change+ method removes the need to write both +up+ and +down+ methods in th
* +rename_index+
* +rename_table+
-If you're going to use other methods, you'll have to write the +up+ and +down+ methods normally.
+If you're going to need to use any other methods, you'll have to write the
++up+ and +down+ methods instead of using the +change+ method.
-h4. Writing Your +down+ Method
+h4. Using the +up+/+down+ Methods
-The +down+ method of your migration should revert the transformations done by the +up+ method. In other words, the database schema should be unchanged if you do an +up+ followed by a +down+. For example, if you create a table in the +up+ method, you should drop it in the +down+ method. It is wise to reverse the transformations in precisely the reverse order they were made in the +up+ method. For example,
+The +down+ method of your migration should revert the transformations done by
+the +up+ method. In other words, the database schema should be unchanged if you
+do an +up+ followed by a +down+. For example, if you create a table in the +up+
+method, you should drop it in the +down+ method. It is wise to reverse the
+transformations in precisely the reverse order they were made in the +up+
+method. For example,
<ruby>
class ExampleMigration < ActiveRecord::Migration
-
def up
create_table :products do |t|
t.references :category
@@ -387,47 +534,69 @@ class ExampleMigration < ActiveRecord::Migration
FOREIGN KEY (category_id)
REFERENCES categories(id)
SQL
-
add_column :users, :home_page_url, :string
-
rename_column :users, :email, :email_address
end
def down
rename_column :users, :email_address, :email
remove_column :users, :home_page_url
- execute "ALTER TABLE products DROP FOREIGN KEY fk_products_categories"
+ execute <<-SQL
+ ALTER TABLE products
+ DROP FOREIGN KEY fk_products_categories
+ SQL
drop_table :products
end
end
</ruby>
-Sometimes your migration will do something which is just plain irreversible; for example, it might destroy some data. In such cases, you can raise +ActiveRecord::IrreversibleMigration+ from your +down+ method. If someone tries to revert your migration, an error message will be displayed saying that it can't be done.
+Sometimes your migration will do something which is just plain irreversible; for
+example, it might destroy some data. In such cases, you can raise
++ActiveRecord::IrreversibleMigration+ from your +down+ method. If someone tries
+to revert your migration, an error message will be displayed saying that it
+can't be done.
h3. Running Migrations
-Rails provides a set of rake tasks to work with migrations which boil down to running certain sets of migrations. The very first migration related rake task you will use will probably be +db:migrate+. In its most basic form it just runs the +up+ method for all the migrations that have not yet been run. If there are no such migrations, it exits.
+Rails provides a set of rake tasks to work with migrations which boil down to
+running certain sets of migrations.
-Note that running the +db:migrate+ also invokes the +db:schema:dump+ task, which will update your db/schema.rb file to match the structure of your database.
+The very first migration related rake task you will use will probably be
++rake db:migrate+. In its most basic form it just runs the +up+ or +change+
+method for all the migrations that have not yet been run. If there are
+no such migrations, it exits. It will run these migrations in order based
+on the date of the migration.
-If you specify a target version, Active Record will run the required migrations (up or down) until it has reached the specified version. The
-version is the numerical prefix on the migration's filename. For example, to migrate to version 20080906120000 run
+Note that running the +db:migrate+ also invokes the +db:schema:dump+ task, which
+will update your db/schema.rb file to match the structure of your database.
+
+If you specify a target version, Active Record will run the required migrations
+(up, down or change) until it has reached the specified version. The version
+is the numerical prefix on the migration's filename. For example, to migrate
+to version 20080906120000 run
<shell>
$ rake db:migrate VERSION=20080906120000
</shell>
-If version 20080906120000 is greater than the current version (i.e., it is migrating upwards), this will run the +up+ method on all migrations up to and including 20080906120000. If migrating downwards, this will run the +down+ method on all the migrations down to, but not including, 20080906120000.
+If version 20080906120000 is greater than the current version (i.e., it is
+migrating upwards), this will run the +up+ method on all migrations up to and
+including 20080906120000, and will not execute any later migrations. If
+migrating downwards, this will run the +down+ method on all the migrations
+down to, but not including, 20080906120000.
h4. Rolling Back
-A common task is to rollback the last migration, for example if you made a mistake in it and wish to correct it. Rather than tracking down the version number associated with the previous migration you can run
+A common task is to rollback the last migration, for example if you made a
+mistake in it and wish to correct it. Rather than tracking down the version
+number associated with the previous migration you can run
<shell>
$ rake db:rollback
</shell>
-This will run the +down+ method from the latest migration. If you need to undo several migrations you can provide a +STEP+ parameter:
+This will run the +down+ method from the latest migration. If you need to undo
+several migrations you can provide a +STEP+ parameter:
<shell>
$ rake db:rollback STEP=3
@@ -435,46 +604,65 @@ $ rake db:rollback STEP=3
will run the +down+ method from the last 3 migrations.
-The +db:migrate:redo+ task is a shortcut for doing a rollback and then migrating back up again. As with the +db:rollback+ task, you can use the +STEP+ parameter if you need to go more than one version back, for example
+The +db:migrate:redo+ task is a shortcut for doing a rollback and then migrating
+back up again. As with the +db:rollback+ task, you can use the +STEP+ parameter
+if you need to go more than one version back, for example
<shell>
$ rake db:migrate:redo STEP=3
</shell>
-Neither of these Rake tasks do anything you could not do with +db:migrate+. They are simply more convenient, since you do not need to explicitly specify the version to migrate to.
+Neither of these Rake tasks do anything you could not do with +db:migrate+. They
+are simply more convenient, since you do not need to explicitly specify the
+version to migrate to.
+
+h4. Resetting the database
-Lastly, the +db:reset+ task will drop the database, recreate it and load the current schema into it.
+The +rake db:reset+ task will drop the database, recreate it and load the
+current schema into it.
-NOTE: This is not the same as running all the migrations - see the section on "schema.rb":#schema-dumping-and-you.
+NOTE: This is not the same as running all the migrations - see the section on
+"schema.rb":#schema-dumping-and-you.
-h4. Being Specific
+h4. Running specific migrations
-If you need to run a specific migration up or down, the +db:migrate:up+ and +db:migrate:down+ tasks will do that. Just specify the appropriate version and the corresponding migration will have its +up+ or +down+ method invoked, for example,
+If you need to run a specific migration up or down, the +db:migrate:up+ and
++db:migrate:down+ tasks will do that. Just specify the appropriate version and
+the corresponding migration will have its +up+ or +down+ method invoked, for
+example,
<shell>
$ rake db:migrate:up VERSION=20080906120000
</shell>
-will run the +up+ method from the 20080906120000 migration. These tasks check whether the migration has already run, so for example +db:migrate:up VERSION=20080906120000+ will do nothing if Active Record believes that 20080906120000 has already been run.
+will run the +up+ method from the 20080906120000 migration. These tasks still
+check whether the migration has already run, so for example +db:migrate:up
+VERSION=20080906120000+ will do nothing if Active Record believes that
+20080906120000 has already been run.
-h4. Being Talkative
+h4. Changing the output of running migrations
-By default migrations tell you exactly what they're doing and how long it took. A migration creating a table and adding an index might produce output like this
+By default migrations tell you exactly what they're doing and how long it took.
+A migration creating a table and adding an index might produce output like this
<shell>
-20080906170109 CreateProducts: migrating
+== CreateProducts: migrating =================================================
-- create_table(:products)
- -> 0.0021s
--- add_index(:products, :name)
- -> 0.0026s
-20080906170109 CreateProducts: migrated (0.0059s)
+ -> 0.0028s
+== CreateProducts: migrated (0.0028s) ========================================
</shell>
-Several methods are provided that allow you to control all this:
+Several methods are provided in migrations that allow you to control all this:
-* +suppress_messages+ takes a block as an argument and suppresses any output generated by the block.
-* +say+ takes a message argument and outputs it as is. A second boolean argument can be passed to specify whether to indent or not.
-* +say_with_time+ outputs text along with how long it took to run its block. If the block returns an integer it assumes it is the number of rows affected.
+|_.Method |_.Purpose|
+|suppress_messages |Takes a block as an argument and suppresses any output
+ generated by the block.|
+|say |Takes a message argument and outputs it as is. A second
+ boolean argument can be passed to specify whether to
+ indent or not.|
+|say_with_time |Outputs text along with how long it took to run its
+ block. If the block returns an integer it assumes it
+ is the number of rows affected.|
For example, this migration
@@ -502,37 +690,46 @@ end
generates the following output
<shell>
-20080906170109 CreateProducts: migrating
- Created a table
+== CreateProducts: migrating =================================================
+-- Created a table
-> and an index!
- Waiting for a while
- -> 10.0001s
+-- Waiting for a while
+ -> 10.0013s
-> 250 rows
-20080906170109 CreateProducts: migrated (10.0097s)
+== CreateProducts: migrated (10.0054s) =======================================
</shell>
-If you just want Active Record to shut up, then running +rake db:migrate VERBOSE=false+ will suppress all output.
+If you want Active Record to not output anything, then running +rake db:migrate
+VERBOSE=false+ will suppress all output.
h3. Using Models in Your Migrations
-When creating or updating data in a migration it is often tempting to use one of your models. After all, they exist to provide easy access to the underlying data. This can be done, but some caution should be observed.
+When creating or updating data in a migration it is often tempting to use one of
+your models. After all, they exist to provide easy access to the underlying
+data. This can be done, but some caution should be observed.
-For example, problems occur when the model uses database columns which are (1) not currently in the database and (2) will be created by this or a subsequent migration.
+For example, problems occur when the model uses database columns which are (1)
+not currently in the database and (2) will be created by this or a subsequent
+migration.
-Consider this example, where Alice and Bob are working on the same code base which contains a +Product+ model:
+Consider this example, where Alice and Bob are working on the same code base
+which contains a +Product+ model:
Bob goes on vacation.
-Alice creates a migration for the +products+ table which adds a new column and initializes it.
-She also adds a validation to the +Product+ model for the new column.
+Alice creates a migration for the +products+ table which adds a new column and
+initializes it. She also adds a validation to the +Product+ model for the new
+column.
<ruby>
# db/migrate/20100513121110_add_flag_to_product.rb
class AddFlagToProduct < ActiveRecord::Migration
def change
- add_column :products, :flag, :int
- Product.all.each { |f| f.update_attributes!(:flag => 'false') }
+ add_column :products, :flag, :boolean
+ Product.all.each do |product|
+ product.update_attributes!(:flag => 'false')
+ end
end
end
</ruby>
@@ -545,7 +742,9 @@ class Product < ActiveRecord::Base
end
</ruby>
-Alice adds a second migration which adds and initializes another column to the +products+ table and also adds a validation to the +Product+ model for the new column.
+Alice adds a second migration which adds and initializes another column to the
++products+ table and also adds a validation to the +Product+ model for the new
+column.
<ruby>
# db/migrate/20100515121110_add_fuzz_to_product.rb
@@ -553,7 +752,9 @@ Alice adds a second migration which adds and initializes another column to the +
class AddFuzzToProduct < ActiveRecord::Migration
def change
add_column :products, :fuzz, :string
- Product.all.each { |f| f.update_attributes! :fuzz => 'fuzzy' }
+ Product.all.each do |product|
+ product.update_attributes! :fuzz => 'fuzzy'
+ end
end
end
</ruby>
@@ -570,10 +771,14 @@ Both migrations work for Alice.
Bob comes back from vacation and:
-# updates the source - which contains both migrations and the latests version of the Product model.
-# runs outstanding migrations with +rake db:migrate+, which includes the one that updates the +Product+ model.
+# Updates the source - which contains both migrations and the latests version of
+the Product model.
+# Runs outstanding migrations with +rake db:migrate+, which
+includes the one that updates the +Product+ model.
-The migration crashes because when the model attempts to save, it tries to validate the second added column, which is not in the database when the _first_ migration runs:
+The migration crashes because when the model attempts to save, it tries to
+validate the second added column, which is not in the database when the _first_
+migration runs:
<plain>
rake aborted!
@@ -582,9 +787,12 @@ An error has occurred, this and all later migrations canceled:
undefined method `fuzz' for #<Product:0x000001049b14a0>
</plain>
-A fix for this is to create a local model within the migration. This keeps rails from running the validations, so that the migrations run to completion.
+A fix for this is to create a local model within the migration. This keeps rails
+from running the validations, so that the migrations run to completion.
-When using a faux model, it's a good idea to call +Product.reset_column_information+ to refresh the +ActiveRecord+ cache for the +Product+ model prior to updating data in the database.
+When using a faux model, it's a good idea to call
++Product.reset_column_information+ to refresh the +ActiveRecord+ cache for the
++Product+ model prior to updating data in the database.
If Alice had done this instead, there would have been no problem:
@@ -596,9 +804,11 @@ class AddFlagToProduct < ActiveRecord::Migration
end
def change
- add_column :products, :flag, :int
+ add_column :products, :flag, :integer
Product.reset_column_information
- Product.all.each { |f| f.update_attributes!(:flag => false) }
+ Product.all.each do |product|
+ product.update_attributes!(:flag => false)
+ end
end
end
</ruby>
@@ -609,32 +819,50 @@ end
class AddFuzzToProduct < ActiveRecord::Migration
class Product < ActiveRecord::Base
end
+
def change
add_column :products, :fuzz, :string
Product.reset_column_information
- Product.all.each { |f| f.update_attributes! :fuzz => 'fuzzy' }
+ Product.all.each do |product|
+ product.update_attributes!(:fuzz => 'fuzzy')
+ end
end
end
</ruby>
-
h3. Schema Dumping and You
h4. What are Schema Files for?
-Migrations, mighty as they may be, are not the authoritative source for your database schema. That role falls to either +db/schema.rb+ or an SQL file which Active Record generates by examining the database. They are not designed to be edited, they just represent the current state of the database.
+Migrations, mighty as they may be, are not the authoritative source for your
+database schema. That role falls to either +db/schema.rb+ or an SQL file which
+Active Record generates by examining the database. They are not designed to be
+edited, they just represent the current state of the database.
-There is no need (and it is error prone) to deploy a new instance of an app by replaying the entire migration history. It is much simpler and faster to just load into the database a description of the current schema.
+There is no need (and it is error prone) to deploy a new instance of an app by
+replaying the entire migration history. It is much simpler and faster to just
+load into the database a description of the current schema.
-For example, this is how the test database is created: the current development database is dumped (either to +db/schema.rb+ or +db/development.sql+) and then loaded into the test database.
+For example, this is how the test database is created: the current development
+database is dumped (either to +db/schema.rb+ or +db/structure.sql+) and then
+loaded into the test database.
-Schema files are also useful if you want a quick look at what attributes an Active Record object has. This information is not in the model's code and is frequently spread across several migrations, but is summed up in the schema file. The "annotate_models":https://github.com/ctran/annotate_models gem automatically adds and updates comments at the top of each model summarizing the schema if you desire that functionality.
+Schema files are also useful if you want a quick look at what attributes an
+Active Record object has. This information is not in the model's code and is
+frequently spread across several migrations, but the information is nicely
+summed up in the schema file. The
+"annotate_models":https://github.com/ctran/annotate_models gem automatically
+adds and updates comments at the top of each model summarizing the schema if
+you desire that functionality.
h4. Types of Schema Dumps
-There are two ways to dump the schema. This is set in +config/application.rb+ by the +config.active_record.schema_format+ setting, which may be either +:sql+ or +:ruby+.
+There are two ways to dump the schema. This is set in +config/application.rb+ by
+the +config.active_record.schema_format+ setting, which may be either +:sql+ or
++:ruby+.
-If +:ruby+ is selected then the schema is stored in +db/schema.rb+. If you look at this file you'll find that it looks an awful lot like one very big migration:
+If +:ruby+ is selected then the schema is stored in +db/schema.rb+. If you look
+at this file you'll find that it looks an awful lot like one very big migration:
<ruby>
ActiveRecord::Schema.define(:version => 20080906171750) do
@@ -646,28 +874,57 @@ ActiveRecord::Schema.define(:version => 20080906171750) do
create_table "products", :force => true do |t|
t.string "name"
- t.text "description"
+ t.text "description"
t.datetime "created_at"
t.datetime "updated_at"
- t.string "part_number"
+ t.string "part_number"
end
end
</ruby>
-In many ways this is exactly what it is. This file is created by inspecting the database and expressing its structure using +create_table+, +add_index+, and so on. Because this is database-independent, it could be loaded into any database that Active Record supports. This could be very useful if you were to distribute an application that is able to run against multiple databases.
-
-There is however a trade-off: +db/schema.rb+ cannot express database specific items such as foreign key constraints, triggers, or stored procedures. While in a migration you can execute custom SQL statements, the schema dumper cannot reconstitute those statements from the database. If you are using features like this, then you should set the schema format to +:sql+.
-
-Instead of using Active Record's schema dumper, the database's structure will be dumped using a tool specific to the database (via the +db:structure:dump+ Rake task) into +db/#{Rails.env}_structure.sql+. For example, for the PostgreSQL RDBMS, the +pg_dump+ utility is used. For MySQL, this file will contain the output of +SHOW CREATE TABLE+ for the various tables. Loading these schemas is simply a question of executing the SQL statements they contain. By definition, this will create a perfect copy of the database's structure. Using the +:sql+ schema format will, however, prevent loading the schema into a RDBMS other than the one used to create it.
+In many ways this is exactly what it is. This file is created by inspecting the
+database and expressing its structure using +create_table+, +add_index+, and so
+on. Because this is database-independent, it could be loaded into any database
+that Active Record supports. This could be very useful if you were to distribute
+an application that is able to run against multiple databases.
+
+There is however a trade-off: +db/schema.rb+ cannot express database specific
+items such as foreign key constraints, triggers, or stored procedures. While in
+a migration you can execute custom SQL statements, the schema dumper cannot
+reconstitute those statements from the database. If you are using features like
+this, then you should set the schema format to +:sql+.
+
+Instead of using Active Record's schema dumper, the database's structure will be
+dumped using a tool specific to the database (via the +db:structure:dump+ Rake task)
+into +db/structure.sql+. For example, for the PostgreSQL RDBMS, the
++pg_dump+ utility is used. For MySQL, this file will contain the output of +SHOW
+CREATE TABLE+ for the various tables. Loading these schemas is simply a question
+of executing the SQL statements they contain. By definition, this will create a
+perfect copy of the database's structure. Using the +:sql+ schema format will,
+however, prevent loading the schema into a RDBMS other than the one used to
+create it.
h4. Schema Dumps and Source Control
-Because schema dumps are the authoritative source for your database schema, it is strongly recommended that you check them into source control.
+Because schema dumps are the authoritative source for your database schema, it
+is strongly recommended that you check them into source control.
h3. Active Record and Referential Integrity
-The Active Record way claims that intelligence belongs in your models, not in the database. As such, features such as triggers or foreign key constraints, which push some of that intelligence back into the database, are not heavily used.
-
-Validations such as +validates :foreign_key, :uniqueness => true+ are one way in which models can enforce data integrity. The +:dependent+ option on associations allows models to automatically destroy child objects when the parent is destroyed. Like anything which operates at the application level, these cannot guarantee referential integrity and so some people augment them with foreign key constraints.
-
-Although Active Record does not provide any tools for working directly with such features, the +execute+ method can be used to execute arbitrary SQL. There are also a number of plugins such as "foreign_key_migrations":https://github.com/harukizaemon/redhillonrails/tree/master/foreign_key_migrations/ which add foreign key support to Active Record (including support for dumping foreign keys in +db/schema.rb+).
+The Active Record way claims that intelligence belongs in your models, not in
+the database. As such, features such as triggers or foreign key constraints,
+which push some of that intelligence back into the database, are not heavily
+used.
+
+Validations such as +validates :foreign_key, :uniqueness => true+ are one way in
+which models can enforce data integrity. The +:dependent+ option on associations
+allows models to automatically destroy child objects when the parent is
+destroyed. Like anything which operates at the application level, these cannot
+guarantee referential integrity and so some people augment them with foreign key
+constraints in the database.
+
+Although Active Record does not provide any tools for working directly with such
+features, the +execute+ method can be used to execute arbitrary SQL. You could
+also use some plugin like "foreigner":https://github.com/matthuhiggins/foreigner
+which add foreign key support to Active Record (including support for dumping
+foreign keys in +db/schema.rb+).
diff --git a/railties/guides/source/performance_testing.textile b/railties/guides/source/performance_testing.textile
index f3ea7e38bc..958b13cd9e 100644
--- a/railties/guides/source/performance_testing.textile
+++ b/railties/guides/source/performance_testing.textile
@@ -151,7 +151,7 @@ Performance tests can be run in two modes: Benchmarking and Profiling.
h5. Benchmarking
-Benchmarking makes it easy to quickly gather a few metrics about each test tun. By default, each test case is run *4 times* in benchmarking mode.
+Benchmarking makes it easy to quickly gather a few metrics about each test run. By default, each test case is run *4 times* in benchmarking mode.
To run performance tests in benchmarking mode:
@@ -447,7 +447,7 @@ h4. Using Ruby-Prof on MRI and REE
Add Ruby-Prof to your applications' Gemfile if you want to benchmark/profile under MRI or REE:
<ruby>
-gem 'ruby-prof', :path => 'git://github.com/wycats/ruby-prof.git'
+gem 'ruby-prof', :git => 'git://github.com/wycats/ruby-prof.git'
</ruby>
Now run +bundle install+ and you're ready to go.
diff --git a/railties/guides/source/plugins.textile b/railties/guides/source/plugins.textile
index 5cfd336d1e..07fd95c825 100644
--- a/railties/guides/source/plugins.textile
+++ b/railties/guides/source/plugins.textile
@@ -30,17 +30,7 @@ Before you continue, take a moment to decide if your new plugin will be potentia
* If your plugin is specific to your application, your new plugin will be a _vendored plugin_.
* If you think your plugin may be used across applications, build it as a _gemified plugin_.
-h4. Either generate a vendored plugin...
-
-Use the +rails generate plugin+ command in your Rails root directory
- to create a new plugin that will live in the +vendor/plugins+
- directory. See usage and options by asking for help:
-
-<shell>
-$ rails generate plugin --help
-</shell>
-
-h4. Or generate a gemified plugin.
+h4. Generate a gemified plugin.
Writing your Rails plugin as a gem, rather than as a vendored plugin,
lets you share your plugin across different rails applications using
@@ -412,30 +402,6 @@ After running +bundle install+, your gem functionality will be available to the
When the gem is ready to be shared as a formal release, it can be published to "RubyGems":http://www.rubygems.org.
For more information about publishing gems to RubyGems, see: "http://blog.thepete.net/2010/11/creating-and-publishing-your-first-ruby.html":http://blog.thepete.net/2010/11/creating-and-publishing-your-first-ruby.html
-h3. Non-Gem Plugins
-
-Non-gem plugins are useful for functionality that won't be shared with another project. Keeping your custom functionality in the
-vendor/plugins directory un-clutters the rest of the application.
-
-Move the directory that you created for the gem based plugin into the vendor/plugins directory of a generated Rails application, create a vendor/plugins/yaffle/init.rb file that contains "require 'yaffle'" and everything will still work.
-
-<ruby>
-# yaffle/init.rb
-
-require 'yaffle'
-</ruby>
-
-You can test this by changing to the Rails application that you added the plugin to and starting a rails console. Once in the
-console we can check to see if the String has an instance method to_squawk:
-
-<shell>
-$ cd my_app
-$ rails console
-$ "Rails plugins are easy!".to_squawk
-</shell>
-
-You can also remove the .gemspec, Gemfile and Gemfile.lock files as they will no longer be needed.
-
h3. RDoc Documentation
Once your plugin is stable and you are ready to deploy do everyone else a favor and document it! Luckily, writing documentation for your plugin is easy.
@@ -461,4 +427,3 @@ h4. References
* "Using Gemspecs As Intended":http://yehudakatz.com/2010/04/02/using-gemspecs-as-intended/
* "Gemspec Reference":http://docs.rubygems.org/read/chapter/20
* "GemPlugins":http://www.mbleigh.com/2008/06/11/gemplugins-a-brief-introduction-to-the-future-of-rails-plugins
-* "Keeping init.rb thin":http://daddy.platte.name/2007/05/rails-plugins-keep-initrb-thin.html
diff --git a/railties/guides/source/rails_application_templates.textile b/railties/guides/source/rails_application_templates.textile
index 3b51a52733..f50ced3307 100644
--- a/railties/guides/source/rails_application_templates.textile
+++ b/railties/guides/source/rails_application_templates.textile
@@ -1,6 +1,6 @@
h2. Rails Application Templates
-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.
+Application templates are simple Ruby files containing DSL for adding gems/initializers etc. to your freshly created Rails project or an existing Rails project.
By referring to this guide, you will be able to:
@@ -82,31 +82,6 @@ For example, if you need to source a gem from "http://code.whytheluckystiff.net"
add_source "http://code.whytheluckystiff.net"
</ruby>
-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 'usingsvn', :svn => 'svn://example.com/usingsvn/trunk'
-</ruby>
-
h4. vendor/lib/file/initializer(filename, data = nil, &block)
Adds an initializer to the generated application’s +config/initializers+ directory.
diff --git a/railties/guides/source/rails_on_rack.textile b/railties/guides/source/rails_on_rack.textile
index d6cbd84b1f..9526526bc7 100644
--- a/railties/guides/source/rails_on_rack.textile
+++ b/railties/guides/source/rails_on_rack.textile
@@ -95,6 +95,7 @@ use ActiveSupport::Cache::Strategy::LocalCache
use Rack::Runtime
use Rails::Rack::Logger
use ActionDispatch::ShowExceptions
+use ActionDispatch::DebugExceptions
use ActionDispatch::RemoteIp
use Rack::Sendfile
use ActionDispatch::Callbacks
diff --git a/railties/guides/source/routing.textile b/railties/guides/source/routing.textile
index f281009fee..0823fb14e3 100644
--- a/railties/guides/source/routing.textile
+++ b/railties/guides/source/routing.textile
@@ -620,7 +620,7 @@ You can specify what Rails should route +"/"+ to with the +root+ method:
root :to => 'pages#main'
</ruby>
-You should put the +root+ route at the end of the file. You also need to delete the +public/index.html+ file for the root route to take effect.
+You should put the +root+ route at the top of the file, because it is the most popular route and should be matched first. You also need to delete the +public/index.html+ file for the root route to take effect.
h3. Customizing Resourceful Routes
@@ -655,7 +655,7 @@ You can use the +:constraints+ option to specify a required format on the implic
resources :photos, :constraints => {:id => /[A-Z][A-Z][0-9]+/}
</ruby>
-This declaration constraints the +:id+ parameter to match the supplied regular expression. So, in this case, the router would no longer match +/photos/1+ to this route. Instead, +/photos/RR27+ would match.
+This declaration constrains the +:id+ parameter to match the supplied regular expression. So, in this case, the router would no longer match +/photos/1+ to this route. Instead, +/photos/RR27+ would match.
You can specify a single constraint to apply to a number of routes by using the block form:
diff --git a/railties/guides/source/ruby_on_rails_guides_guidelines.textile b/railties/guides/source/ruby_on_rails_guides_guidelines.textile
index 29aefd25f8..f3c8fa654d 100644
--- a/railties/guides/source/ruby_on_rails_guides_guidelines.textile
+++ b/railties/guides/source/ruby_on_rails_guides_guidelines.textile
@@ -40,7 +40,9 @@ The guides and the API should be coherent where appropriate. Please have a look
Those guidelines apply also to guides.
-h3. HTML Generation
+h3. HTML Guides
+
+h4. Generation
To generate all the guides, just +cd+ into the +railties+ directory and execute:
@@ -68,7 +70,7 @@ If you want to generate guides in languages other than English, you can keep the
bundle exec rake generate_guides GUIDES_LANGUAGE=es
</plain>
-h3. HTML Validation
+h4. Validation
Please validate the generated HTML with:
@@ -77,3 +79,13 @@ bundle exec rake validate_guides
</plain>
Particularly, titles get an ID generated from their content and this often leads to duplicates. Please set +WARNINGS=1+ when generating guides to detect them. The warning messages suggest a way to fix them.
+
+h3. Kindle Guides
+
+h4. Generation
+
+To generate guides for the Kindle, you need to provide +KINDLE=1+ as an environment variable:
+
+<plain>
+KINDLE=1 bundle exec rake generate_guides
+</plain>
diff --git a/railties/guides/source/security.textile b/railties/guides/source/security.textile
index c2ef7bf9b5..b1a09c0c05 100644
--- a/railties/guides/source/security.textile
+++ b/railties/guides/source/security.textile
@@ -385,7 +385,7 @@ params[:user] # => {:name => “ow3ned”, :admin => true}
So if you create a new user using mass-assignment, it may be too easy to become an administrator.
-Note that this vulnerability is not restricted to database columns. Any setter method, unless explicitly protected, is accessible via the <tt>attributes=</tt> method. In fact, this vulnerability is extended even further with the introduction of nested mass assignment (and nested object forms) in Rails 2.3+. The +accepts_nested_attributes_for+ declaration provides us the ability to extend mass assignment to model associations (+has_many+, +has_one+, +has_and_belongs_to_many+). For example:
+Note that this vulnerability is not restricted to database columns. Any setter method, unless explicitly protected, is accessible via the <tt>attributes=</tt> method. In fact, this vulnerability is extended even further with the introduction of nested mass assignment (and nested object forms) in Rails 2.3<plus>. The +accepts_nested_attributes_for+ declaration provides us the ability to extend mass assignment to model associations (+has_many+, +has_one+, +has_and_belongs_to_many+). For example:
<ruby>
class Person < ActiveRecord::Base
diff --git a/railties/guides/source/testing.textile b/railties/guides/source/testing.textile
index 2341a3522c..1e6b92f45c 100644
--- a/railties/guides/source/testing.textile
+++ b/railties/guides/source/testing.textile
@@ -114,25 +114,18 @@ Rails by default automatically loads all fixtures from the +test/fixtures+ folde
* Load the fixture data into the table
* Dump the fixture data into a variable in case you want to access it directly
-h5. Hashes with Special Powers
+h5. Fixtures are ActiveRecord objects
-Fixtures are basically Hash objects. As mentioned in point #3 above, you can access the hash object directly because it is automatically setup as a local variable of the test case. For example:
+Fixtures are instances of ActiveRecord. As mentioned in point #3 above, you can access the object directly because it is automatically setup as a local variable of the test case. For example:
<ruby>
-# this will return the Hash for the fixture named david
+# this will return the User object for the fixture named david
users(:david)
# this will return the property for david called id
users(:david).id
-</ruby>
-
-Fixtures can also transform themselves into the form of the original class. Thus, you can get at the methods only available to that class.
-
-<ruby>
-# using the find method, we grab the "real" david as a User
-david = users(:david).find
-# and now we have access to methods only available to a User class
+# one can also access methods available on the User class
email(david.girlfriend.email, david.location_tonight)
</ruby>
@@ -738,7 +731,6 @@ You don't need to set up and run your tests by hand on a test-by-test basis. Rai
|+rake test:benchmark+ |Benchmark the performance tests|
|+rake test:functionals+ |Runs all the functional tests from +test/functional+|
|+rake test:integration+ |Runs all the integration tests from +test/integration+|
-|+rake test:plugins+ |Run all the plugin tests from +vendor/plugins/*/**/test+ (or specify with +PLUGIN=_name_+)|
|+rake test:profile+ |Profile the performance tests|
|+rake test:recent+ |Tests recent changes|
|+rake test:uncommitted+ |Runs all the tests which are uncommitted. Supports Subversion and Git|
@@ -927,7 +919,7 @@ class UserControllerTest < ActionController::TestCase
assert_difference 'ActionMailer::Base.deliveries.size', +1 do
post :invite_friend, :email => 'friend@example.com'
end
- invite_email = ActionMailer::Base.deliveries.first
+ invite_email = ActionMailer::Base.deliveries.last
assert_equal "You have been invited by me@example.com", invite_email.subject
assert_equal 'friend@example.com', invite_email.to[0]