aboutsummaryrefslogtreecommitdiffstats
path: root/guides/source
diff options
context:
space:
mode:
Diffstat (limited to 'guides/source')
-rw-r--r--guides/source/4_0_release_notes.md876
-rw-r--r--guides/source/_welcome.html.erb2
-rw-r--r--guides/source/action_controller_overview.md69
-rw-r--r--guides/source/action_mailer_basics.md67
-rw-r--r--guides/source/action_view_overview.md18
-rw-r--r--guides/source/active_model_basics.md94
-rw-r--r--guides/source/active_record_basics.md56
-rw-r--r--guides/source/active_record_callbacks.md361
-rw-r--r--guides/source/active_record_querying.md40
-rw-r--r--guides/source/active_record_validations.md963
-rw-r--r--guides/source/active_record_validations_callbacks.md1372
-rw-r--r--guides/source/active_support_core_extensions.md42
-rw-r--r--guides/source/active_support_instrumentation.md32
-rw-r--r--guides/source/api_documentation_guidelines.md5
-rw-r--r--guides/source/asset_pipeline.md56
-rw-r--r--guides/source/association_basics.md16
-rw-r--r--guides/source/caching_with_rails.md110
-rw-r--r--guides/source/command_line.md18
-rw-r--r--guides/source/configuring.md16
-rw-r--r--guides/source/contributing_to_ruby_on_rails.md18
-rw-r--r--guides/source/debugging_rails_applications.md12
-rw-r--r--guides/source/development_dependencies_install.md2
-rw-r--r--guides/source/documents.yaml10
-rw-r--r--guides/source/engines.md16
-rw-r--r--guides/source/form_helpers.md22
-rw-r--r--guides/source/generators.md18
-rw-r--r--guides/source/getting_started.md102
-rw-r--r--guides/source/i18n.md20
-rw-r--r--guides/source/initialization.md4
-rw-r--r--guides/source/layouts_and_rendering.md33
-rw-r--r--guides/source/migrations.md601
-rw-r--r--guides/source/nested_model_forms.md4
-rw-r--r--guides/source/performance_testing.md18
-rw-r--r--guides/source/plugins.md15
-rw-r--r--guides/source/rails_application_templates.md6
-rw-r--r--guides/source/rails_on_rack.md12
-rw-r--r--guides/source/routing.md224
-rw-r--r--guides/source/ruby_on_rails_guides_guidelines.md9
-rw-r--r--guides/source/security.md20
-rw-r--r--guides/source/testing.md14
-rw-r--r--guides/source/upgrading_ruby_on_rails.md8
-rw-r--r--guides/source/working_with_javascript_in_rails.md14
42 files changed, 2305 insertions, 3110 deletions
diff --git a/guides/source/4_0_release_notes.md b/guides/source/4_0_release_notes.md
index ecb8dd04f5..dd57787111 100644
--- a/guides/source/4_0_release_notes.md
+++ b/guides/source/4_0_release_notes.md
@@ -1,41 +1,24 @@
Ruby on Rails 4.0 Release Notes
===============================
-Highlights in Rails 4.0: (WIP)
+Highlights in Rails 4.0:
* Ruby 1.9.3 only
* Strong Parameters
* Queue API
-* Caching Improvements
+* Turbolinks
+* Russian Doll Caching
+* Asynchronous Mailers
-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/master) in the main Rails repository on GitHub.
+These release notes cover only the major changes. To know about various bug fixes and changes, please refer to the change logs or check out the [list of commits](https://github.com/rails/rails/commits/master) in the main Rails repository on GitHub.
--------------------------------------------------------------------------------
Upgrading to Rails 4.0
----------------------
-TODO. This is a WIP guide.
+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.2 in case you haven't and make sure your application still runs as expected before attempting an update to Rails 4.0. A list of things to watch out for when upgrading is available in the [Upgrading to Rails](upgrading_ruby_on_rails.html#upgrading-from-rails-3-2-to-rails-4-0) guide.
-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.2 in case you haven't and make sure your application still runs as expected before attempting an update to Rails 4.0. Then take heed of the following changes:
-
-### Rails 4.0 requires at least Ruby 1.9.3
-
-Rails 4.0 requires Ruby 1.9.3 or higher. Support for all of the previous Ruby versions has been dropped officially and you should upgrade as early as possible.
-
-### What to update in your apps
-
-* Update your Gemfile to depend on
- * `rails = 4.0.0`
- * `sass-rails ~> 3.2.3`
- * `coffee-rails ~> 3.2.1`
- * `uglifier >= 1.0.3`
-
-TODO: Update the versions above.
-
-* Rails 4.0 removes `vendor/plugins` completely. You have to replace 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, `lib/my_plugin/*` and add an appropriate initializer in `config/initializers/my_plugin.rb`.
-
-TODO: Configuration changes in environment files
Creating a Rails 4.0 application
--------------------------------
@@ -69,6 +52,24 @@ $ ruby /path/to/rails/railties/bin/rails new myapp --dev
Major Features
--------------
+TODO. Give a list and then talk about each of them briefly. We can point to relevant code commits or documentation from these sections.
+
+![Rails 4.0](images/rails4_features.png)
+
+Extraction of features to gems
+---------------------------
+
+In Rails 4.0, several features have been extracted into gems. You can simply add the extracted gems to your `Gemfile` to bring the functionality back.
+
+* Hash-based & Dynamic finder methods ([Github](https://github.com/rails/activerecord-deprecated_finders))
+* Mass assignment protection in Active Record models ([Github](https://github.com/rails/protected_attributes), [Pull Request](https://github.com/rails/rails/pull/7251))
+* ActiveRecord::SessionStore ([Github](https://github.com/rails/activerecord-session_store), [Pull Request](https://github.com/rails/rails/pull/7436))
+* Active Record Observers ([Github](https://github.com/rails/rails-observers), [Commit](https://github.com/rails/rails/commit/39e85b3b90c58449164673909a6f1893cba290b2))
+* Active Resource ([Github](https://github.com/rails/activeresource), [Pull Request](https://github.com/rails/rails/pull/572), [Blog](http://yetimedia.tumblr.com/post/35233051627/activeresource-is-dead-long-live-activeresource))
+* Action Caching ([Github](https://github.com/rails/actionpack-action_caching), [Pull Request](https://github.com/rails/rails/pull/7833))
+* Page Caching ([Github](https://github.com/rails/actionpack-page_caching), [Pull Request](https://github.com/rails/rails/pull/7833))
+* Sprockets ([Github](https://github.com/rails/sprockets-rails))
+
Documentation
-------------
@@ -79,841 +80,132 @@ Documentation
Railties
--------
-* Ensure that RAILS_ENV is set when accessing Rails.env.
-
-* Don't eager-load app/assets and app/views.
-
-* Add `.rake` to list of file extensions included by `rake notes` and `rake notes:custom`.
-
-* New test locations `test/models`, `test/helpers`, `test/controllers`, and `test/mailers`. Corresponding rake tasks added as well.
-
-* Set a different cache per environment for assets pipeline through `config.assets.cache`.
-
-* `Rails.public_path` now returns a Pathname object.
-
-* Remove highly uncommon `config.assets.manifest` option for moving the manifest path. This option is now unsupported in sprockets-rails.
+Please refer to the [Changelog](https://github.com/rails/rails/blob/master/railties/CHANGELOG.md) for detailed changes.
-* Add `config.action_controller.permit_all_parameters` to disable StrongParameters protection, it's false by default.
+### Notable changes
-* Remove `config.active_record.whitelist_attributes` and `config.active_record.mass_assignment_sanitizer` from new applications since MassAssignmentSecurity has been extracted from Rails.
+* New test locations `test/models`, `test/helpers`, `test/controllers`, and `test/mailers`. Corresponding rake tasks added as well. ([Pull Request](https://github.com/rails/rails/pull/7878))
-* Change `rails new` and `rails plugin new` generators to name the `.gitkeep` files as `.keep` in a more SCM-agnostic way. Change `--skip-git` option to only skip the `.gitignore` file and still generate the `.keep` files. Add `--skip-keeps` option to skip the `.keep` files.
+* Threadsafe on by default
-* Fixed support for DATABASE_URL environment variable for rake db tasks.
+* Add `Rails.queue` for processing jobs in the background.
-* rails dbconsole now can use SSL for MySQL. The database.yml options sslca, sslcert, sslcapath, sslcipher and sslkey now affect rails dbconsole.
-
-* Correctly handle SCRIPT_NAME when generating routes to engine in application that's mounted at a sub-uri. With this behavior, you *should not* use default_url_options[:script_name] to set proper application's mount point by yourself.
-
-* `config.threadsafe!` is deprecated in favor of `config.eager_load` which provides a more fine grained control on what is eager loaded.
+### Deprecations
-* The migration generator will now produce AddXXXToYYY/RemoveXXXFromYYY migrations with references statements, for instance
+* `config.threadsafe!` is deprecated in favor of `config.eager_load` which provides a more fine grained control on what is eager loaded.
- rails g migration AddReferencesToProducts user:references supplier:references{polymorphic}
+* `Rails::Plugin` has gone. Instead of adding plugins to `vendor/plugins` use gems or bundler with path or git dependencies.
- will generate the migration with:
+Action Mailer
+-------------
- add_reference :products, :user, index: true
- add_reference :products, :supplier, polymorphic: true, index: true
+Please refer to the [Changelog](https://github.com/rails/rails/blob/master/actionmailer/CHANGELOG.md) for detailed changes.
-* Allow scaffold/model/migration generators to accept a `polymorphic` modifier for `references`/`belongs_to`, for instance
+### Notable changes
- ```
- rails g model Product supplier:references{polymorphic}
- ```
+* Asynchronously send messages via the Rails Queue. ([Pull Request](https://github.com/rails/rails/pull/6839))
- will generate the model with `belongs_to :supplier, polymorphic: true` association and appropriate migration.
+### Deprecations
-* Set `config.active_record.migration_error` to `:page_load` for development.
+Active Model
+------------
-* Add runner to `Rails::Railtie` as a hook called just after runner starts.
+Please refer to the [Changelog](https://github.com/rails/rails/blob/master/activemodel/CHANGELOG.md) for detailed changes.
-* Add `/rails/info/routes` path which displays the same information as `rake routes`.
+### Notable changes
-* Improved `rake routes` output for redirects.
+* Add `ActiveModel::ForbiddenAttributesProtection`, a simple module to protect attributes from mass assignment when non-permitted attributes are passed.
-* Load all environments available in `config.paths["config/environments"]`.
+* Added `ActiveModel::Model`, a mixin to make Ruby objects work with AP out of box.
-* Add `config.queue_consumer` to change the job queue consumer from the default `ActiveSupport::ThreadedQueueConsumer`.
+### Deprecations
-* Add `Rails.queue` for processing jobs in the background.
+Active Support
+--------------
-* Remove `Rack::SSL` in favour of `ActionDispatch::SSL`.
+Please refer to the [Changelog](https://github.com/rails/rails/blob/master/activesupport/CHANGELOG.md) for detailed changes.
-* Allow to set class that will be used to run as a console, other than IRB, with `Rails.application.config.console=`. It's best to add it to console block.
+### Notable changes
- ```ruby
- # it can be added to config/application.rb
- console do
- # this block is called only when running console,
- # so we can safely require pry here
- require "pry"
- config.console = Pry
- end
- ```
+* Replace deprecated `memcache-client` gem with `dalli` in ActiveSupport::Cache::MemCacheStore.
-* Add a convenience method `hide!` to Rails generators to hide the current generator namespace from showing when running `rails generate`.
+* Optimize ActiveSupport::Cache::Entry to reduce memory and processing overhead.
-* Scaffold now uses `content_tag_for` in `index.html.erb`.
+* Inflections can now be defined per locale. `singularize` and `pluralize` accept locale as an extra argument.
-* `Rails::Plugin` is removed. Instead of adding plugins to `vendor/plugins`, use gems or bundler with path or git dependencies.
+* `Object#try` will now return nil instead of raise a NoMethodError if the receiving object does not implement the method, but you can still get the old behavior by using the new `Object#try!`.
### Deprecations
-Action Mailer
--------------
-
-* Allow to set default Action Mailer options via `config.action_mailer.default_options=`.
-
-* Raise an `ActionView::MissingTemplate` exception when no implicit template could be found.
+* Deprecate `ActiveSupport::TestCase#pending` method, use `skip` from MiniTest instead.
-* Asynchronously send messages via the Rails Queue.
+* ActiveSupport::Benchmarkable#silence has been deprecated due to its lack of thread safety. It will be removed without replacement in Rails 4.1.
-* Delivery Options (such as SMTP Settings) can now be set dynamically per mailer action.
+* `ActiveSupport::JSON::Variable` is deprecated. Define your own `#as_json` and `#encode_json` methods for custom JSON string literals.
- Delivery options are set via <tt>:delivery_method_options</tt> key on mail.
+* Deprecates the compatibility method Module#local_constant_names, use Module#local_constants instead (which returns symbols).
- ```ruby
- def welcome_mailer(user,company)
- delivery_options = { user_name: company.smtp_user, password: company.smtp_password, address: company.smtp_host }
- mail(to: user.email, subject: "Welcome!", delivery_method_options: delivery_options)
- end
- ```
+* BufferedLogger is deprecated. Use ActiveSupport::Logger, or the logger from Ruby stdlib.
-* Allow for callbacks in mailers similar to ActionController::Base. You can now set up headers/attachments using `before_filter` or `after_filter`. You could also change delivery settings or prevent delivery in an after filter based on instance variables set in your mailer action. You have access to `ActionMailer::Base` instance methods like `message`, `attachments`, `headers`.
Action Pack
-----------
-### Action Controller
-
-* Add `ActionController::Flash.add_flash_types` method to allow people to register their own flash types. e.g.:
-
- ```ruby
- class ApplicationController
- add_flash_types :error, :warning
- end
- ```
-
- If you add the above code, you can use `<%= error %>` in an erb, and `redirect_to /foo, :error => 'message'` in a controller.
-
-* Remove Active Model dependency from Action Pack.
-
-* Support unicode characters in routes. Route will be automatically escaped, so instead of manually escaping:
-
- ```ruby
- get Rack::Utils.escape('こんにちは') => 'home#index'
- ```
-
- You just have to write the unicode route:
-
- ```ruby
- get 'こんにちは' => 'home#index'
- ```
-
-* Return proper format on exceptions.
-
-* Extracted redirect logic from `ActionController::ForceSSL::ClassMethods.force_ssl` into `ActionController::ForceSSL#force_ssl_redirect`.
-
-* URL path parameters with invalid encoding now raise `ActionController::BadRequest`.
-
-* Malformed query and request parameter hashes now raise `ActionController::BadRequest`.
-
-* `respond_to` and `respond_with` now raise `ActionController::UnknownFormat` instead of directly returning head 406. The exception is rescued and converted to 406 in the exception handling middleware.
-
-* JSONP now uses `application/javascript` instead of `application/json` as the MIME type.
-
-* Session arguments passed to process calls in functional tests are now merged into the existing session, whereas previously they would replace the existing session. This change may break some existing tests if they are asserting the exact contents of the session but should not break existing tests that only assert individual keys.
-
-* Forms of persisted records use always PATCH (via the `_method` hack).
-
-* For resources, both PATCH and PUT are routed to the `update` action.
-
-* Don't ignore `force_ssl` in development. This is a change of behavior - use an `:if` condition to recreate the old behavior.
-
- ```ruby
- class AccountsController < ApplicationController
- force_ssl :if => :ssl_configured?
-
- def ssl_configured?
- !Rails.env.development?
- end
- end
- ```
-
-#### Deprecations
-
-* Deprecated `ActionController::Integration` in favour of `ActionDispatch::Integration`.
-
-* Deprecated `ActionController::IntegrationTest` in favour of `ActionDispatch::IntegrationTest`.
-
-* Deprecated `ActionController::PerformanceTest` in favour of `ActionDispatch::PerformanceTest`.
-
-* Deprecated `ActionController::AbstractRequest` in favour of `ActionDispatch::Request`.
-
-* Deprecated `ActionController::Request` in favour of `ActionDispatch::Request`.
-
-* Deprecated `ActionController::AbstractResponse` in favour of `ActionDispatch::Response`.
-
-* Deprecated `ActionController::Response` in favour of `ActionDispatch::Response`.
-
-* Deprecated `ActionController::Routing` in favour of `ActionDispatch::Routing`.
-
-### Action Dispatch
-
-* Add Routing Concerns to declare common routes that can be reused inside others resources and routes.
-
- Code before:
-
- ```ruby
- resources :messages do
- resources :comments
- end
-
- resources :posts do
- resources :comments
- resources :images, only: :index
- end
- ```
-
- Code after:
-
- ```ruby
- concern :commentable do
- resources :comments
- end
-
- concern :image_attachable do
- resources :images, only: :index
- end
+Please refer to the [Changelog](https://github.com/rails/rails/blob/master/railties/CHANGELOG.md) for detailed changes.
- resources :messages, concerns: :commentable
+### Notable changes
- resources :posts, concerns: [:commentable, :image_attachable]
- ```
-
-* Show routes in exception page while debugging a `RoutingError` in development.
-
-* Include `mounted_helpers` (helpers for accessing mounted engines) in `ActionDispatch::IntegrationTest` by default.
-
-* Added `ActionDispatch::SSL` middleware that when included force all the requests to be under HTTPS protocol.
-
-* Copy literal route constraints to defaults so that url generation know about them. The copied constraints are `:protocol`, `:subdomain`, `:domain`, `:host` and `:port`.
-
-* Allows `assert_redirected_to` to match against a regular expression.
-
-* Adds a backtrace to the routing error page in development.
-
-* `assert_generates`, `assert_recognizes`, and `assert_routing` all raise `Assertion` instead of `RoutingError`.
-
-* Allows the route helper root to take a string argument. For example, `root 'pages#main'` as a shortcut for `root to: 'pages#main'`.
-
-* Adds support for the PATCH verb: Request objects respond to `patch?`. Routes now have a new `patch` method, and understand `:patch` in the existing places where a verb is configured, like `:via`. Functional tests have a new method `patch` and integration tests have a new method `patch_via_redirect`.
-If `:patch` is the default verb for updates, edits are tunneled as `PATCH` rather than as `PUT` and routing acts accordingly.
-
-* Integration tests support the OPTIONS method.
-
-* `expires_in` accepts a `must_revalidate` flag. If true, "must-revalidate" is added to the `Cache-Control` header.
-
-* Default responder will now always use your overridden block in `respond_with` to render your response.
-
-* Turn off verbose mode of `rack-cache`, we still have `X-Rack-Cache` to check that info.
-
-#### Deprecations
-
-### Action View
-
-* Remove Active Model dependency from Action Pack.
-
-* Allow to use `mounted_helpers` (helpers for accessing mounted engines) in `ActionView::TestCase`.
-
-* Make current object and counter (when it applies) variables accessible when rendering templates with `:object` or `:collection`.
-
-* Allow to lazy load `default_form_builder` by passing a string instead of a constant.
-
-* Add index method to `FormBuilder` class.
-
-* Adds support for layouts when rendering a partial with a given collection.
-
-* Remove `:disable_with` in favor of `data-disable-with` option from `submit_tag`, `button_tag` and `button_to` helpers.
-
-* Remove `:mouseover` option from `image_tag` helper.
-
-* Templates without a handler extension now raises a deprecation warning but still defaults to `ERb`. In future releases, it will simply return the template content.
-
-* Add a `divider` option to `grouped_options_for_select` to generate a separator optgroup automatically, and deprecate prompt as third argument, in favor of using an options hash.
-
-* Add `time_field` and `time_field_tag` helpers which render an `input[type="time"]` tag.
-
-* Removed old `text_helper` apis for `highlight`, `excerpt` and `word_wrap`.
-
-* Remove the leading \n added by textarea on `assert_select`.
-
-* Changed default value for `config.action_view.embed_authenticity_token_in_remote_forms` to false. This change breaks remote forms that need to work also without JavaScript, so if you need such behavior, you can either set it to true or explicitly pass `:authenticity_token => true` in form options.
-
-* Make possible to use a block in `button_to` helper if button text is hard to fit into the name parameter:
-
- ```ruby
- <%= button_to [:make_happy, @user] do %>
- Make happy <strong><%= @user.name %></strong>
- <% end %>
- # => "<form method="post" action="/users/1/make_happy" class="button_to">
- # <div>
- # <button type="submit">
- # Make happy <strong>Name</strong>
- # </button>
- # </div>
- # </form>"
- ```
-
-* Replace `include_seconds` boolean argument with `:include_seconds => true` option in `distance_of_time_in_words` and `time_ago_in_words` signature.
-
-* Remove `button_to_function` and `link_to_function` helpers.
-
-* `truncate` now always returns an escaped HTML-safe string. The option `:escape` can be used as `false` to not escape the result.
-
-* `truncate` now accepts a block to show extra content when the text is truncated.
-
-* Add `week_field`, `week_field_tag`, `month_field`, `month_field_tag`, `datetime_local_field`, `datetime_local_field_tag`, `datetime_field` and `datetime_field_tag` helpers.
-
-* Add `color_field` and `color_field_tag` helpers.
-
-* Add `include_hidden` option to select tag. With `:include_hidden => false` select with multiple attribute doesn't generate hidden input with blank value.
-
-* Removed default size option from the `text_field`, `search_field`, `telephone_field`, `url_field`, `email_field` helpers.
-
-* Removed default cols and rows options from the `text_area` helper.
-
-* Adds `image_url`, `javascript_url`, `stylesheet_url`, `audio_url`, `video_url`, and `font_url` to assets tag helper. These URL helpers will return the full path to your assets. This is useful when you are going to reference this asset from external host.
-
-* Allow `value_method` and `text_method` arguments from `collection_select` and `options_from_collection_for_select` to receive an object that responds to `:call` such as a proc, to evaluate the option in the current element context. This works the same way with `collection_radio_buttons` and `collection_check_boxes`.
-
-* Add `date_field` and `date_field_tag` helpers which render an `input[type="date"]` tag.
-
-* Add `collection_check_boxes` form helper, similar to `collection_select`:
-
- ```ruby
- collection_check_boxes :post, :author_ids, Author.all, :id, :name
- # Outputs something like:
- <input id="post_author_ids_1" name="post[author_ids][]" type="checkbox" value="1" />
- <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 name="post[author_ids][]" type="hidden" value="" />
- ```
-
- The label/check_box pairs can be customized with a block.
-
-* Add `collection_radio_buttons` form helper, similar to `collection_select`:
-
- ```ruby
- collection_radio_buttons :post, :author_id, Author.all, :id, :name
- # Outputs something like:
- <input id="post_author_id_1" name="post[author_id]" type="radio" value="1" />
- <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>
- ```
-
- The label/radio_button pairs can be customized with a block.
-
-* `check_box` with an HTML5 attribute `:form` will now replicate the `:form` attribute to the hidden field as well.
-
-* label form helper accepts `:for => nil` to not generate the attribute.
-
-* Add `:format` option to `number_to_percentage`.
-
-* Add `config.action_view.logger` to configure logger for `Action View`.
-
-* `check_box` helper with `:disabled => true` will generate a `disabled` hidden field to conform with the HTML convention where disabled fields are not submitted with the form. This is a behavior change, previously the hidden tag had a value of the disabled checkbox.
-
-* `favicon_link_tag` helper will now use the favicon in `app/assets` by default.
-
-* `ActionView::Helpers::TextHelper#highlight` now defaults to the HTML5 `mark` element.
-
-#### Deprecations
-
-### Sprockets
+### Deprecations
-Moved into a separate gem `sprockets-rails`.
Active Record
-------------
-* Add `add_reference` and `remove_reference` schema statements. Aliases, `add_belongs_to` and `remove_belongs_to` are acceptable. References are reversible.
-
- ```ruby
- # Create a user_id column
- add_reference(:products, :user)
-
- # Create a supplier_id, supplier_type columns and appropriate index
- add_reference(:products, :supplier, polymorphic: true, index: true)
-
- # Remove polymorphic reference
- remove_reference(:products, :supplier, polymorphic: true)
- ```
-
-* Add `:default` and `:null` options to `column_exists?`.
-
- ```ruby
- column_exists?(:testings, :taggable_id, :integer, null: false)
- column_exists?(:testings, :taggable_type, :string, default: 'Photo')
- ```
-
-* `ActiveRecord::Relation#inspect` now makes it clear that you are dealing with a `Relation` object rather than an array:
-
- ```ruby
- User.where(:age => 30).inspect
- # => <ActiveRecord::Relation [#<User ...>, #<User ...>]>
-
- User.where(:age => 30).to_a.inspect
- # => [#<User ...>, #<User ...>]
- ```
-
- if more than 10 items are returned by the relation, inspect will only show the first 10 followed by ellipsis.
-
-* Add `:collation` and `:ctype` support to PostgreSQL. These are available for PostgreSQL 8.4 or later.
-
- ```yaml
- development:
- adapter: postgresql
- host: localhost
- database: rails_development
- username: foo
- password: bar
- encoding: UTF8
- collation: ja_JP.UTF8
- ctype: ja_JP.UTF8
- ```
+Please refer to the [Changelog](https://github.com/rails/rails/blob/master/railties/CHANGELOG.md) for detailed changes.
-* `FinderMethods#exists?` now returns `false` with the `false` argument.
+### Notable changes
-* Added support for specifying the precision of a timestamp in the postgresql adapter. So, instead of having to incorrectly specify the precision using the `:limit` option, you may use `:precision`, as intended. For example, in a migration:
+* Adds some metadata columns to `schema_migrations` table.
- ```ruby
- def change
- create_table :foobars do |t|
- t.timestamps :precision => 0
- end
- end
- ```
+ * `migrated_at`
+ * `fingerprint` - an md5 hash of the migration.
+ * `name` - the filename minus version and extension.
-* Allow `ActiveRecord::Relation#pluck` to accept multiple columns. Returns an array of arrays containing the typecasted values:
+* Adds PostgreSQL array type support. Any datatype can be used to create an array column, with full migration and schema dumper support.
- ```ruby
- Person.pluck(:id, :name)
- # SELECT people.id, people.name FROM people
- # => [[1, 'David'], [2, 'Jeremy'], [3, 'Jose']]
- ```
+* Add `Relation#load` to explicitly load the record and return `self`.
-* Improve the derivation of HABTM join table name to take account of nesting. It now takes the table names of the two models, sorts them lexically and then joins them, stripping any common prefix from the second table name. Some examples:
-
- ```
- Top level models (Category <=> Product)
- Old: categories_products
- New: categories_products
-
- Top level models with a global table_name_prefix (Category <=> Product)
- Old: site_categories_products
- New: site_categories_products
-
- Nested models in a module without a table_name_prefix method (Admin::Category <=> Admin::Product)
- Old: categories_products
- New: categories_products
-
- Nested models in a module with a table_name_prefix method (Admin::Category <=> Admin::Product)
- Old: categories_products
- New: admin_categories_products
-
- Nested models in a parent model (Catalog::Category <=> Catalog::Product)
- Old: categories_products
- New: catalog_categories_products
-
- Nested models in different parent models (Catalog::Category <=> Content::Page)
- Old: categories_pages
- New: catalog_categories_content_pages
- ```
-
-* Move HABTM validity checks to `ActiveRecord::Reflection`. One side effect of this is to move when the exceptions are raised from the point of declaration to when the association is built. This is consistant with other association validity checks.
-
-* Added `stored_attributes` hash which contains the attributes stored using `ActiveRecord::Store`. This allows you to retrieve the list of attributes you've defined.
-
- ```ruby
- class User < ActiveRecord::Base
- store :settings, accessors: [:color, :homepage]
- end
-
- User.stored_attributes[:settings] # [:color, :homepage]
- ```
-
-* PostgreSQL default log level is now 'warning', to bypass the noisy notice messages. You can change the log level using the `min_messages` option available in your `config/database.yml`.
-
-* Add uuid datatype support to PostgreSQL adapter.
+* `Model.all` now returns an `ActiveRecord::Relation`, rather than an array of records. Use `Relation#to_a` if you really want an array. In some specific cases, this may cause breakage when upgrading.
* Added `ActiveRecord::Migration.check_pending!` that raises an error if migrations are pending.
-* Added `#destroy!` which acts like `#destroy` but will raise an `ActiveRecord::RecordNotDestroyed` exception instead of returning `false`.
-
-* Allow blocks for count with `ActiveRecord::Relation`, to work similar as `Array#count`: `Person.where("age > 26").count { |person| person.gender == 'female' }`
-
-* Added support to `CollectionAssociation#delete` for passing fixnum or string values as record ids. This finds the records responding to the ids and deletes them.
-
- ```ruby
- class Person < ActiveRecord::Base
- has_many :pets
- end
-
- person.pets.delete("1") # => [#<Pet id: 1>]
- person.pets.delete(2, 3) # => [#<Pet id: 2>, #<Pet id: 3>]
- ```
-
-* It's not possible anymore to destroy a model marked as read only.
-
-* Added ability to `ActiveRecord::Relation#from` to accept other `ActiveRecord::Relation` objects.
-
* Added custom coders support for `ActiveRecord::Store`. Now you can set your custom coder like this:
- ```ruby
- store :settings, accessors: [ :color, :homepage ], coder: JSON
- ```
-
-* `mysql` and `mysql2` connections will set `SQL_MODE=STRICT_ALL_TABLES` by default to avoid silent data loss. This can be disabled by specifying `strict: false` in `config/database.yml`.
-
-* Added default order to `ActiveRecord::Base#first` to assure consistent results among different database engines. Introduced `ActiveRecord::Base#take` as a replacement to the old behavior.
-
-* Added an `:index` option to automatically create indexes for `references` and `belongs_to` statements in migrations. This can be either a boolean or a hash that is identical to options available to the `add_index` method:
-
- ```ruby
- create_table :messages do |t|
- t.references :person, :index => true
- end
- ```
-
- Is the same as:
-
- ```ruby
- create_table :messages do |t|
- t.references :person
- end
- add_index :messages, :person_id
- ```
-
- Generators have also been updated to use the new syntax.
-
-* Added bang methods for mutating `ActiveRecord::Relation` objects. For example, while `foo.where(:bar)` will return a new object leaving foo unchanged, `foo.where!(:bar)` will mutate the foo object.
-
-* Added `#find_by` and `#find_by!` to mirror the functionality provided by dynamic finders in a way that allows dynamic input more easily:
-
- ```ruby
- Post.find_by name: 'Spartacus', rating: 4
- Post.find_by "published_at < ?", 2.weeks.ago
- Post.find_by! name: 'Spartacus'
- ```
-
-* Added `ActiveRecord::Base#slice` to return a hash of the given methods with their names as keys and returned values as values.
-
-* Remove IdentityMap - IdentityMap has never graduated to be an "enabled-by-default" feature, due to some inconsistencies with associations, as described in this [commit](https://github.com/rails/rails/commit/302c912bf6bcd0fa200d964ec2dc4a44abe328a6). Hence the removal from the codebase, until such issues are fixed.
-
-* Added a feature to dump/load internal state of `SchemaCache` instance because we want to boot more quickly when we have many models.
-
- ```ruby
- # execute rake task.
- RAILS_ENV=production bundle exec rake db:schema:cache:dump
- => generate db/schema_cache.dump
-
- # add config.use_schema_cache_dump = true in config/production.rb. BTW, true is default.
-
- # boot rails.
- RAILS_ENV=production bundle exec rails server
- => use db/schema_cache.dump
+ store :settings, accessors: [ :color, :homepage ], coder: JSON
- # If you remove clear dumped cache, execute rake task.
- RAILS_ENV=production bundle exec rake db:schema:cache:clear
- => remove db/schema_cache.dump
- ```
+* `mysql` and `mysql2` connections will set `SQL_MODE=STRICT_ALL_TABLES` by default to avoid silent data loss. This can be disabled by specifying `strict: false` in your `database.yml`.
-* Added support for partial indices to `PostgreSQL` adapter.
+* Remove IdentityMap.
-* The `add_index` method now supports a `where` option that receives a string with the partial index criteria.
-
-* Added the `ActiveRecord::NullRelation` class implementing the null object pattern for the Relation class.
-
-* Implemented `ActiveRecord::Relation#none` method which returns a chainable relation with zero records (an instance of the `NullRelation` class). Any subsequent condition chained to the returned relation will continue generating an empty relation and will not fire any query to the database.
+* Adds `ActiveRecord::NullRelation` and `ActiveRecord::Relation#none` implementing the null object pattern for the Relation class.
* Added `create_join_table` migration helper to create HABTM join tables.
- ```ruby
- create_join_table :products, :categories
- # =>
- # create_table :categories_products, :id => false do |td|
- # td.integer :product_id, :null => false
- # td.integer :category_id, :null => false
- # end
- ```
-
-* The primary key is always initialized in the `@attributes` hash to nil (unless another value has been specified).
-
-* In previous releases, the following would generate a single query with an OUTER JOIN comments, rather than two separate queries:
-
- ```ruby
- Post.includes(:comments).where("comments.name = 'foo'")
- ```
-
- This behaviour relies on matching SQL string, which is an inherently flawed idea unless we write an SQL parser, which we do not wish to do. Therefore, it is now deprecated.
-
- To avoid deprecation warnings and for future compatibility, you must explicitly state which tables you reference, when using SQL snippets:
-
- ```ruby
- Post.includes(:comments).where("comments.name = 'foo'").references(:comments)
- ```
-
- Note that you do not need to explicitly specify references in the following cases, as they can be automatically inferred:
-
- ```ruby
- Post.where(comments: { name: 'foo' })
- Post.where('comments.name' => 'foo')
- Post.order('comments.name')
- ```
-
- You also do not need to worry about this unless you are doing eager loading. Basically, don't worry unless you see a deprecation warning or (in future releases) an SQL error due to a missing JOIN.
-
-* Support for the `schema_info` table has been dropped. Please switch to `schema_migrations`.
-
-* Connections *must* be closed at the end of a thread. If not, your connection pool can fill and an exception will be raised.
-
-* PostgreSQL hstore records can be created.
-
-* PostgreSQL hstore types are automatically deserialized from the database.
-
-* Added `#update_columns` method which updates the attributes from the passed-in hash without calling save, hence skipping validations and callbacks. `ActiveRecordError` will be raised when called on new objects or when at least one of the attributes is marked as read only.
-
- ```ruby
- post.attributes # => {"id"=>2, "title"=>"My title", "body"=>"My content", "author"=>"Peter"}
- post.update_columns({title: 'New title', author: 'Sebastian'}) # => true
- post.attributes # => {"id"=>2, "title"=>"New title", "body"=>"My content", "author"=>"Sebastian"}
- ```
-
-### Deprecations
-
-* Deprecated most of the 'dynamic finder' methods. All dynamic methods except for `find_by_...` and `find_by_...!` are deprecated. Here's how you can rewrite the code:
-
- ```ruby
- find_all_by_... can be rewritten using where(...)
- find_last_by_... can be rewritten using where(...).last
- scoped_by_... can be rewritten using where(...)
- find_or_initialize_by_... can be rewritten using where(...).first_or_initialize
- find_or_create_by_... can be rewritten using where(...).first_or_create
- find_or_create_by_...! can be rewritten using where(...).first_or_create!
- ```
-
- The implementation of the deprecated dynamic finders has been moved to the `active_record_deprecated_finders` gem.
-
-* Deprecated the old-style hash based finder API. This means that methods which previously accepted "finder options" no longer do. For example this:
-
- ```ruby
- Post.find(:all, :conditions => { :comments_count => 10 }, :limit => 5)
- ```
-
- should be rewritten in the new style which has existed since Rails 3:
-
- ```ruby
- Post.where(comments_count: 10).limit(5)
- ```
-
- Note that as an interim step, it is possible to rewrite the above as:
-
- ```ruby
- Post.scoped(:where => { :comments_count => 10 }, :limit => 5)
- ```
-
- This could save you a lot of work if there is a lot of old-style finder usage in your application.
-
- Calling `Post.scoped(options)` is a shortcut for `Post.scoped.merge(options)`. `Relation#merge` now accepts a hash of options, but they must be identical to the names of the equivalent finder method. These are mostly identical to the old-style finder option names, except in the following cases:
-
- ```
- :conditions becomes :where
- :include becomes :includes
- :extend becomes :extending
- ```
-
- The code to implement the deprecated features has been moved out to the `active_record_deprecated_finders` gem. This gem is a dependency of Active Record in Rails 4.0. It will no longer be a dependency from Rails 4.1, but if your app relies on the deprecated features then you can add it to your own Gemfile. It will be maintained by the Rails core team until Rails 5.0 is released.
-
-* Deprecate eager-evaluated scopes.
-
- Don't use this:
-
- ```ruby
- scope :red, where(color: 'red')
- default_scope where(color: 'red')
- ```
-
- Use this:
-
- ```ruby
- scope :red, -> { where(color: 'red') }
- default_scope { where(color: 'red') }
- ```
-
- The former has numerous issues. It is a common newbie gotcha to do the following:
-
- ```ruby
- scope :recent, where(published_at: Time.now - 2.weeks)
- ```
-
- Or a more subtle variant:
-
- ```ruby
- scope :recent, -> { where(published_at: Time.now - 2.weeks) }
- scope :recent_red, recent.where(color: 'red')
- ```
-
- Eager scopes are also very complex to implement within Active Record, and there are still bugs. For example, the following does not do what you expect:
-
- ```ruby
- scope :remove_conditions, except(:where)
- where(...).remove_conditions # => still has conditions
- ```
-
-* Added deprecation for the `:dependent => :restrict` association option.
-
-* Up until now `has_many` and `has_one, :dependent => :restrict` option raised a `DeleteRestrictionError` at the time of destroying the object. Instead, it will add an error on the model.
-
-* To fix this warning, make sure your code isn't relying on a `DeleteRestrictionError` and then add `config.active_record.dependent_restrict_raises = false` to your application config.
-
-* New rails application would be generated with the `config.active_record.dependent_restrict_raises = false` in the application config.
-
-* The migration generator now creates a join table with (commented) indexes every time the migration name contains the word "join_table".
-
-* `ActiveRecord::SessionStore` is removed from Rails 4.0 and is now a separate [gem](https://github.com/rails/activerecord-session_store).
-
-Active Model
-------------
-
-* Changed `AM::Serializers::JSON.include_root_in_json` default value to false. Now, AM Serializers and AR objects have the same default behaviour.
-
- ```ruby
- class User < ActiveRecord::Base; end
-
- class Person
- include ActiveModel::Model
- include ActiveModel::AttributeMethods
- include ActiveModel::Serializers::JSON
-
- attr_accessor :name, :age
-
- def attributes
- instance_values
- end
- end
-
- user.as_json
- => {"id"=>1, "name"=>"Konata Izumi", "age"=>16, "awesome"=>true}
- # root is not included
-
- person.as_json
- => {"name"=>"Francesco", "age"=>22}
- # root is not included
- ```
-
-* Passing false hash values to `validates` will no longer enable the corresponding validators.
-
-* `ConfirmationValidator` error messages will attach to `:#{attribute}_confirmation` instead of `attribute`.
-
-* Added `ActiveModel::Model`, a mixin to make Ruby objects work with Action Pack out of the box.
-
-* `ActiveModel::Errors#to_json` supports a new parameter `:full_messages`.
-
-* Trims down the API by removing `valid?` and `errors.full_messages`.
-
-### Deprecations
-
-Active Resource
----------------
-
-* Active Resource is removed from Rails 4.0 and is now a separate [gem](https://github.com/rails/activeresource).
-
-Active Support
---------------
-
-* Add default values to all `ActiveSupport::NumberHelper` methods, to avoid errors with empty locales or missing values.
-
-* `Time#change` now works with time values with offsets other than UTC or the local time zone.
-
-* Add `Time#prev_quarter` and `Time#next_quarter` short-hands for `months_ago(3)` and `months_since(3)`.
-
-* Add `Time#last_week`, `Time#last_month`, `Time#last_year` as aliases for `Time#prev_week`, `Time#prev_month`, and `Time#prev_year`.
-
-* Add `Date#last_week`, `Date#last_month`, `Date#last_year` as aliases for `Date#prev_week`, `Date#prev_month`, and `Date#prev_year`.
-
-* Remove obsolete and unused `require_association` method from dependencies.
-
-* Add `:instance_accessor` option for `config_accessor`.
-
- ```ruby
- class User
- include ActiveSupport::Configurable
- config_accessor :allowed_access, instance_accessor: false
- end
-
- User.new.allowed_access = true # => NoMethodError
- User.new.allowed_access # => NoMethodError
- ```
-
-* `ActionView::Helpers::NumberHelper` methods have been moved to `ActiveSupport::NumberHelper` and are now available via `Numeric#to_s`.
-
-* `Numeric#to_s` now accepts the formatting options :phone, :currency, :percentage, :delimited, :rounded, :human, and :human_size.
-
-* Add `Hash#transform_keys`, `Hash#transform_keys!`, `Hash#deep_transform_keys` and `Hash#deep_transform_keys!`.
-
-* Changed xml type datetime to dateTime (with upper case letter T).
-
-* Add `:instance_accessor` option for `class_attribute`.
-
-* `constantize` now looks in the ancestor chain.
-
-* Add `Hash#deep_stringify_keys` and `Hash#deep_stringify_keys!` to convert all keys from a `Hash` instance into strings.
-
-* Add `Hash#deep_symbolize_keys` and `Hash#deep_symbolize_keys!` to convert all keys from a `Hash` instance into symbols.
-
-* `Object#try` can't call private methods.
-
-* AS::Callbacks#run_callbacks remove key argument.
-
-* `deep_dup` works more expectedly now and duplicates also values in `Hash` instances and elements in `Array` instances.
-
-* Inflector no longer applies ice -> ouse to words like slice, police.
-
-* Add `ActiveSupport::Deprecations.behavior = :silence` to completely ignore Rails runtime deprecations.
-
-* Make `Module#delegate` stop using send - can no longer delegate to private methods.
-
-* AS::Callbacks deprecate :rescuable option.
-
-* Adds `Integer#ordinal` to get the ordinal suffix string of an integer.
-
-* AS::Callbacks :per_key option is no longer supported.
-
-* AS::Callbacks#define_callbacks add :skip_after_callbacks_if_terminated option.
-
-* Add html_escape_once to ERB::Util, and delegate escape_once tag helper to it.
-
-* Remove `ActiveSupport::TestCase#pending` method, use `skip` instead.
-
-* Deletes the compatibility method `Module#method_names`, use `Module#methods` from now on (which returns symbols).
-
-* Deletes the compatibility method `Module#instance_method_names`, use `Module#instance_methods` from now on (which returns symbols).
-
-* Unicode database updated to 6.1.0.
-
-* Adds `encode_big_decimal_as_string` option to force JSON serialization of BigDecimals as numeric instead of wrapping them in strings for safety.
+* Allows PostgreSQL hstore records to be created.
### Deprecations
-* `ActiveSupport::Callbacks`: deprecate usage of filter object with `#before` and `#after` methods as `around` callback.
+* Deprecated the old-style hash based finder API. This means that methods which previously accepted "finder options" no longer do.
-* `BufferedLogger` is deprecated. Use `ActiveSupport::Logger` or the `logger` from Ruby stdlib.
+* All dynamic methods except for `find_by_...` and `find_by_...!` are deprecated. Here's
+ how you can rewrite the code:
-* Deprecates the compatibility method `Module#local_constant_names` and use `Module#local_constants` instead (which returns symbols).
+ * `find_all_by_...` can be rewritten using `where(...)`.
+ * `find_last_by_...` can be rewritten using `where(...).last`.
+ * `scoped_by_...` can be rewritten using `where(...)`.
+ * `find_or_initialize_by_...` can be rewritten using `where(...).first_or_initialize`.
+ * `find_or_create_by_...` can be rewritten using `find_or_create_by(...)` or `where(...).first_or_create`.
+ * `find_or_create_by_...!` can be rewritten using `find_or_create_by!(...)` or `where(...).first_or_create!`.
Credits
-------
diff --git a/guides/source/_welcome.html.erb b/guides/source/_welcome.html.erb
index 9d2e9c1d68..a50961a0c7 100644
--- a/guides/source/_welcome.html.erb
+++ b/guides/source/_welcome.html.erb
@@ -1,4 +1,4 @@
-<h2>Ruby on Rails Guides (<%= @version %>)</h2>
+<h2>Ruby on Rails Guides (<%= @edge ? @version[0, 7] : @version %>)</h2>
<% if @edge %>
<p>
diff --git a/guides/source/action_controller_overview.md b/guides/source/action_controller_overview.md
index 6f161e83ea..46ff9027fd 100644
--- a/guides/source/action_controller_overview.md
+++ b/guides/source/action_controller_overview.md
@@ -1,15 +1,17 @@
Action Controller Overview
==========================
-In this guide you will learn how controllers work and how they fit into the request cycle in your application. After reading this guide, you will be able to:
+In this guide you will learn how controllers work and how they fit into the request cycle in your application.
-* Follow the flow of a request through a controller
-* Understand why and how to store data in the session or cookies
-* Work with filters to execute code during request processing
-* Use Action Controller's built-in HTTP authentication
-* Stream data directly to the user's browser
-* Filter sensitive parameters so they do not appear in the application's log
-* Deal with exceptions that may be raised during request processing
+After reading this guide, you will know:
+
+* How to follow the flow of a request through a controller.
+* Why and how to store data in the session or cookies.
+* How to work with filters to execute code during request processing.
+* How to use Action Controller's built-in HTTP authentication.
+* How to stream data directly to the user's browser.
+* How to filter sensitive parameters so they do not appear in the application's log.
+* How to deal with exceptions that may be raised during request processing.
--------------------------------------------------------------------------------
@@ -432,7 +434,7 @@ Filters are inherited, so if you set a filter on `ApplicationController`, it wil
```ruby
class ApplicationController < ActionController::Base
- before_filter :require_login
+ before_action :require_login
private
@@ -456,11 +458,11 @@ end
The method simply stores an error message in the flash and redirects to the login form if the user is not logged in. If a "before" filter renders or redirects, the action will not run. If there are additional filters scheduled to run after that filter, they are also cancelled.
-In this example the filter is added to `ApplicationController` and thus all controllers in the application inherit it. This will make everything in the application require the user to be logged in in order to use it. For obvious reasons (the user wouldn't be able to log in in the first place!), not all controllers or actions should require this. You can prevent this filter from running before particular actions with `skip_before_filter`:
+In this example the filter is added to `ApplicationController` and thus all controllers in the application inherit it. This will make everything in the application require the user to be logged in in order to use it. For obvious reasons (the user wouldn't be able to log in in the first place!), not all controllers or actions should require this. You can prevent this filter from running before particular actions with `skip_before_action`:
```ruby
class LoginsController < ApplicationController
- skip_before_filter :require_login, only: [:new, :create]
+ skip_before_action :require_login, only: [:new, :create]
end
```
@@ -478,7 +480,7 @@ For example, in a website where changes have an approval workflow an administrat
```ruby
class ChangesController < ActionController::Base
- around_filter :wrap_in_transaction, only: :show
+ around_action :wrap_in_transaction, only: :show
private
@@ -500,13 +502,13 @@ You can choose not to yield and build the response yourself, in which case the a
### Other Ways to Use Filters
-While the most common way to use filters is by creating private methods and using *_filter to add them, there are two other ways to do the same thing.
+While the most common way to use filters is by creating private methods and using *_action to add them, there are two other ways to do the same thing.
-The first is to use a block directly with the *_filter methods. The block receives the controller as an argument, and the `require_login` filter from above could be rewritten to use a block:
+The first is to use a block directly with the *_action methods. The block receives the controller as an argument, and the `require_login` filter from above could be rewritten to use a block:
```ruby
class ApplicationController < ActionController::Base
- before_filter do |controller|
+ before_action do |controller|
redirect_to new_login_url unless controller.send(:logged_in?)
end
end
@@ -518,7 +520,7 @@ The second way is to use a class (actually, any object that responds to the righ
```ruby
class ApplicationController < ActionController::Base
- before_filter LoginFilter
+ before_action LoginFilter
end
class LoginFilter
@@ -646,7 +648,7 @@ HTTP digest authentication is superior to the basic authentication as it does no
class AdminController < ApplicationController
USERS = { "lifo" => "world" }
- before_filter :authenticate
+ before_action :authenticate
private
@@ -749,15 +751,36 @@ Now the user can request to get a PDF version of a client just by adding ".pdf"
GET /clients/1.pdf
```
-Parameter Filtering
--------------------
+Log Filtering
+-------------
+
+Rails keeps a log file for each environment in the `log` folder. These are extremely useful when debugging what's actually going on in your application, but in a live application you may not want every bit of information to be stored in the log file.
+
+### Parameters Filtering
-Rails keeps a log file for each environment in the `log` folder. These are extremely useful when debugging what's actually going on in your application, but in a live application you may not want every bit of information to be stored in the log file. You can filter certain request parameters from your log files by appending them to `config.filter_parameters` in the application configuration. These parameters will be marked [FILTERED] in the log.
+You can filter certain request parameters from your log files by appending them to `config.filter_parameters` in the application configuration. These parameters will be marked [FILTERED] in the log.
```ruby
config.filter_parameters << :password
```
+### Redirects Filtering
+
+Sometimes it's desirable to filter out from log files some sensible locations your application is redirecting to.
+You can do that by using the `config.filter_redirect` configuration option:
+
+```ruby
+config.filter_redirect << 's3.amazonaws.com'
+```
+
+You can set it to a String, a Regexp, or an array of both.
+
+```ruby
+config.filter_redirect.concat ['s3.amazonaws.com', /private_path/]
+```
+
+Matching URLs will be marked as '[FILTERED]'.
+
Rescue
------
@@ -805,7 +828,7 @@ end
class ClientsController < ApplicationController
# Check that the user has the right authorization to access clients.
- before_filter :check_authorization
+ before_action :check_authorization
# Note how the actions don't have to worry about all the auth stuff.
def edit
@@ -826,7 +849,7 @@ NOTE: Certain exceptions are only rescuable from the `ApplicationController` cla
Force HTTPS protocol
--------------------
-Sometime you might want to force a particular controller to only be accessible via an HTTPS protocol for security reasons. Since Rails 3.1 you can now use the `force_ssl` method in your controller to enforce that:
+Sometime you might want to force a particular controller to only be accessible via an HTTPS protocol for security reasons. You can use the `force_ssl` method in your controller to enforce that:
```ruby
class DinnerController
@@ -834,7 +857,7 @@ class DinnerController
end
```
-Just like the filter, you could also passing `:only` and `:except` to enforce the secure connection only to specific actions:
+Just like the filter, you could also pass `:only` and `:except` to enforce the secure connection only to specific actions:
```ruby
class DinnerController
diff --git a/guides/source/action_mailer_basics.md b/guides/source/action_mailer_basics.md
index 8687cfea52..aaf04f4256 100644
--- a/guides/source/action_mailer_basics.md
+++ b/guides/source/action_mailer_basics.md
@@ -3,9 +3,13 @@ Action Mailer Basics
This guide should provide you with all you need to get started in sending and receiving emails from and to your application, and many internals of Action Mailer. It also covers how to test your mailers.
---------------------------------------------------------------------------------
+After reading this guide, you will know:
-WARNING. This guide is based on Rails 3.2. Some of the code shown here will not work in earlier versions of Rails.
+* How to send and receive email within a Rails application.
+* How to generate and edit an Action Mailer class and mailer view.
+* How to configure Action Mailer for your environment.
+* How to test your Action Mailer classes.
+--------------------------------------------------------------------------------
Introduction
------------
@@ -105,7 +109,7 @@ When you call the `mail` method now, Action Mailer will detect the two templates
#### Wire It Up So That the System Sends the Email When a User Signs Up
-There are several ways to do this, some people create Rails Observers to fire off emails, others do it inside of the User Model. However, in Rails 3, mailers are really just another way to render a view. Instead of rendering a view and sending out the HTTP protocol, they are just sending it out through the Email protocols instead. Due to this, it makes sense to just have your controller tell the mailer to send an email when a user is successfully created.
+There are several ways to do this, some people create Rails Observers to fire off emails, others do it inside of the User Model. However, mailers are really just another way to render a view. Instead of rendering a view and sending out the HTTP protocol, they are just sending it out through the Email protocols instead. Due to this, it makes sense to just have your controller tell the mailer to send an email when a user is successfully created.
Setting this up is painfully simple.
@@ -145,10 +149,6 @@ This provides a much simpler implementation that does not require the registerin
The method `welcome_email` returns a `Mail::Message` object which can then just be told `deliver` to send itself out.
-NOTE: In previous versions of Rails, you would call `deliver_welcome_email` or `create_welcome_email`. This has been deprecated in Rails 3.0 in favour of just calling the method name itself.
-
-WARNING: Sending out an email should only take a fraction of a second. If you are planning on sending out many emails, or you have a slow domain resolution service, you might want to investigate using a background process like Delayed Job.
-
### Auto encoding header values
Action Mailer now handles the auto encoding of multibyte characters inside of headers and bodies.
@@ -397,7 +397,7 @@ end
The above will send a multipart email with an attachment, properly nested with the top level being `multipart/mixed` and the first part being a `multipart/alternative` containing the plain text and HTML email messages.
-#### Sending Emails with Dynamic Delivery Options
+### Sending Emails with Dynamic Delivery Options
If you wish to override the default delivery options (e.g. SMTP credentials) while delivering emails, you can do this using `delivery_method_options` in the mailer action.
@@ -444,6 +444,57 @@ class UserMailer < ActionMailer::Base
end
```
+Action Mailer Callbacks
+---------------------------
+
+Action Mailer allows for you to specify a `before_action`, `after_action` and 'around_action'.
+
+* Filters can be specified with a block or a symbol to a method in the mailer class similar to controllers.
+
+* You could use a `before_action` to prepopulate the mail object with defaults, delivery_method_options or insert default headers and attachments.
+
+* You could use an `after_action` to do similar setup as a `before_action` but using instance variables set in your mailer action.
+
+```ruby
+class UserMailer < ActionMailer::Base
+ after_action :set_delivery_options, :prevent_delivery_to_guests, :set_business_headers
+
+ def feedback_message(business, user)
+ @business = business
+ @user = user
+ mail
+ end
+
+ def campaign_message(business, user)
+ @business = business
+ @user = user
+ end
+
+ private
+
+ def set_delivery_options
+ # You have access to the mail instance and @business and @user instance variables here
+ if @business && @business.has_smtp_settings?
+ mail.delivery_method.settings.merge!(@business.smtp_settings)
+ end
+ end
+
+ def prevent_delivery_to_guests
+ if @user && @user.guest?
+ mail.perform_deliveries = false
+ end
+ end
+
+ def set_business_headers
+ if @business
+ headers["X-SMTPAPI-CATEGORY"] = @business.code
+ end
+ end
+end
+```
+
+* Mailer Filters abort further processing if body is set to a non-nil value.
+
Using Action Mailer Helpers
---------------------------
diff --git a/guides/source/action_view_overview.md b/guides/source/action_view_overview.md
index 2625e237bf..6c2871d478 100644
--- a/guides/source/action_view_overview.md
+++ b/guides/source/action_view_overview.md
@@ -1,13 +1,13 @@
Action View Overview
====================
-In this guide you will learn:
+After reading this guide, you will know:
-* What Action View is and how to use it with Rails
-* How best to use templates, partials, and layouts
-* What helpers are provided by Action View and how to make your own
-* How to use localized views
-* How to use Action View outside of Rails
+* What Action View is and how to use it with Rails.
+* How best to use templates, partials, and layouts.
+* What helpers are provided by Action View and how to make your own.
+* How to use localized views.
+* How to use Action View outside of Rails.
--------------------------------------------------------------------------------
@@ -1263,10 +1263,8 @@ Creates a field set for grouping HTML form elements.
Creates a file upload field.
-Prior to Rails 3.1, if you are using file uploads, then you will need to set the multipart option for the form tag. Rails 3.1+ does this automatically.
-
```html+erb
-<%= form_tag {action: "post"}, {multipart: true} do %>
+<%= form_tag {action: "post"} do %>
<label for="file">File to Upload</label> <%= file_field_tag "file" %>
<%= submit_tag %>
<% end %>
@@ -1486,7 +1484,7 @@ You can use the same technique to localize the rescue files in your public direc
Since Rails doesn't restrict the symbols that you use to set I18n.locale, you can leverage this system to display different content depending on anything you like. For example, suppose you have some "expert" users that should see different pages from "normal" users. You could add the following to `app/controllers/application.rb`:
```ruby
-before_filter :set_expert_locale
+before_action :set_expert_locale
def set_expert_locale
I18n.locale = :expert if current_user.expert?
diff --git a/guides/source/active_model_basics.md b/guides/source/active_model_basics.md
index 92b51334a3..68ac26c681 100644
--- a/guides/source/active_model_basics.md
+++ b/guides/source/active_model_basics.md
@@ -1,16 +1,16 @@
Active Model Basics
===================
-This guide should provide you with all you need to get started using model classes. Active Model allows for Action Pack helpers to interact with non-ActiveRecord models. Active Model also helps building custom ORMs for use outside of the Rails framework.
+This guide should provide you with all you need to get started using model classes. Active Model allows for Action Pack helpers to interact with non-Active Record models. Active Model also helps building custom ORMs for use outside of the Rails framework.
---------------------------------------------------------------------------------
+After reading this guide, you will know:
-WARNING. This guide is based on Rails 3.0. Some of the code shown here will not work in earlier versions of Rails.
+--------------------------------------------------------------------------------
Introduction
------------
-Active Model is a library containing various modules used in developing frameworks that need to interact with the Rails Action Pack library. Active Model provides a known set of interfaces for usage in classes. Some of modules are explained below.
+Active Model is a library containing various modules used in developing frameworks that need to interact with the Rails Action Pack library. Active Model provides a known set of interfaces for usage in classes. Some of modules are explained below.
### AttributeMethods
@@ -26,23 +26,21 @@ class Person
attr_accessor :age
-private
- def reset_attribute(attribute)
- send("#{attribute}=", 0)
- end
+ private
+ def reset_attribute(attribute)
+ send("#{attribute}=", 0)
+ end
- def attribute_highest?(attribute)
- send(attribute) > 100 ? true : false
- end
-
+ def attribute_highest?(attribute)
+ send(attribute) > 100
+ end
end
person = Person.new
person.age = 110
person.age_highest? # true
person.reset_age # 0
-person.age_highest? # false
-
+person.age_highest? # false
```
### Callbacks
@@ -87,14 +85,14 @@ class Person
end
person = Person.new
-person.to_model == person #=> true
-person.to_key #=> nil
-person.to_param #=> nil
+person.to_model == person # => true
+person.to_key # => nil
+person.to_param # => nil
```
### Dirty
-An object becomes dirty when it has gone through one or more changes to its attributes and has not been saved. This gives the ability to check whether an object has been changed or not. It also has attribute based accessor methods. Let's consider a Person class with attributes first_name and last_name
+An object becomes dirty when it has gone through one or more changes to its attributes and has not been saved. This gives the ability to check whether an object has been changed or not. It also has attribute based accessor methods. Let's consider a Person class with attributes `first_name` and `last_name`:
```ruby
require 'active_model'
@@ -123,8 +121,8 @@ class Person
def save
@previously_changed = changes
+ # do save work...
end
-
end
```
@@ -132,21 +130,22 @@ end
```ruby
person = Person.new
-person.first_name = "First Name"
+person.changed? # => false
-person.first_name #=> "First Name"
-person.first_name = "First Name Changed"
+person.first_name = "First Name"
+person.first_name # => "First Name"
-person.changed? #=> true
+# returns if any attribute has changed.
+person.changed? # => true
-#returns an list of fields arry which all has been changed before saved.
-person.changed #=> ["first_name"]
+# returns a list of attributes that have changed before saving.
+person.changed # => ["first_name"]
-#returns a hash of the fields that have changed with their original values.
-person.changed_attributes #=> {"first_name" => "First Name Changed"}
+# returns a hash of the attributes that have changed with their original values.
+person.changed_attributes # => {"first_name"=>nil}
-#returns a hash of changes, with the attribute names as the keys, and the values will be an array of the old and new value for that field.
-person.changes #=> {"first_name" => ["First Name","First Name Changed"]}
+# returns a hash of changes, with the attribute names as the keys, and the values will be an array of the old and new value for that field.
+person.changes # => {"first_name"=>[nil, "First Name"]}
```
#### Attribute based accessor methods
@@ -154,28 +153,24 @@ person.changes #=> {"first_name" => ["First Name","First Name Changed"]}
Track whether the particular attribute has been changed or not.
```ruby
-#attr_name_changed?
-person.first_name #=> "First Name"
-
-#assign some other value to first_name attribute
-person.first_name = "First Name 1"
-
-person.first_name_changed? #=> true
+# attr_name_changed?
+person.first_name # => "First Name"
+person.first_name_changed? # => true
```
Track what was the previous value of the attribute.
```ruby
-#attr_name_was accessor
-person.first_name_was #=> "First Name"
+# attr_name_was accessor
+person.first_name_was # => "First Name"
```
Track both previous and current value of the changed attribute. Returns an array if changed, else returns nil.
```ruby
-#attr_name_change
-person.first_name_change #=> ["First Name", "First Name 1"]
-person.last_name_change #=> nil
+# attr_name_change
+person.first_name_change # => [nil, "First Name"]
+person.last_name_change # => nil
```
### Validations
@@ -187,20 +182,19 @@ class Person
include ActiveModel::Validations
attr_accessor :name, :email, :token
-
+
validates :name, presence: true
- validates_format_of :email, with: /\A([^\s]+)((?:[-a-z0-9]\.)[a-z]{2,})\z/i
+ validates_format_of :email, with: /\A([^\s]+)((?:[-a-z0-9]\.)[a-z]{2,})\z/i
validates! :token, presence: true
-
end
person = Person.new(token: "2b1f325")
-person.valid? #=> false
-person.name = 'vishnu'
-person.email = 'me'
-person.valid? #=> false
+person.valid? # => false
+person.name = 'vishnu'
+person.email = 'me'
+person.valid? # => false
person.email = 'me@vishnuatrai.com'
-person.valid? #=> true
+person.valid? # => true
person.token = nil
-person.valid? #=> raises ActiveModel::StrictValidationFailed
+person.valid? # => raises ActiveModel::StrictValidationFailed
```
diff --git a/guides/source/active_record_basics.md b/guides/source/active_record_basics.md
index 810a0263c0..68c6416e89 100644
--- a/guides/source/active_record_basics.md
+++ b/guides/source/active_record_basics.md
@@ -1,13 +1,15 @@
Active Record Basics
====================
-This guide is an introduction to Active Record. After reading this guide we hope that you'll learn:
+This guide is an introduction to Active Record.
-* What Object Relational Mapping and Active Record are and how they are used in Rails
-* How Active Record fits into the Model-View-Controller paradigm
-* How to use Active Record models to manipulate data stored in a relational database
-* Active Record schema naming conventions
-* The concepts of database migrations, validations and callbacks
+After reading this guide, you will know:
+
+* What Object Relational Mapping and Active Record are and how they are used in Rails.
+* How Active Record fits into the Model-View-Controller paradigm.
+* How to use Active Record models to manipulate data stored in a relational database.
+* Active Record schema naming conventions.
+* The concepts of database migrations, validations and callbacks.
--------------------------------------------------------------------------------
@@ -145,15 +147,15 @@ Active Record objects can be created from a hash, a block or have their attribut
For example, given a model `User` with attributes of `name` and `occupation`, the `create` method call will create and save a new record into the database:
```ruby
- user = User.create(name: "David", occupation: "Code Artist")
+user = User.create(name: "David", occupation: "Code Artist")
```
Using the `new` method, an object can be created without being saved:
```ruby
- user = User.new
- user.name = "David"
- user.occupation = "Code Artist"
+user = User.new
+user.name = "David"
+user.occupation = "Code Artist"
```
A call to `user.save` will commit the record to the database.
@@ -161,10 +163,10 @@ A call to `user.save` will commit the record to the database.
Finally, if a block is provided, both `create` and `new` will yield the new object to that block for initialization:
```ruby
- user = User.new do |u|
- u.name = "David"
- u.occupation = "Code Artist"
- end
+user = User.new do |u|
+ u.name = "David"
+ u.occupation = "Code Artist"
+end
```
### Read
@@ -172,23 +174,23 @@ Finally, if a block is provided, both `create` and `new` will yield the new obje
Active Record provides a rich API for accessing data within a database. Below are a few examples of different data access methods provided by Active Record.
```ruby
- # return array with all records
- users = User.all
+# return array with all records
+users = User.all
```
```ruby
- # return the first record
- user = User.first
+# return the first record
+user = User.first
```
```ruby
- # return the first user named David
- david = User.find_by_name('David')
+# return the first user named David
+david = User.find_by_name('David')
```
```ruby
- # find all users named David who are Code Artists and sort by created_at in reverse chronological order
- users = User.where(name: 'David', occupation: 'Code Artist').order('created_at DESC')
+# find all users named David who are Code Artists and sort by created_at in reverse chronological order
+users = User.where(name: 'David', occupation: 'Code Artist').order('created_at DESC')
```
You can learn more about querying an Active Record model in the [Active Record Query Interface](active_record_querying.html) guide.
@@ -198,9 +200,9 @@ You can learn more about querying an Active Record model in the [Active Record Q
Once an Active Record object has been retrieved, its attributes can be modified and it can be saved to the database.
```ruby
- user = User.find_by_name('David')
- user.name = 'Dave'
- user.save
+user = User.find_by_name('David')
+user.name = 'Dave'
+user.save
```
### Delete
@@ -208,8 +210,8 @@ Once an Active Record object has been retrieved, its attributes can be modified
Likewise, once retrieved an Active Record object can be destroyed which removes it from the database.
```ruby
- user = User.find_by_name('David')
- user.destroy
+user = User.find_by_name('David')
+user.destroy
```
Validations
diff --git a/guides/source/active_record_callbacks.md b/guides/source/active_record_callbacks.md
new file mode 100644
index 0000000000..971c1cdb25
--- /dev/null
+++ b/guides/source/active_record_callbacks.md
@@ -0,0 +1,361 @@
+Active Record Callbacks
+=======================
+
+This guide teaches you how to hook into the life cycle of your Active Record
+objects.
+
+After reading this guide, you will know:
+
+* The life cycle of Active Record objects.
+* How to create callback methods that respond to events in the object life cycle.
+* How to create special classes that encapsulate common behavior for your callbacks.
+
+--------------------------------------------------------------------------------
+
+The Object Life Cycle
+---------------------
+
+During the normal operation of a Rails application, objects may be created, updated, and destroyed. Active Record provides hooks into this <em>object life cycle</em> so that you can control your application and its data.
+
+Callbacks allow you to trigger logic before or after an alteration of an object's state.
+
+Callbacks Overview
+------------------
+
+Callbacks are methods that get called at certain moments of an object's life cycle. With callbacks it is possible to write code that will run whenever an Active Record object is created, saved, updated, deleted, validated, or loaded from the database.
+
+### Callback Registration
+
+In order to use the available callbacks, you need to register them. You can implement the callbacks as ordinary methods and use a macro-style class method to register them as callbacks:
+
+```ruby
+class User < ActiveRecord::Base
+ validates :login, :email, presence: true
+
+ before_validation :ensure_login_has_a_value
+
+ protected
+ def ensure_login_has_a_value
+ if login.nil?
+ self.login = email unless email.blank?
+ end
+ end
+end
+```
+
+The macro-style class methods can also receive a block. Consider using this style if the code inside your block is so short that it fits in a single line:
+
+```ruby
+class User < ActiveRecord::Base
+ validates :login, :email, presence: true
+
+ before_create do |user|
+ user.name = user.login.capitalize if user.name.blank?
+ end
+end
+```
+
+Callbacks can also be registered to only fire on certain lifecycle events:
+
+```ruby
+class User < ActiveRecord::Base
+ before_validation :normalize_name, on: :create
+
+ # :on takes an array as well
+ after_validation :set_location, on: [ :create, :update ]
+
+ protected
+ def normalize_name
+ self.name = self.name.downcase.titleize
+ end
+
+ def set_location
+ self.location = LocationService.query(self)
+ end
+end
+```
+
+It is considered good practice to declare callback methods as protected or private. If left public, they can be called from outside of the model and violate the principle of object encapsulation.
+
+Available Callbacks
+-------------------
+
+Here is a list with all the available Active Record callbacks, listed in the same order in which they will get called during the respective operations:
+
+### Creating an Object
+
+* `before_validation`
+* `after_validation`
+* `before_save`
+* `around_save`
+* `before_create`
+* `around_create`
+* `after_create`
+* `after_save`
+
+### Updating an Object
+
+* `before_validation`
+* `after_validation`
+* `before_save`
+* `around_save`
+* `before_update`
+* `around_update`
+* `after_update`
+* `after_save`
+
+### Destroying an Object
+
+* `before_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.
+
+### `after_initialize` and `after_find`
+
+The `after_initialize` callback will be called whenever an Active Record object is instantiated, either by directly using `new` or when a record is loaded from the database. It can be useful to avoid the need to directly override your Active Record `initialize` method.
+
+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 have no `before_*` counterparts, but they can be registered just like the other Active Record callbacks.
+
+```ruby
+class User < ActiveRecord::Base
+ after_initialize do |user|
+ puts "You have initialized an object!"
+ end
+
+ after_find do |user|
+ puts "You have found an object!"
+ end
+end
+
+>> User.new
+You have initialized an object!
+=> #<User id: nil>
+
+>> User.first
+You have found an object!
+You have initialized an object!
+=> #<User id: 1>
+```
+
+Running Callbacks
+-----------------
+
+The following methods trigger callbacks:
+
+* `create`
+* `create!`
+* `decrement!`
+* `destroy`
+* `destroy_all`
+* `increment!`
+* `save`
+* `save!`
+* `save(validate: false)`
+* `toggle!`
+* `update`
+* `update_attribute`
+* `update_attributes`
+* `update_attributes!`
+* `valid?`
+
+Additionally, the `after_find` callback is triggered by the following finder methods:
+
+* `all`
+* `first`
+* `find`
+* `find_all_by_*`
+* `find_by_*`
+* `find_by_*!`
+* `find_by_sql`
+* `last`
+
+The `after_initialize` callback is triggered every time a new object of the class is initialized.
+
+NOTE: The `find_all_by_*`, `find_by_*` and `find_by_*!` methods are dynamic finders generated automatically for every attribute. Learn more about them at the [Dynamic finders section](active_record_querying.html#dynamic-finders)
+
+Skipping Callbacks
+------------------
+
+Just as with validations, it is also possible to skip callbacks. These methods should be used with caution, however, because important business rules and application logic may be kept in callbacks. Bypassing them without understanding the potential implications may lead to invalid data.
+
+* `decrement`
+* `decrement_counter`
+* `delete`
+* `delete_all`
+* `increment`
+* `increment_counter`
+* `toggle`
+* `touch`
+* `update_column`
+* `update_columns`
+* `update_all`
+* `update_counters`
+
+Halting Execution
+-----------------
+
+As you start registering new callbacks for your models, they will be queued for execution. This queue will include all your model's validations, the registered callbacks, and the database operation to be executed.
+
+The whole callback chain is wrapped in a transaction. If any _before_ callback method returns exactly `false` or raises an exception, the execution chain gets halted and a ROLLBACK is issued; _after_ callbacks can only accomplish that by raising an exception.
+
+WARNING. Raising an arbitrary exception may break code that expects `save` and its friends not to fail like that. The `ActiveRecord::Rollback` exception is thought precisely to tell Active Record a rollback is going on. That one is internally captured but not reraised.
+
+Relational Callbacks
+--------------------
+
+Callbacks work through model relationships, and can even be defined by them. Suppose an example where a user has many posts. A user's posts should be destroyed if the user is destroyed. Let's add an `after_destroy` callback to the `User` model by way of its relationship to the `Post` model:
+
+```ruby
+class User < ActiveRecord::Base
+ has_many :posts, dependent: :destroy
+end
+
+class Post < ActiveRecord::Base
+ after_destroy :log_destroy_action
+
+ def log_destroy_action
+ puts 'Post destroyed'
+ end
+end
+
+>> user = User.first
+=> #<User id: 1>
+>> user.posts.create!
+=> #<Post id: 1, user_id: 1>
+>> user.destroy
+Post destroyed
+=> #<User id: 1>
+```
+
+Conditional Callbacks
+---------------------
+
+As with validations, we can also make the calling of a callback method conditional on the satisfaction of a given predicate. We can do this using the `:if` and `:unless` options, which can take a symbol, a string, a `Proc` or an `Array`. You may use the `:if` option when you want to specify under which conditions the callback **should** be called. If you want to specify the conditions under which the callback **should not** be called, then you may use the `:unless` option.
+
+### Using `:if` and `:unless` with a `Symbol`
+
+You can associate the `:if` and `:unless` options with a symbol corresponding to the name of a predicate method that will get called right before the callback. When using the `:if` option, the callback won't be executed if the predicate method returns false; when using the `:unless` option, the callback won't be executed if the predicate method returns true. This is the most common option. Using this form of registration it is also possible to register several different predicates that should be called to check if the callback should be executed.
+
+```ruby
+class Order < ActiveRecord::Base
+ before_save :normalize_card_number, if: :paid_with_card?
+end
+```
+
+### Using `:if` and `:unless` with a String
+
+You can also use a string that will be evaluated using `eval` and hence needs to contain valid Ruby code. You should use this option only when the string represents a really short condition:
+
+```ruby
+class Order < ActiveRecord::Base
+ before_save :normalize_card_number, if: "paid_with_card?"
+end
+```
+
+### Using `:if` and `:unless` with a `Proc`
+
+Finally, it is possible to associate `:if` and `:unless` with a `Proc` object. This option is best suited when writing short validation methods, usually one-liners:
+
+```ruby
+class Order < ActiveRecord::Base
+ before_save :normalize_card_number,
+ if: Proc.new { |order| order.paid_with_card? }
+end
+```
+
+### Multiple Conditions for Callbacks
+
+When writing conditional callbacks, it is possible to mix both `:if` and `:unless` in the same callback declaration:
+
+```ruby
+class Comment < ActiveRecord::Base
+ after_create :send_email_to_author, if: :author_wants_emails?,
+ unless: Proc.new { |comment| comment.post.ignore_comments? }
+end
+```
+
+Callback Classes
+----------------
+
+Sometimes the callback methods that you'll write will be useful enough to be reused by other models. Active Record makes it possible to create classes that encapsulate the callback methods, so it becomes very easy to reuse them.
+
+Here's an example where we create a class with an `after_destroy` callback for a `PictureFile` model:
+
+```ruby
+class PictureFileCallbacks
+ def after_destroy(picture_file)
+ if File.exists?(picture_file.filepath)
+ File.delete(picture_file.filepath)
+ end
+ end
+end
+```
+
+When declared inside a class, as above, the callback methods will receive the model object as a parameter. We can now use the callback class in the model:
+
+```ruby
+class PictureFile < ActiveRecord::Base
+ after_destroy PictureFileCallbacks.new
+end
+```
+
+Note that we needed to instantiate a new `PictureFileCallbacks` object, since we declared our callback as an instance method. This is particularly useful if the callbacks make use of the state of the instantiated object. Often, however, it will make more sense to declare the callbacks as class methods:
+
+```ruby
+class PictureFileCallbacks
+ def self.after_destroy(picture_file)
+ if File.exists?(picture_file.filepath)
+ File.delete(picture_file.filepath)
+ end
+ end
+end
+```
+
+If the callback method is declared this way, it won't be necessary to instantiate a `PictureFileCallbacks` object.
+
+```ruby
+class PictureFile < ActiveRecord::Base
+ after_destroy PictureFileCallbacks
+end
+```
+
+You can declare as many callbacks as you want inside your callback classes.
+
+Transaction Callbacks
+---------------------
+
+There are two additional callbacks that are triggered by the completion of a database transaction: `after_commit` and `after_rollback`. These callbacks are very similar to the `after_save` callback except that they don't execute until after database changes have either been committed or rolled back. They are most useful when your active record models need to interact with external systems which are not part of the database transaction.
+
+Consider, for example, the previous example where the `PictureFile` model needs to delete a file after the corresponding record is destroyed. If anything raises an exception after the `after_destroy` callback is called and the transaction rolls back, the file will have been deleted and the model will be left in an inconsistent state. For example, suppose that `picture_file_2` in the code below is not valid and the `save!` method raises an error.
+
+```ruby
+PictureFile.transaction do
+ picture_file_1.destroy
+ picture_file_2.save!
+end
+```
+
+By using the `after_commit` callback we can account for this case.
+
+```ruby
+class PictureFile < ActiveRecord::Base
+ attr_accessor :delete_file
+
+ after_destroy do |picture_file|
+ picture_file.delete_file = picture_file.filepath
+ end
+
+ after_commit do |picture_file|
+ if picture_file.delete_file && File.exist?(picture_file.delete_file)
+ File.delete(picture_file.delete_file)
+ picture_file.delete_file = nil
+ end
+ end
+end
+```
+
+The `after_commit` and `after_rollback` callbacks are guaranteed to be called for all models created, updated, or destroyed within a transaction block. If any exceptions are raised within one of these callbacks, they will be ignored so that they don't interfere with the other callbacks. As such, if your callback code could raise an exception, you'll need to rescue it and handle it appropriately within the callback.
diff --git a/guides/source/active_record_querying.md b/guides/source/active_record_querying.md
index 32c139df99..24f98f68ca 100644
--- a/guides/source/active_record_querying.md
+++ b/guides/source/active_record_querying.md
@@ -1,15 +1,17 @@
Active Record Query Interface
=============================
-This guide covers different ways to retrieve data from the database using Active Record. By referring to this guide, you will be able to:
+This guide covers different ways to retrieve data from the database using Active Record.
-* Find records using a variety of methods and conditions
-* Specify the order, retrieved attributes, grouping, and other properties of the found records
-* Use eager loading to reduce the number of database queries needed for data retrieval
-* Use dynamic finders methods
-* Check for the existence of particular records
-* Perform various calculations on Active Record models
-* Run EXPLAIN on relations
+After reading this guide, you will know:
+
+* How to find records using a variety of methods and conditions.
+* How to specify the order, retrieved attributes, grouping, and other properties of the found records.
+* How to use eager loading to reduce the number of database queries needed for data retrieval.
+* How to use dynamic finders methods.
+* How to check for the existence of particular records.
+* How to perform various calculations on Active Record models.
+* How to run EXPLAIN on relations.
--------------------------------------------------------------------------------
@@ -466,7 +468,7 @@ The field name can also be a string:
Client.where('locked' => true)
```
-In the case of a belongs_to relationship, an association key can be used to specify the model if an ActiveRecord object is used as the value. This method works with polymorphic relationships as well.
+In the case of a belongs_to relationship, an association key can be used to specify the model if an Active Record object is used as the value. This method works with polymorphic relationships as well.
```ruby
Post.where(author: author)
@@ -503,6 +505,20 @@ This code will generate SQL like this:
SELECT * FROM clients WHERE (clients.orders_count IN (1,3,5))
```
+### NOT, LIKE, and NOT LIKE Conditions
+
+`NOT`, `LIKE`, and `NOT LIKE` SQL queries can be built by `where.not`, `where.like`, and `where.not_like` respectively.
+
+```ruby
+Post.where.not(author: author)
+
+Author.where.like(name: 'Nari%')
+
+Developer.where.not_like(name: 'Tenderl%')
+```
+
+In other words, these sort of queries can be generated by calling `where` with no argument, then immediately chain with `not`, `like`, or `not_like` passing `where` conditions.
+
Ordering
--------
@@ -1188,7 +1204,7 @@ class Client < ActiveRecord::Base
end
```
-### Removing all scoping
+### Removing All Scoping
If we wish to remove scoping for any reason we can use the `unscoped` method. This is
especially useful if a `default_scope` is specified in the model and should not be
@@ -1220,9 +1236,7 @@ You can specify an exclamation point (`!`) on the end of the dynamic finders to
If you want to find both by name and locked, you can chain these finders together by simply typing "`and`" between the fields. For example, `Client.find_by_first_name_and_locked("Ryan", true)`.
-WARNING: Up to and including Rails 3.1, when the number of arguments passed to a dynamic finder method is lesser than the number of fields, say `Client.find_by_name_and_locked("Ryan")`, the behavior is to pass `nil` as the missing argument. This is **unintentional** and this behavior will be changed in Rails 3.2 to throw an `ArgumentError`.
-
-Find or build a new object
+Find or Build a New Object
--------------------------
It's common that you need to find a record or create it if it doesn't exist. You can do that with the `find_or_create_by` and `find_or_create_by!` methods.
diff --git a/guides/source/active_record_validations.md b/guides/source/active_record_validations.md
new file mode 100644
index 0000000000..2e2f0e4ea9
--- /dev/null
+++ b/guides/source/active_record_validations.md
@@ -0,0 +1,963 @@
+Active Record Validations
+=========================
+
+This guide teaches you how to validate the state of objects before they go into
+the database using Active Record's validations feature.
+
+After reading this guide, you will know:
+
+* How to use the built-in Active Record validation helpers.
+* How to create your own custom validation methods.
+* How to work with the error messages generated by the validation process.
+
+--------------------------------------------------------------------------------
+
+Validations Overview
+--------------------
+
+Here's an example of a very simple validation:
+
+```ruby
+class Person < ActiveRecord::Base
+ validates :name, presence: true
+end
+
+Person.create(name: "John Doe").valid? # => true
+Person.create(name: nil).valid? # => false
+```
+
+As you can see, our validation lets us know that our `Person` is not valid
+without a `name` attribute. The second `Person` will not be persisted to the
+database.
+
+Before we dig into more details, let's talk about how validations fit into the
+big picture of your application.
+
+### Why Use Validations?
+
+Validations are used to ensure that only valid data is saved into your
+database. For example, it may be important to your application to ensure that
+every user provides a valid email address and mailing address. Model-level
+validations are the best way to ensure that only valid data is saved into your
+database. They are database agnostic, cannot be bypassed by end users, and are
+convenient to test and maintain. Rails makes them easy to use, provides
+built-in helpers for common needs, and allows you to create your own validation
+methods as well.
+
+There are several other ways to validate data before it is saved into your
+database, including native database constraints, client-side validations,
+controller-level validations. Here's a summary of the pros and cons:
+
+* Database constraints and/or stored procedures make the validation mechanisms
+ database-dependent and can make testing and maintenance more difficult.
+ However, if your database is used by other applications, it may be a good
+ idea to use some constraints at the database level. Additionally,
+ database-level validations can safely handle some things (such as uniqueness
+ in heavily-used tables) that can be difficult to implement otherwise.
+* Client-side validations can be useful, but are generally unreliable if used
+ alone. If they are implemented using JavaScript, they may be bypassed if
+ JavaScript is turned off in the user's browser. However, if combined with
+ other techniques, client-side validation can be a convenient way to provide
+ users with immediate feedback as they use your site.
+* Controller-level validations can be tempting to use, but often become
+ unwieldy and difficult to test and maintain. Whenever possible, it's a good
+ idea to keep your controllers skinny, as it will make your application a
+ pleasure to work with in the long run.
+
+Choose these in certain, specific cases. It's the opinion of the Rails team
+that model-level validations are the most appropriate in most circumstances.
+
+### When Does Validation Happen?
+
+There are two kinds of Active Record objects: those that correspond to a row
+inside your database and those that do not. When you create a fresh object, for
+example using the `new` method, that object does not belong to the database
+yet. Once you call `save` upon that object it will be saved into the
+appropriate database table. Active Record uses the `new_record?` instance
+method to determine whether an object is already in the database or not.
+Consider the following simple Active Record class:
+
+```ruby
+class Person < ActiveRecord::Base
+end
+```
+
+We can see how it works by looking at some `rails console` output:
+
+```ruby
+$ rails console
+>> p = Person.new(name: "John Doe")
+=> #<Person id: nil, name: "John Doe", created_at: nil, updated_at: nil>
+>> p.new_record?
+=> true
+>> p.save
+=> true
+>> p.new_record?
+=> false
+```
+
+Creating and saving a new record will send an SQL `INSERT` operation to the
+database. Updating an existing record will send an SQL `UPDATE` operation
+instead. Validations are typically run before these commands are sent to the
+database. If any validations fail, the object will be marked as invalid and
+Active Record will not perform the `INSERT` or `UPDATE` operation. This avoids
+storing an invalid object in the database. You can choose to have specific
+validations run when an object is created, saved, or updated.
+
+CAUTION: There are many ways to change the state of an object in the database.
+Some methods will trigger validations, but some will not. This means that it's
+possible to save an object in the database in an invalid state if you aren't
+careful.
+
+The following methods trigger validations, and will save the object to the
+database only if the object is valid:
+
+* `create`
+* `create!`
+* `save`
+* `save!`
+* `update`
+* `update_attributes`
+* `update_attributes!`
+
+The bang versions (e.g. `save!`) raise an exception if the record is invalid.
+The non-bang versions don't: `save` and `update_attributes` return `false`,
+`create` and `update` just return the objects.
+
+### Skipping Validations
+
+The following methods skip validations, and will save the object to the
+database regardless of its validity. They should be used with caution.
+
+* `decrement!`
+* `decrement_counter`
+* `increment!`
+* `increment_counter`
+* `toggle!`
+* `touch`
+* `update_all`
+* `update_attribute`
+* `update_column`
+* `update_columns`
+* `update_counters`
+
+Note that `save` also has the ability to skip validations if passed `validate:
+false` as argument. This technique should be used with caution.
+
+* `save(validate: false)`
+
+### `valid?` and `invalid?`
+
+To verify whether or not an object is valid, Rails uses the `valid?` method.
+You can also use this method on your own. `valid?` triggers your validations
+and returns true if no errors were found in the object, and false otherwise.
+As you saw above:
+
+```ruby
+class Person < ActiveRecord::Base
+ validates :name, presence: true
+end
+
+Person.create(name: "John Doe").valid? # => true
+Person.create(name: nil).valid? # => false
+```
+
+After Active Record has performed validations, any errors found can be accessed
+through the `errors` instance method, which returns a collection of errors. By
+definition, an object is valid if this collection is empty after running
+validations.
+
+Note that an object instantiated with `new` will not report errors even if it's
+technically invalid, because validations are not run when using `new`.
+
+```ruby
+class Person < ActiveRecord::Base
+ validates :name, presence: true
+end
+
+>> p = Person.new
+#=> #<Person id: nil, name: nil>
+>> p.errors
+#=> {}
+
+>> p.valid?
+#=> false
+>> p.errors
+#=> {name:["can't be blank"]}
+
+>> p = Person.create
+#=> #<Person id: nil, name: nil>
+>> p.errors
+#=> {name:["can't be blank"]}
+
+>> p.save
+#=> false
+
+>> p.save!
+#=> ActiveRecord::RecordInvalid: Validation failed: Name can't be blank
+
+>> Person.create!
+#=> ActiveRecord::RecordInvalid: Validation failed: Name can't be blank
+```
+
+`invalid?` is simply the inverse of `valid?`. It triggers your validations,
+returning true if any errors were found in the object, and false otherwise.
+
+### `errors[]`
+
+To verify whether or not a particular attribute of an object is valid, you can
+use `errors[:attribute]`. It returns an array of all the errors for
+`:attribute`. If there are no errors on the specified attribute, an empty array
+is returned.
+
+This method is only useful _after_ validations have been run, because it only
+inspects the errors collection and does not trigger validations itself. It's
+different from the `ActiveRecord::Base#invalid?` method explained above because
+it doesn't verify the validity of the object as a whole. It only checks to see
+whether there are errors found on an individual attribute of the object.
+
+```ruby
+class Person < ActiveRecord::Base
+ validates :name, presence: true
+end
+
+>> Person.new.errors[:name].any? # => false
+>> Person.create.errors[:name].any? # => true
+```
+
+We'll cover validation errors in greater depth in the [Working with Validation
+Errors](#working-with-validation-errors) section. For now, let's turn to the
+built-in validation helpers that Rails provides by default.
+
+Validation Helpers
+------------------
+
+Active Record offers many pre-defined validation helpers that you can use
+directly inside your class definitions. These helpers provide common validation
+rules. Every time a validation fails, an error message is added to the object's
+`errors` collection, and this message is associated with the attribute being
+validated.
+
+Each helper accepts an arbitrary number of attribute names, so with a single
+line of code you can add the same kind of validation to several attributes.
+
+All of them accept the `:on` and `:message` options, which define when the
+validation should be run and what message should be added to the `errors`
+collection if it fails, respectively. The `:on` option takes one of the values
+`:save` (the default), `:create` or `:update`. There is a default error
+message for each one of the validation helpers. These messages are used when
+the `:message` option isn't specified. Let's take a look at each one of the
+available helpers.
+
+### `acceptance`
+
+This method validates that a checkbox on the user interface was checked when a
+form was submitted. This is typically used when the user needs to agree to your
+application's terms of service, confirm reading some text, or any similar
+concept. This validation is very specific to web applications and this
+'acceptance' does not need to be recorded anywhere in your database (if you
+don't have a field for it, the helper will just create a virtual attribute).
+
+```ruby
+class Person < ActiveRecord::Base
+ validates :terms_of_service, acceptance: true
+end
+```
+
+The default error message for this helper is _"must be accepted"_.
+
+It can receive an `:accept` option, which determines the value that will be
+considered acceptance. It defaults to "1" and can be easily changed.
+
+```ruby
+class Person < ActiveRecord::Base
+ validates :terms_of_service, acceptance: { accept: 'yes' }
+end
+```
+
+### `validates_associated`
+
+You should use this helper when your model has associations with other models
+and they also need to be validated. When you try to save your object, `valid?`
+will be called upon each one of the associated objects.
+
+```ruby
+class Library < ActiveRecord::Base
+ has_many :books
+ validates_associated :books
+end
+```
+
+This validation will work with all of the association types.
+
+CAUTION: Don't use `validates_associated` on both ends of your associations.
+They would call each other in an infinite loop.
+
+The default error message for `validates_associated` is _"is invalid"_. Note
+that each associated object will contain its own `errors` collection; errors do
+not bubble up to the calling model.
+
+### `confirmation`
+
+You should use this helper when you have two text fields that should receive
+exactly the same content. For example, you may want to confirm an email address
+or a password. This validation creates a virtual attribute whose name is the
+name of the field that has to be confirmed with "_confirmation" appended.
+
+```ruby
+class Person < ActiveRecord::Base
+ validates :email, confirmation: true
+end
+```
+
+In your view template you could use something like
+
+```erb
+<%= text_field :person, :email %>
+<%= text_field :person, :email_confirmation %>
+```
+
+This check is performed only if `email_confirmation` is not `nil`. To require
+confirmation, make sure to add a presence check for the confirmation attribute
+(we'll take a look at `presence` later on this guide):
+
+```ruby
+class Person < ActiveRecord::Base
+ validates :email, confirmation: true
+ validates :email_confirmation, presence: true
+end
+```
+
+The default error message for this helper is _"doesn't match confirmation"_.
+
+### `exclusion`
+
+This helper validates that the attributes' values are not included in a given
+set. In fact, this set can be any enumerable object.
+
+```ruby
+class Account < ActiveRecord::Base
+ validates :subdomain, exclusion: { in: %w(www us ca jp),
+ message: "Subdomain %{value} is reserved." }
+end
+```
+
+The `exclusion` helper has an option `:in` that receives the set of values that
+will not be accepted for the validated attributes. The `:in` option has an
+alias called `:within` that you can use for the same purpose, if you'd like to.
+This example uses the `:message` option to show how you can include the
+attribute's value.
+
+The default error message is _"is reserved"_.
+
+### `format`
+
+This helper validates the attributes' values by testing whether they match a
+given regular expression, which is specified using the `:with` option.
+
+```ruby
+class Product < ActiveRecord::Base
+ validates :legacy_code, format: { with: /\A[a-zA-Z]+\z/,
+ message: "Only letters allowed" }
+end
+```
+
+The default error message is _"is invalid"_.
+
+### `inclusion`
+
+This helper validates that the attributes' values are included in a given set.
+In fact, this set can be any enumerable object.
+
+```ruby
+class Coffee < ActiveRecord::Base
+ validates :size, inclusion: { in: %w(small medium large),
+ message: "%{value} is not a valid size" }
+end
+```
+
+The `inclusion` helper has an option `:in` that receives the set of values that
+will be accepted. The `:in` option has an alias called `:within` that you can
+use for the same purpose, if you'd like to. The previous example uses the
+`:message` option to show how you can include the attribute's value.
+
+The default error message for this helper is _"is not included in the list"_.
+
+### `length`
+
+This helper validates the length of the attributes' values. It provides a
+variety of options, so you can specify length constraints in different ways:
+
+```ruby
+class Person < ActiveRecord::Base
+ validates :name, length: { minimum: 2 }
+ validates :bio, length: { maximum: 500 }
+ validates :password, length: { in: 6..20 }
+ validates :registration_number, length: { is: 6 }
+end
+```
+
+The possible length constraint options are:
+
+* `:minimum` - The attribute cannot have less than the specified length.
+* `:maximum` - The attribute cannot have more than the specified length.
+* `:in` (or `:within`) - The attribute length must be included in a given
+ interval. The value for this option must be a range.
+* `:is` - The attribute length must be equal to the given value.
+
+The default error messages depend on the type of length validation being
+performed. You can personalize these messages using the `:wrong_length`,
+`:too_long`, and `:too_short` options and `%{count}` as a placeholder for the
+number corresponding to the length constraint being used. You can still use the
+`:message` option to specify an error message.
+
+```ruby
+class Person < ActiveRecord::Base
+ validates :bio, length: { maximum: 1000,
+ too_long: "%{count} characters is the maximum allowed" }
+end
+```
+
+This helper counts characters by default, but you can split the value in a
+different way using the `:tokenizer` option:
+
+```ruby
+class Essay < ActiveRecord::Base
+ validates :content, length: {
+ minimum: 300,
+ maximum: 400,
+ tokenizer: lambda { |str| str.scan(/\w+/) },
+ too_short: "must have at least %{count} words",
+ too_long: "must have at most %{count} words"
+ }
+end
+```
+
+Note that the default error messages are plural (e.g., "is too short (minimum
+is %{count} characters)"). For this reason, when `:minimum` is 1 you should
+provide a personalized message or use `validates_presence_of` instead. When
+`:in` or `:within` have a lower limit of 1, you should either provide a
+personalized message or call `presence` prior to `length`.
+
+The `size` helper is an alias for `length`.
+
+### `numericality`
+
+This helper validates that your attributes have only numeric values. By
+default, it will match an optional sign followed by an integral or floating
+point number. To specify that only integral numbers are allowed set
+`:only_integer` to true.
+
+If you set `:only_integer` to `true`, then it will use the
+
+```ruby
+/\A[+-]?\d+\Z/
+```
+
+regular expression to validate the attribute's value. Otherwise, it will try to
+convert the value to a number using `Float`.
+
+WARNING. Note that the regular expression above allows a trailing newline
+character.
+
+```ruby
+class Player < ActiveRecord::Base
+ validates :points, numericality: true
+ validates :games_played, numericality: { only_integer: true }
+end
+```
+
+Besides `:only_integer`, this helper also accepts the following options to add
+constraints to acceptable values:
+
+* `:greater_than` - Specifies the value must be greater than the supplied
+ value. The default error message for this option is _"must be greater than
+ %{count}"_.
+* `:greater_than_or_equal_to` - Specifies the value must be greater than or
+ equal to the supplied value. The default error message for this option is
+ _"must be greater than or equal to %{count}"_.
+* `:equal_to` - Specifies the value must be equal to the supplied value. The
+ default error message for this option is _"must be equal to %{count}"_.
+* `:less_than` - Specifies the value must be less than the supplied value. The
+ default error message for this option is _"must be less than %{count}"_.
+* `:less_than_or_equal_to` - Specifies the value must be less than or equal the
+ supplied value. The default error message for this option is _"must be less
+ than or equal to %{count}"_.
+* `:odd` - Specifies the value must be an odd number if set to true. The
+ default error message for this option is _"must be odd"_.
+* `:even` - Specifies the value must be an even number if set to true. The
+ default error message for this option is _"must be even"_.
+
+The default error message is _"is not a number"_.
+
+### `presence`
+
+This helper validates that the specified attributes are not empty. It uses the
+`blank?` method to check if the value is either `nil` or a blank string, that
+is, a string that is either empty or consists of whitespace.
+
+```ruby
+class Person < ActiveRecord::Base
+ validates :name, :login, :email, presence: true
+end
+```
+
+If you want to be sure that an association is present, you'll need to test
+whether the foreign key used to map the association is present, and not the
+associated object itself.
+
+```ruby
+class LineItem < ActiveRecord::Base
+ belongs_to :order
+ validates :order, presence: true
+end
+```
+
+You should also be sure to have a proper `:inverse_of` as well:
+
+```ruby
+class Order < ActiveRecord::Base
+ has_many :line_items, inverse_of: :order
+end
+```
+
+If you validate the presence of an object associated via a `has_one` or
+`has_many` relationship, it will check that the object is neither `blank?` nor
+`marked_for_destruction?`.
+
+Since `false.blank?` is true, if you want to validate the presence of a boolean
+field you should use `validates :field_name, inclusion: { in: [true, false] }`.
+
+The default error message is _"can't be empty"_.
+
+### `uniqueness`
+
+This helper validates that the attribute's value is unique right before the
+object gets saved. It does not create a uniqueness constraint in the database,
+so it may happen that two different database connections create two records
+with the same value for a column that you intend to be unique. To avoid that,
+you must create a unique index in your database.
+
+```ruby
+class Account < ActiveRecord::Base
+ validates :email, uniqueness: true
+end
+```
+
+The validation happens by performing an SQL query into the model's table,
+searching for an existing record with the same value in that attribute.
+
+There is a `:scope` option that you can use to specify other attributes that
+are used to limit the uniqueness check:
+
+```ruby
+class Holiday < ActiveRecord::Base
+ validates :name, uniqueness: { scope: :year,
+ message: "should happen once per year" }
+end
+```
+
+There is also a `:case_sensitive` option that you can use to define whether the
+uniqueness constraint will be case sensitive or not. This option defaults to
+true.
+
+```ruby
+class Person < ActiveRecord::Base
+ validates :name, uniqueness: { case_sensitive: false }
+end
+```
+
+WARNING. Note that some databases are configured to perform case-insensitive
+searches anyway.
+
+The default error message is _"has already been taken"_.
+
+### `validates_with`
+
+This helper passes the record to a separate class for validation.
+
+```ruby
+class Person < ActiveRecord::Base
+ validates_with GoodnessValidator
+end
+
+class GoodnessValidator < ActiveModel::Validator
+ def validate(record)
+ if record.first_name == "Evil"
+ record.errors[:base] << "This person is evil"
+ end
+ end
+end
+```
+
+NOTE: Errors added to `record.errors[:base]` relate to the state of the record
+as a whole, and not to a specific attribute.
+
+The `validates_with` helper takes a class, or a list of classes to use for
+validation. There is no default error message for `validates_with`. You must
+manually add errors to the record's errors collection in the validator class.
+
+To implement the validate method, you must have a `record` parameter defined,
+which is the record to be validated.
+
+Like all other validations, `validates_with` takes the `:if`, `:unless` and
+`:on` options. If you pass any other options, it will send those options to the
+validator class as `options`:
+
+```ruby
+class Person < ActiveRecord::Base
+ validates_with GoodnessValidator, fields: [:first_name, :last_name]
+end
+
+class GoodnessValidator < ActiveModel::Validator
+ def validate(record)
+ if options[:fields].any?{|field| record.send(field) == "Evil" }
+ record.errors[:base] << "This person is evil"
+ end
+ end
+end
+```
+
+### `validates_each`
+
+This helper validates attributes against a block. It doesn't have a predefined
+validation function. You should create one using a block, and every attribute
+passed to `validates_each` will be tested against it. In the following example,
+we don't want names and surnames to begin with lower case.
+
+```ruby
+class Person < ActiveRecord::Base
+ validates_each :name, :surname do |record, attr, value|
+ record.errors.add(attr, 'must start with upper case') if value =~ /\A[a-z]/
+ end
+end
+```
+
+The block receives the record, the attribute's name and the attribute's value.
+You can do anything you like to check for valid data within the block. If your
+validation fails, you should add an error message to the model, therefore
+making it invalid.
+
+Common Validation Options
+-------------------------
+
+These are common validation options:
+
+### `:allow_nil`
+
+The `:allow_nil` option skips the validation when the value being validated is
+`nil`.
+
+```ruby
+class Coffee < ActiveRecord::Base
+ validates :size, inclusion: { in: %w(small medium large),
+ message: "%{value} is not a valid size" }, allow_nil: true
+end
+```
+
+TIP: `:allow_nil` is ignored by the presence validator.
+
+### `:allow_blank`
+
+The `:allow_blank` option is similar to the `:allow_nil` option. This option
+will let validation pass if the attribute's value is `blank?`, like `nil` or an
+empty string for example.
+
+```ruby
+class Topic < ActiveRecord::Base
+ validates :title, length: { is: 5 }, allow_blank: true
+end
+
+Topic.create("title" => "").valid? # => true
+Topic.create("title" => nil).valid? # => true
+```
+
+TIP: `:allow_blank` is ignored by the presence validator.
+
+### `:message`
+
+As you've already seen, the `:message` option lets you specify the message that
+will be added to the `errors` collection when validation fails. When this
+option is not used, Active Record will use the respective default error message
+for each validation helper.
+
+### `:on`
+
+The `:on` option lets you specify when the validation should happen. The
+default behavior for all the built-in validation helpers is to be run on save
+(both when you're creating a new record and when you're updating it). If you
+want to change it, you can use `on: :create` to run the validation only when a
+new record is created or `on: :update` to run the validation only when a record
+is updated.
+
+```ruby
+class Person < ActiveRecord::Base
+ # it will be possible to update email with a duplicated value
+ validates :email, uniqueness: true, on: :create
+
+ # it will be possible to create the record with a non-numerical age
+ validates :age, numericality: true, on: :update
+
+ # the default (validates on both create and update)
+ validates :name, presence: true, on: :save
+end
+```
+
+Strict Validations
+------------------
+
+You can also specify validations to be strict and raise
+`ActiveModel::StrictValidationFailed` when the object is invalid.
+
+```ruby
+class Person < ActiveRecord::Base
+ validates :name, presence: { strict: true }
+end
+
+Person.new.valid? # => ActiveModel::StrictValidationFailed: Name can't be blank
+```
+
+There is also an ability to pass custom exception to `:strict` option
+
+```ruby
+class Person < ActiveRecord::Base
+ validates :token, presence: true, uniqueness: true, strict: TokenGenerationException
+end
+
+Person.new.valid? # => TokenGenerationException: Token can't be blank
+```
+
+Conditional Validation
+----------------------
+
+Sometimes it will make sense to validate an object only when a given predicate
+is satisfied. You can do that by using the `:if` and `:unless` options, which
+can take a symbol, a string, a `Proc` or an `Array`. You may use the `:if`
+option when you want to specify when the validation **should** happen. If you
+want to specify when the validation **should not** happen, then you may use the
+`:unless` option.
+
+### Using a Symbol with `:if` and `:unless`
+
+You can associate the `:if` and `:unless` options with a symbol corresponding
+to the name of a method that will get called right before validation happens.
+This is the most commonly used option.
+
+```ruby
+class Order < ActiveRecord::Base
+ validates :card_number, presence: true, if: :paid_with_card?
+
+ def paid_with_card?
+ payment_type == "card"
+ end
+end
+```
+
+### Using a String with `:if` and `:unless`
+
+You can also use a string that will be evaluated using `eval` and needs to
+contain valid Ruby code. You should use this option only when the string
+represents a really short condition.
+
+```ruby
+class Person < ActiveRecord::Base
+ validates :surname, presence: true, if: "name.nil?"
+end
+```
+
+### Using a Proc with `:if` and `:unless`
+
+Finally, it's possible to associate `:if` and `:unless` with a `Proc` object
+which will be called. Using a `Proc` object gives you the ability to write an
+inline condition instead of a separate method. This option is best suited for
+one-liners.
+
+```ruby
+class Account < ActiveRecord::Base
+ validates :password, confirmation: true,
+ unless: Proc.new { |a| a.password.blank? }
+end
+```
+
+### Grouping Conditional validations
+
+Sometimes it is useful to have multiple validations use one condition, it can
+be easily achieved using `with_options`.
+
+```ruby
+class User < ActiveRecord::Base
+ with_options if: :is_admin? do |admin|
+ admin.validates :password, length: { minimum: 10 }
+ admin.validates :email, presence: true
+ end
+end
+```
+
+All validations inside of `with_options` block will have automatically passed
+the condition `if: :is_admin?`
+
+### Combining Validation Conditions
+
+On the other hand, when multiple conditions define whether or not a validation
+should happen, an `Array` can be used. Moreover, you can apply both `:if` and
+`:unless` to the same validation.
+
+```ruby
+class Computer < ActiveRecord::Base
+ validates :mouse, presence: true,
+ if: ["market.retail?", :desktop?]
+ unless: Proc.new { |c| c.trackpad.present? }
+end
+```
+
+The validation only runs when all the `:if` conditions and none of the
+`:unless` conditions are evaluated to `true`.
+
+Performing Custom Validations
+-----------------------------
+
+When the built-in validation helpers are not enough for your needs, you can
+write your own validators or validation methods as you prefer.
+
+### Custom Validators
+
+Custom validators are classes that extend `ActiveModel::Validator`. These
+classes must implement a `validate` method which takes a record as an argument
+and performs the validation on it. The custom validator is called using the
+`validates_with` method.
+
+```ruby
+class MyValidator < ActiveModel::Validator
+ def validate(record)
+ unless record.name.starts_with? 'X'
+ record.errors[:name] << 'Need a name starting with X please!'
+ end
+ end
+end
+
+class Person
+ include ActiveModel::Validations
+ validates_with MyValidator
+end
+```
+
+The easiest way to add custom validators for validating individual attributes
+is with the convenient `ActiveModel::EachValidator`. In this case, the custom
+validator class must implement a `validate_each` method which takes three
+arguments: record, attribute and value which correspond to the instance, the
+attribute to be validated and the value of the attribute in the passed
+instance.
+
+```ruby
+class EmailValidator < ActiveModel::EachValidator
+ def validate_each(record, attribute, value)
+ unless value =~ /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i
+ record.errors[attribute] << (options[:message] || "is not an email")
+ end
+ end
+end
+
+class Person < ActiveRecord::Base
+ validates :email, presence: true, email: true
+end
+```
+
+As shown in the example, you can also combine standard validations with your
+own custom validators.
+
+### 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 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.
+
+```ruby
+class Invoice < ActiveRecord::Base
+ validate :expiration_date_cannot_be_in_the_past,
+ :discount_cannot_be_greater_than_total_value
+
+ def expiration_date_cannot_be_in_the_past
+ if expiration_date.present? && expiration_date < Date.today
+ errors.add(:expiration_date, "can't be in the past")
+ end
+ end
+
+ def discount_cannot_be_greater_than_total_value
+ if discount > total_value
+ errors.add(:discount, "can't be greater than total value")
+ end
+ end
+end
+```
+
+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
+```
+
+Displaying Validation Errors in Views
+-------------------------------------
+
+Once you've created a model and added validations, if that model is created via
+a web form, you probably want to display an error message when one of the
+validations fail.
+
+Because every application handles this kind of thing differently, Rails does
+not include any view helpers to help you generate these messages directly.
+However, due to the rich number of methods Rails gives you to interact with
+validations in general, it's fairly easy to build your own. In addition, when
+generating a scaffold, Rails will put some ERB into the `_form.html.erb` that
+it generates that displays the full list of errors on that model.
+
+Assuming we have a model that's been saved in an instance variable named
+`@post`, it looks like this:
+
+```ruby
+<% if @post.errors.any? %>
+ <div id="error_explanation">
+ <h2><%= pluralize(@post.errors.count, "error") %> prohibited this post from being saved:</h2>
+
+ <ul>
+ <% @post.errors.full_messages.each do |msg| %>
+ <li><%= msg %></li>
+ <% end %>
+ </ul>
+ </div>
+<% end %>
+```
+
+Furthermore, if you use the Rails form helpers to generate your forms, when
+a validation error occurs on a field, it will generate an extra `<div>` around
+the entry.
+
+```
+<div class="field_with_errors">
+ <input id="post_title" name="post[title]" size="30" type="text" value="">
+</div>
+```
+
+You can then style this div however you'd like. The default scaffold that
+Rails generates, for example, adds this CSS rule:
+
+```
+.field_with_errors {
+ padding: 2px;
+ background-color: red;
+ display: table;
+}
+```
+
+This means that any field with an error ends up with a 2 pixel red border.
diff --git a/guides/source/active_record_validations_callbacks.md b/guides/source/active_record_validations_callbacks.md
deleted file mode 100644
index 0f4140b650..0000000000
--- a/guides/source/active_record_validations_callbacks.md
+++ /dev/null
@@ -1,1372 +0,0 @@
-Active Record Validations and Callbacks
-=======================================
-
-This guide teaches you how to hook into the life cycle of your Active Record objects. You will learn how to validate the state of objects before they go into the database, and how to perform custom operations at certain points in the object life cycle.
-
-After reading this guide and trying out the presented concepts, we hope that you'll be able to:
-
-* Understand the life cycle of Active Record objects
-* Use the built-in Active Record validation helpers
-* Create your own custom validation methods
-* Work with the error messages generated by the validation process
-* Create callback methods that respond to events in the object life cycle
-* Create special classes that encapsulate common behavior for your callbacks
-* Create Observers that respond to life cycle events outside of the original class
-
---------------------------------------------------------------------------------
-
-The Object Life Cycle
----------------------
-
-During the normal operation of a Rails application, objects may be created, updated, and destroyed. Active Record provides hooks into this <em>object life cycle</em> so that you can control your application and its data.
-
-Validations allow you to ensure that only valid data is stored in your database. Callbacks and observers allow you to trigger logic before or after an alteration of an object's state.
-
-Validations Overview
---------------------
-
-Before you dive into the detail of validations in Rails, you should understand a bit about how validations fit into the big picture.
-
-### Why Use Validations?
-
-Validations are used to ensure that only valid data is saved into your database. For example, it may be important to your application to ensure that every user provides a valid email address and mailing address.
-
-There are several ways to validate data before it is saved into your database, including native database constraints, client-side validations, controller-level validations, and model-level validations:
-
-* Database constraints and/or stored procedures make the validation mechanisms database-dependent and can make testing and maintenance more difficult. However, if your database is used by other applications, it may be a good idea to use some constraints at the database level. Additionally, database-level validations can safely handle some things (such as uniqueness in heavily-used tables) that can be difficult to implement otherwise.
-* Client-side validations can be useful, but are generally unreliable if used alone. If they are implemented using JavaScript, they may be bypassed if JavaScript is turned off in the user's browser. However, if combined with other techniques, client-side validation can be a convenient way to provide users with immediate feedback as they use your site.
-* Controller-level validations can be tempting to use, but often become unwieldy and difficult to test and maintain. Whenever possible, it's a good idea to [keep your controllers skinny](http://weblog.jamisbuck.org/2006/10/18/skinny-controller-fat-model), as it will make your application a pleasure to work with in the long run.
-* Model-level validations are the best way to ensure that only valid data is saved into your database. They are database agnostic, cannot be bypassed by end users, and are convenient to test and maintain. Rails makes them easy to use, provides built-in helpers for common needs, and allows you to create your own validation methods as well.
-
-### When Does Validation Happen?
-
-There are two kinds of Active Record objects: those that correspond to a row inside your database and those that do not. When you create a fresh object, for example using the `new` method, that object does not belong to the database yet. Once you call `save` upon that object it will be saved into the appropriate database table. Active Record uses the `new_record?` instance method to determine whether an object is already in the database or not. Consider the following simple Active Record class:
-
-```ruby
-class Person < ActiveRecord::Base
-end
-```
-
-We can see how it works by looking at some `rails console` output:
-
-```ruby
-$ rails console
->> p = Person.new(name: "John Doe")
-=> #<Person id: nil, name: "John Doe", created_at: nil, updated_at: nil>
->> p.new_record?
-=> true
->> p.save
-=> true
->> p.new_record?
-=> false
-```
-
-TIP: All lines starting with a dollar sign `$` are intended to be run on the command line.
-
-Creating and saving a new record will send an SQL `INSERT` operation to the database. Updating an existing record will send an SQL `UPDATE` operation instead. Validations are typically run before these commands are sent to the database. If any validations fail, the object will be marked as invalid and Active Record will not perform the `INSERT` or `UPDATE` operation. This helps to avoid storing an invalid object in the database. You can choose to have specific validations run when an object is created, saved, or updated.
-
-CAUTION: There are many ways to change the state of an object in the database. Some methods will trigger validations, but some will not. This means that it's possible to save an object in the database in an invalid state if you aren't careful.
-
-The following methods trigger validations, and will save the object to the database only if the object is valid:
-
-* `create`
-* `create!`
-* `save`
-* `save!`
-* `update`
-* `update_attributes`
-* `update_attributes!`
-
-The bang versions (e.g. `save!`) raise an exception if the record is invalid. The non-bang versions don't: `save` and `update_attributes` return `false`, `create` and `update` just return the objects.
-
-### Skipping Validations
-
-The following methods skip validations, and will save the object to the database regardless of its validity. They should be used with caution.
-
-* `decrement!`
-* `decrement_counter`
-* `increment!`
-* `increment_counter`
-* `toggle!`
-* `touch`
-* `update_all`
-* `update_attribute`
-* `update_column`
-* `update_columns`
-* `update_counters`
-
-Note that `save` also has the ability to skip validations if passed `validate: false` as argument. This technique should be used with caution.
-
-* `save(validate: false)`
-
-### `valid?` and `invalid?`
-
-To verify whether or not an object is valid, Rails uses the `valid?` method. You can also use this method on your own. `valid?` triggers your validations and returns true if no errors were found in the object, and false otherwise.
-
-```ruby
-class Person < ActiveRecord::Base
- validates :name, presence: true
-end
-
-Person.create(name: "John Doe").valid? # => true
-Person.create(name: nil).valid? # => false
-```
-
-After Active Record has performed validations, any errors found can be accessed through the `errors` instance method, which returns a collection of errors. By definition, an object is valid if this collection is empty after running validations.
-
-Note that an object instantiated with `new` will not report errors even if it's technically invalid, because validations are not run when using `new`.
-
-```ruby
-class Person < ActiveRecord::Base
- validates :name, presence: true
-end
-
->> p = Person.new
-#=> #<Person id: nil, name: nil>
->> p.errors
-#=> {}
-
->> p.valid?
-#=> false
->> p.errors
-#=> {name:["can't be blank"]}
-
->> p = Person.create
-#=> #<Person id: nil, name: nil>
->> p.errors
-#=> {name:["can't be blank"]}
-
->> p.save
-#=> false
-
->> p.save!
-#=> ActiveRecord::RecordInvalid: Validation failed: Name can't be blank
-
->> Person.create!
-#=> ActiveRecord::RecordInvalid: Validation failed: Name can't be blank
-```
-
-`invalid?` is simply the inverse of `valid?`. It triggers your validations, returning true if any errors were found in the object, and false otherwise.
-
-### `errors[]`
-
-To verify whether or not a particular attribute of an object is valid, you can use `errors[:attribute]`. It returns an array of all the errors for `:attribute`. If there are no errors on the specified attribute, an empty array is returned.
-
-This method is only useful _after_ validations have been run, because it only inspects the errors collection and does not trigger validations itself. It's different from the `ActiveRecord::Base#invalid?` method explained above because it doesn't verify the validity of the object as a whole. It only checks to see whether there are errors found on an individual attribute of the object.
-
-```ruby
-class Person < ActiveRecord::Base
- validates :name, presence: true
-end
-
->> Person.new.errors[:name].any? # => false
->> Person.create.errors[:name].any? # => true
-```
-
-We'll cover validation errors in greater depth in the [Working with Validation Errors](#working-with-validation-errors) section. For now, let's turn to the built-in validation helpers that Rails provides by default.
-
-Validation Helpers
-------------------
-
-Active Record offers many pre-defined validation helpers that you can use directly inside your class definitions. These helpers provide common validation rules. Every time a validation fails, an error message is added to the object's `errors` collection, and this message is associated with the attribute being validated.
-
-Each helper accepts an arbitrary number of attribute names, so with a single line of code you can add the same kind of validation to several attributes.
-
-All of them accept the `:on` and `:message` options, which define when the validation should be run and what message should be added to the `errors` collection if it fails, respectively. The `:on` option takes one of the values `:save` (the default), `:create` or `:update`. There is a default error message for each one of the validation helpers. These messages are used when the `:message` option isn't specified. Let's take a look at each one of the available helpers.
-
-### `acceptance`
-
-Validates that a checkbox on the user interface was checked when a form was submitted. This is typically used when the user needs to agree to your application's terms of service, confirm reading some text, or any similar concept. This validation is very specific to web applications and this 'acceptance' does not need to be recorded anywhere in your database (if you don't have a field for it, the helper will just create a virtual attribute).
-
-```ruby
-class Person < ActiveRecord::Base
- validates :terms_of_service, acceptance: true
-end
-```
-
-The default error message for this helper is "_must be accepted_".
-
-It can receive an `:accept` option, which determines the value that will be considered acceptance. It defaults to "1" and can be easily changed.
-
-```ruby
-class Person < ActiveRecord::Base
- validates :terms_of_service, acceptance: { accept: 'yes' }
-end
-```
-
-### `validates_associated`
-
-You should use this helper when your model has associations with other models and they also need to be validated. When you try to save your object, `valid?` will be called upon each one of the associated objects.
-
-```ruby
-class Library < ActiveRecord::Base
- has_many :books
- validates_associated :books
-end
-```
-
-This validation will work with all of the association types.
-
-CAUTION: Don't use `validates_associated` on both ends of your associations. They would call each other in an infinite loop.
-
-The default error message for `validates_associated` is "_is invalid_". Note that each associated object will contain its own `errors` collection; errors do not bubble up to the calling model.
-
-### `confirmation`
-
-You should use this helper when you have two text fields that should receive exactly the same content. For example, you may want to confirm an email address or a password. This validation creates a virtual attribute whose name is the name of the field that has to be confirmed with "_confirmation" appended.
-
-```ruby
-class Person < ActiveRecord::Base
- validates :email, confirmation: true
-end
-```
-
-In your view template you could use something like
-
-```erb
-<%= text_field :person, :email %>
-<%= text_field :person, :email_confirmation %>
-```
-
-This check is performed only if `email_confirmation` is not `nil`. To require confirmation, make sure to add a presence check for the confirmation attribute (we'll take a look at `presence` later on this guide):
-
-```ruby
-class Person < ActiveRecord::Base
- validates :email, confirmation: true
- validates :email_confirmation, presence: true
-end
-```
-
-The default error message for this helper is "_doesn't match confirmation_".
-
-### `exclusion`
-
-This helper validates that the attributes' values are not included in a given set. In fact, this set can be any enumerable object.
-
-```ruby
-class Account < ActiveRecord::Base
- validates :subdomain, exclusion: { in: %w(www us ca jp),
- message: "Subdomain %{value} is reserved." }
-end
-```
-
-The `exclusion` helper has an option `:in` that receives the set of values that will not be accepted for the validated attributes. The `:in` option has an alias called `:within` that you can use for the same purpose, if you'd like to. This example uses the `:message` option to show how you can include the attribute's value.
-
-The default error message is "_is reserved_".
-
-### `format`
-
-This helper validates the attributes' values by testing whether they match a given regular expression, which is specified using the `:with` option.
-
-```ruby
-class Product < ActiveRecord::Base
- validates :legacy_code, format: { with: /\A[a-zA-Z]+\z/,
- message: "Only letters allowed" }
-end
-```
-
-The default error message is "_is invalid_".
-
-### `inclusion`
-
-This helper validates that the attributes' values are included in a given set. In fact, this set can be any enumerable object.
-
-```ruby
-class Coffee < ActiveRecord::Base
- validates :size, inclusion: { in: %w(small medium large),
- message: "%{value} is not a valid size" }
-end
-```
-
-The `inclusion` helper has an option `:in` that receives the set of values that will be accepted. The `:in` option has an alias called `:within` that you can use for the same purpose, if you'd like to. The previous example uses the `:message` option to show how you can include the attribute's value.
-
-The default error message for this helper is "_is not included in the list_".
-
-### `length`
-
-This helper validates the length of the attributes' values. It provides a variety of options, so you can specify length constraints in different ways:
-
-```ruby
-class Person < ActiveRecord::Base
- validates :name, length: { minimum: 2 }
- validates :bio, length: { maximum: 500 }
- validates :password, length: { in: 6..20 }
- validates :registration_number, length: { is: 6 }
-end
-```
-
-The possible length constraint options are:
-
-* `:minimum` - The attribute cannot have less than the specified length.
-* `:maximum` - The attribute cannot have more than the specified length.
-* `:in` (or `:within`) - The attribute length must be included in a given interval. The value for this option must be a range.
-* `:is` - The attribute length must be equal to the given value.
-
-The default error messages depend on the type of length validation being performed. You can personalize these messages using the `:wrong_length`, `:too_long`, and `:too_short` options and `%{count}` as a placeholder for the number corresponding to the length constraint being used. You can still use the `:message` option to specify an error message.
-
-```ruby
-class Person < ActiveRecord::Base
- validates :bio, length: { maximum: 1000,
- too_long: "%{count} characters is the maximum allowed" }
-end
-```
-
-This helper counts characters by default, but you can split the value in a different way using the `:tokenizer` option:
-
-```ruby
-class Essay < ActiveRecord::Base
- validates :content, length: {
- minimum: 300,
- maximum: 400,
- tokenizer: lambda { |str| str.scan(/\w+/) },
- too_short: "must have at least %{count} words",
- too_long: "must have at most %{count} words"
- }
-end
-```
-
-Note that the default error messages are plural (e.g., "is too short (minimum is %{count} characters)"). For this reason, when `:minimum` is 1 you should provide a personalized message or use `validates_presence_of` instead. When `:in` or `:within` have a lower limit of 1, you should either provide a personalized message or call `presence` prior to `length`.
-
-The `size` helper is an alias for `length`.
-
-### `numericality`
-
-This helper validates that your attributes have only numeric values. By default, it will match an optional sign followed by an integral or floating point number. To specify that only integral numbers are allowed set `:only_integer` to true.
-
-If you set `:only_integer` to `true`, then it will use the
-
-```ruby
-/\A[+-]?\d+\Z/
-```
-
-regular expression to validate the attribute's value. Otherwise, it will try to convert the value to a number using `Float`.
-
-WARNING. Note that the regular expression above allows a trailing newline character.
-
-```ruby
-class Player < ActiveRecord::Base
- validates :points, numericality: true
- validates :games_played, numericality: { only_integer: true }
-end
-```
-
-Besides `:only_integer`, this helper also accepts the following options to add constraints to acceptable values:
-
-* `:greater_than` - Specifies the value must be greater than the supplied value. The default error message for this option is "_must be greater than %{count}_".
-* `:greater_than_or_equal_to` - Specifies the value must be greater than or equal to the supplied value. The default error message for this option is "_must be greater than or equal to %{count}_".
-* `:equal_to` - Specifies the value must be equal to the supplied value. The default error message for this option is "_must be equal to %{count}_".
-* `:less_than` - Specifies the value must be less than the supplied value. The default error message for this option is "_must be less than %{count}_".
-* `:less_than_or_equal_to` - Specifies the value must be less than or equal the supplied value. The default error message for this option is "_must be less than or equal to %{count}_".
-* `:odd` - Specifies the value must be an odd number if set to true. The default error message for this option is "_must be odd_".
-* `:even` - Specifies the value must be an even number if set to true. The default error message for this option is "_must be even_".
-
-The default error message is "_is not a number_".
-
-### `presence`
-
-This helper validates that the specified attributes are not empty. It uses the `blank?` method to check if the value is either `nil` or a blank string, that is, a string that is either empty or consists of whitespace.
-
-```ruby
-class Person < ActiveRecord::Base
- validates :name, :login, :email, presence: true
-end
-```
-
-If you want to be sure that an association is present, you'll need to test whether the foreign key used to map the association is present, and not the associated object itself.
-
-```ruby
-class LineItem < ActiveRecord::Base
- belongs_to :order
- validates :order_id, presence: true
-end
-```
-
-If you validate the presence of an object associated via a `has_one` or `has_many` relationship, it will check that the object is neither `blank?` nor `marked_for_destruction?`.
-
-Since `false.blank?` is true, if you want to validate the presence of a boolean field you should use `validates :field_name, inclusion: { in: [true, false] }`.
-
-The default error message is "_can't be empty_".
-
-### `uniqueness`
-
-This helper validates that the attribute's value is unique right before the object gets saved. It does not create a uniqueness constraint in the database, so it may happen that two different database connections create two records with the same value for a column that you intend to be unique. To avoid that, you must create a unique index in your database.
-
-```ruby
-class Account < ActiveRecord::Base
- validates :email, uniqueness: true
-end
-```
-
-The validation happens by performing an SQL query into the model's table, searching for an existing record with the same value in that attribute.
-
-There is a `:scope` option that you can use to specify other attributes that are used to limit the uniqueness check:
-
-```ruby
-class Holiday < ActiveRecord::Base
- validates :name, uniqueness: { scope: :year,
- message: "should happen once per year" }
-end
-```
-
-There is also a `:case_sensitive` option that you can use to define whether the uniqueness constraint will be case sensitive or not. This option defaults to true.
-
-```ruby
-class Person < ActiveRecord::Base
- validates :name, uniqueness: { case_sensitive: false }
-end
-```
-
-WARNING. Note that some databases are configured to perform case-insensitive searches anyway.
-
-The default error message is "_has already been taken_".
-
-### `validates_with`
-
-This helper passes the record to a separate class for validation.
-
-```ruby
-class Person < ActiveRecord::Base
- validates_with GoodnessValidator
-end
-
-class GoodnessValidator < ActiveModel::Validator
- def validate(record)
- if record.first_name == "Evil"
- record.errors[:base] << "This person is evil"
- end
- end
-end
-```
-
-NOTE: Errors added to `record.errors[:base]` relate to the state of the record as a whole, and not to a specific attribute.
-
-The `validates_with` helper takes a class, or a list of classes to use for validation. There is no default error message for `validates_with`. You must manually add errors to the record's errors collection in the validator class.
-
-To implement the validate method, you must have a `record` parameter defined, which is the record to be validated.
-
-Like all other validations, `validates_with` takes the `:if`, `:unless` and `:on` options. If you pass any other options, it will send those options to the validator class as `options`:
-
-```ruby
-class Person < ActiveRecord::Base
- validates_with GoodnessValidator, fields: [:first_name, :last_name]
-end
-
-class GoodnessValidator < ActiveModel::Validator
- def validate(record)
- if options[:fields].any?{|field| record.send(field) == "Evil" }
- record.errors[:base] << "This person is evil"
- end
- end
-end
-```
-
-### `validates_each`
-
-This helper validates attributes against a block. It doesn't have a predefined validation function. You should create one using a block, and every attribute passed to `validates_each` will be tested against it. In the following example, we don't want names and surnames to begin with lower case.
-
-```ruby
-class Person < ActiveRecord::Base
- validates_each :name, :surname do |record, attr, value|
- record.errors.add(attr, 'must start with upper case') if value =~ /\A[a-z]/
- end
-end
-```
-
-The block receives the record, the attribute's name and the attribute's value. You can do anything you like to check for valid data within the block. If your validation fails, you should add an error message to the model, therefore making it invalid.
-
-Common Validation Options
--------------------------
-
-These are common validation options:
-
-### `:allow_nil`
-
-The `:allow_nil` option skips the validation when the value being validated is `nil`.
-
-```ruby
-class Coffee < ActiveRecord::Base
- validates :size, inclusion: { in: %w(small medium large),
- message: "%{value} is not a valid size" }, allow_nil: true
-end
-```
-
-TIP: `:allow_nil` is ignored by the presence validator.
-
-### `:allow_blank`
-
-The `:allow_blank` option is similar to the `:allow_nil` option. This option will let validation pass if the attribute's value is `blank?`, like `nil` or an empty string for example.
-
-```ruby
-class Topic < ActiveRecord::Base
- validates :title, length: { is: 5 }, allow_blank: true
-end
-
-Topic.create("title" => "").valid? # => true
-Topic.create("title" => nil).valid? # => true
-```
-
-TIP: `:allow_blank` is ignored by the presence validator.
-
-### `:message`
-
-As you've already seen, the `:message` option lets you specify the message that will be added to the `errors` collection when validation fails. When this option is not used, Active Record will use the respective default error message for each validation helper.
-
-### `:on`
-
-The `:on` option lets you specify when the validation should happen. The default behavior for all the built-in validation helpers is to be run on save (both when you're creating a new record and when you're updating it). If you want to change it, you can use `on: :create` to run the validation only when a new record is created or `on: :update` to run the validation only when a record is updated.
-
-```ruby
-class Person < ActiveRecord::Base
- # it will be possible to update email with a duplicated value
- validates :email, uniqueness: true, on: :create
-
- # it will be possible to create the record with a non-numerical age
- validates :age, numericality: true, on: :update
-
- # the default (validates on both create and update)
- validates :name, presence: true, on: :save
-end
-```
-
-Strict Validations
-------------------
-
-You can also specify validations to be strict and raise `ActiveModel::StrictValidationFailed` when the object is invalid.
-
-```ruby
-class Person < ActiveRecord::Base
- validates :name, presence: { strict: true }
-end
-
-Person.new.valid? #=> ActiveModel::StrictValidationFailed: Name can't be blank
-```
-
-There is also an ability to pass custom exception to `:strict` option
-
-```ruby
-class Person < ActiveRecord::Base
- validates :token, presence: true, uniqueness: true, strict: TokenGenerationException
-end
-
-Person.new.valid? #=> TokenGenerationException: Token can't be blank
-```
-
-Conditional Validation
-----------------------
-
-Sometimes it will make sense to validate an object just when a given predicate is satisfied. You can do that by using the `:if` and `:unless` options, which can take a symbol, a string, a `Proc` or an `Array`. You may use the `:if` option when you want to specify when the validation **should** happen. If you want to specify when the validation **should not** happen, then you may use the `:unless` option.
-
-### Using a Symbol with `:if` and `:unless`
-
-You can associate the `:if` and `:unless` options with a symbol corresponding to the name of a method that will get called right before validation happens. This is the most commonly used option.
-
-```ruby
-class Order < ActiveRecord::Base
- validates :card_number, presence: true, if: :paid_with_card?
-
- def paid_with_card?
- payment_type == "card"
- end
-end
-```
-
-### Using a String with `:if` and `:unless`
-
-You can also use a string that will be evaluated using `eval` and needs to contain valid Ruby code. You should use this option only when the string represents a really short condition.
-
-```ruby
-class Person < ActiveRecord::Base
- validates :surname, presence: true, if: "name.nil?"
-end
-```
-
-### Using a Proc with `:if` and `:unless`
-
-Finally, it's possible to associate `:if` and `:unless` with a `Proc` object which will be called. Using a `Proc` object gives you the ability to write an inline condition instead of a separate method. This option is best suited for one-liners.
-
-```ruby
-class Account < ActiveRecord::Base
- validates :password, confirmation: true,
- unless: Proc.new { |a| a.password.blank? }
-end
-```
-
-### Grouping conditional validations
-
-Sometimes it is useful to have multiple validations use one condition, it can be easily achieved using `with_options`.
-
-```ruby
-class User < ActiveRecord::Base
- with_options if: :is_admin? do |admin|
- admin.validates :password, length: { minimum: 10 }
- admin.validates :email, presence: true
- end
-end
-```
-
-All validations inside of `with_options` block will have automatically passed the condition `if: :is_admin?`
-
-### Combining validation conditions
-
-On the other hand, when multiple conditions define whether or not a validation should happen, an `Array` can be used. Moreover, you can apply both `:if` and `:unless` to the same validation.
-
-```ruby
-class Computer < ActiveRecord::Base
- validates :mouse, presence: true,
- if: ["market.retail?", :desktop?]
- unless: Proc.new { |c| c.trackpad.present? }
-end
-```
-
-The validation only runs when all the `:if` conditions and none of the `:unless` conditions are evaluated to `true`.
-
-Performing Custom Validations
------------------------------
-
-When the built-in validation helpers are not enough for your needs, you can write your own validators or validation methods as you prefer.
-
-### Custom Validators
-
-Custom validators are classes that extend `ActiveModel::Validator`. These classes must implement a `validate` method which takes a record as an argument and performs the validation on it. The custom validator is called using the `validates_with` method.
-
-```ruby
-class MyValidator < ActiveModel::Validator
- def validate(record)
- unless record.name.starts_with? 'X'
- record.errors[:name] << 'Need a name starting with X please!'
- end
- end
-end
-
-class Person
- include ActiveModel::Validations
- validates_with MyValidator
-end
-```
-
-The easiest way to add custom validators for validating individual attributes is with the convenient `ActiveModel::EachValidator`. In this case, the custom validator class must implement a `validate_each` method which takes three arguments: record, attribute and value which correspond to the instance, the attribute to be validated and the value of the attribute in the passed instance.
-
-```ruby
-class EmailValidator < ActiveModel::EachValidator
- def validate_each(record, attribute, value)
- unless value =~ /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i
- record.errors[attribute] << (options[:message] || "is not an email")
- end
- end
-end
-
-class Person < ActiveRecord::Base
- validates :email, presence: true, email: true
-end
-```
-
-As shown in the example, you can also combine standard validations with your own custom validators.
-
-### 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 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.
-
-```ruby
-class Invoice < ActiveRecord::Base
- validate :expiration_date_cannot_be_in_the_past,
- :discount_cannot_be_greater_than_total_value
-
- def expiration_date_cannot_be_in_the_past
- if !expiration_date.blank? and expiration_date < Date.today
- errors.add(:expiration_date, "can't be in the past")
- end
- end
-
- def discount_cannot_be_greater_than_total_value
- if discount > total_value
- errors.add(:discount, "can't be greater than total value")
- end
- end
-end
-```
-
-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
-```
-
-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) }
- end
-end
-```
-
-Simply reopen `ActiveRecord::Base` and define a class method like that. You'd typically put this code somewhere in `config/initializers`. You can use this helper like this:
-
-```ruby
-class Movie < ActiveRecord::Base
- validates_as_choice :rating, 5
-end
-```
-
-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 `ActiveModel::Errors` documentation for a list of all the available methods.
-
-### `errors`
-
-Returns an instance of the class `ActiveModel::Errors` containing all errors. Each key is the attribute name and the value is an array of strings with all errors.
-
-```ruby
-class Person < ActiveRecord::Base
- validates :name, presence: true, length: { minimum: 3 }
-end
-
-person = Person.new
-person.valid? # => false
-person.errors
- # => {:name=>["can't be blank", "is too short (minimum is 3 characters)"]}
-
-person = Person.new(name: "John Doe")
-person.valid? # => true
-person.errors # => []
-```
-
-### `errors[]`
-
-`errors[]` is used when you want to check the error messages for a specific attribute. It returns an array of strings with all error messages for the given attribute, each string with one error message. If there are no errors related to the attribute, it returns an empty array.
-
-```ruby
-class Person < ActiveRecord::Base
- validates :name, presence: true, length: { minimum: 3 }
-end
-
-person = Person.new(name: "John Doe")
-person.valid? # => true
-person.errors[:name] # => []
-
-person = Person.new(name: "JD")
-person.valid? # => false
-person.errors[:name] # => ["is too short (minimum is 3 characters)"]
-
-person = Person.new
-person.valid? # => false
-person.errors[:name]
- # => ["can't be blank", "is too short (minimum is 3 characters)"]
-```
-
-### `errors.add`
-
-The `add` method lets you manually add messages that are related to particular attributes. You can use the `errors.full_messages` or `errors.to_a` methods to view the messages in the form they might be displayed to a user. Those particular messages get the attribute name prepended (and capitalized). `add` receives the name of the attribute you want to add the message to, and the message itself.
-
-```ruby
-class Person < ActiveRecord::Base
- def a_method_used_for_validation_purposes
- errors.add(:name, "cannot contain the characters !@#%*()_-+=")
- end
-end
-
-person = Person.create(name: "!@#")
-
-person.errors[:name]
- # => ["cannot contain the characters !@#%*()_-+="]
-
-person.errors.full_messages
- # => ["Name cannot contain the characters !@#%*()_-+="]
-```
-
-Another way to do this is using `[]=` setter
-
-```ruby
- class Person < ActiveRecord::Base
- def a_method_used_for_validation_purposes
- errors[:name] = "cannot contain the characters !@#%*()_-+="
- end
- end
-
- person = Person.create(name: "!@#")
-
- person.errors[:name]
- # => ["cannot contain the characters !@#%*()_-+="]
-
- person.errors.to_a
- # => ["Name cannot contain the characters !@#%*()_-+="]
-```
-
-### `errors[:base]`
-
-You can add error messages that are related to the object's state as a whole, instead of being related to a specific attribute. You can use this method when you want to say that the object is invalid, no matter the values of its attributes. Since `errors[:base]` is an array, you can simply add a string to it and it will be used as an error message.
-
-```ruby
-class Person < ActiveRecord::Base
- def a_method_used_for_validation_purposes
- errors[:base] << "This person is invalid because ..."
- end
-end
-```
-
-### `errors.clear`
-
-The `clear` method is used when you intentionally want to clear all the messages in the `errors` collection. Of course, calling `errors.clear` upon an invalid object won't actually make it valid: the `errors` collection will now be empty, but the next time you call `valid?` or any method that tries to save this object to the database, the validations will run again. If any of the validations fail, the `errors` collection will be filled again.
-
-```ruby
-class Person < ActiveRecord::Base
- validates :name, presence: true, length: { minimum: 3 }
-end
-
-person = Person.new
-person.valid? # => false
-person.errors[:name]
- # => ["can't be blank", "is too short (minimum is 3 characters)"]
-
-person.errors.clear
-person.errors.empty? # => true
-
-p.save # => false
-
-p.errors[:name]
-# => ["can't be blank", "is too short (minimum is 3 characters)"]
-```
-
-### `errors.size`
-
-The `size` method returns the total number of error messages for the object.
-
-```ruby
-class Person < ActiveRecord::Base
- validates :name, presence: true, length: { minimum: 3 }
-end
-
-person = Person.new
-person.valid? # => false
-person.errors.size # => 2
-
-person = Person.new(name: "Andrea", email: "andrea@example.com")
-person.valid? # => true
-person.errors.size # => 0
-```
-
-Displaying Validation Errors in the View
-----------------------------------------
-
-[DynamicForm](https://github.com/joelmoss/dynamic_form) provides helpers to display the error messages of your models in your view templates.
-
-You can install it as a gem by adding this line to your Gemfile:
-
-```ruby
-gem "dynamic_form"
-```
-
-Now you will have access to the two helper methods `error_messages` and `error_messages_for` in your view templates.
-
-### `error_messages` and `error_messages_for`
-
-When creating a form with the `form_for` helper, you can use the `error_messages` method on the form builder to render all failed validation messages for the current model instance.
-
-```ruby
-class Product < ActiveRecord::Base
- validates :description, :value, presence: true
- validates :value, numericality: true, allow_nil: true
-end
-```
-
-```erb
-<%= form_for(@product) do |f| %>
- <%= f.error_messages %>
- <p>
- <%= f.label :description %><br />
- <%= f.text_field :description %>
- </p>
- <p>
- <%= f.label :value %><br />
- <%= f.text_field :value %>
- </p>
- <p>
- <%= f.submit "Create" %>
- </p>
-<% end %>
-```
-
-If you submit the form with empty fields, the result will be similar to the one shown below:
-
-![Error messages](images/error_messages.png)
-
-NOTE: The appearance of the generated HTML will be different from the one shown, unless you have used scaffolding. See [Customizing the Error Messages CSS](#customizing-the-error-messages-css).
-
-You can also use the `error_messages_for` helper to display the error messages of a model assigned to a view template. It is very similar to the previous example and will achieve exactly the same result.
-
-```erb
-<%= error_messages_for :product %>
-```
-
-The displayed text for each error message will always be formed by the capitalized name of the attribute that holds the error, followed by the error message itself.
-
-Both the `form.error_messages` and the `error_messages_for` helpers accept options that let you customize the `div` element that holds the messages, change the header text, change the message below the header, and specify the tag used for the header element. For example,
-
-```erb
-<%= f.error_messages header_message: "Invalid product!",
- message: "You'll need to fix the following fields:",
- header_tag: :h3 %>
-```
-
-results in:
-
-![Customized error messages](images/customized_error_messages.png)
-
-If you pass `nil` in any of these options, the corresponding section of the `div` will be discarded.
-
-### Customizing the Error Messages CSS
-
-The selectors used to customize the style of error messages are:
-
-* `.field_with_errors` - Style for the form fields and labels with errors.
-* `#error_explanation` - Style for the `div` element with the error messages.
-* `#error_explanation h2` - Style for the header of the `div` element.
-* `#error_explanation p` - Style for the paragraph holding the message that appears right below the header of the `div` element.
-* `#error_explanation ul li` - Style for the list items with individual error messages.
-
-If scaffolding was used, file `app/assets/stylesheets/scaffolds.css.scss` will have been generated automatically. This file defines the red-based styles you saw in the examples above.
-
-The name of the class and the id can be changed with the `:class` and `:id` options, accepted by both helpers.
-
-### Customizing the Error Messages HTML
-
-By default, form fields with errors are displayed enclosed by a `div` element with the `field_with_errors` CSS class. However, it's possible to override that.
-
-The way form fields with errors are treated is defined by `ActionView::Base.field_error_proc`. This is a `Proc` that receives two parameters:
-
-* A string with the HTML tag
-* An instance of `ActionView::Helpers::InstanceTag`.
-
-Below is a simple example where we change the Rails behavior to always display the error messages in front of each of the form fields in error. The error messages will be enclosed by a `span` element with a `validation-error` CSS class. There will be no `div` element enclosing the `input` element, so we get rid of that red border around the text field. You can use the `validation-error` CSS class to style it anyway you want.
-
-```ruby
-ActionView::Base.field_error_proc = Proc.new do |html_tag, instance|
- if html_tag =~ /\<label/
- html_tag
- else
- errors = Array(instance.error_message).join(',')
- %(#{html_tag}<span class="validation-error">&nbsp;#{errors}</span>).html_safe
- end
-end
-```
-
-The result looks like the following:
-
-![Validation error messages](images/validation_error_messages.png)
-
-Callbacks Overview
-------------------
-
-Callbacks are methods that get called at certain moments of an object's life cycle. With callbacks it is possible to write code that will run whenever an Active Record object is created, saved, updated, deleted, validated, or loaded from the database.
-
-### Callback Registration
-
-In order to use the available callbacks, you need to register them. You can implement the callbacks as ordinary methods and use a macro-style class method to register them as callbacks:
-
-```ruby
-class User < ActiveRecord::Base
- validates :login, :email, presence: true
-
- before_validation :ensure_login_has_a_value
-
- protected
- def ensure_login_has_a_value
- if login.nil?
- self.login = email unless email.blank?
- end
- end
-end
-```
-
-The macro-style class methods can also receive a block. Consider using this style if the code inside your block is so short that it fits in a single line:
-
-```ruby
-class User < ActiveRecord::Base
- validates :login, :email, presence: true
-
- before_create do |user|
- user.name = user.login.capitalize if user.name.blank?
- end
-end
-```
-
-Callbacks can also be registered to only fire on certain lifecycle events:
-
-```ruby
-class User < ActiveRecord::Base
- before_validation :normalize_name, on: :create
-
- # :on takes an array as well
- after_validation :set_location, on: [ :create, :update ]
-
- protected
- def normalize_name
- self.name = self.name.downcase.titleize
- end
-
- def set_location
- self.location = LocationService.query(self)
- end
-end
-```
-
-It is considered good practice to declare callback methods as protected or private. If left public, they can be called from outside of the model and violate the principle of object encapsulation.
-
-Available Callbacks
--------------------
-
-Here is a list with all the available Active Record callbacks, listed in the same order in which they will get called during the respective operations:
-
-### Creating an Object
-
-* `before_validation`
-* `after_validation`
-* `before_save`
-* `around_save`
-* `before_create`
-* `around_create`
-* `after_create`
-* `after_save`
-
-### Updating an Object
-
-* `before_validation`
-* `after_validation`
-* `before_save`
-* `around_save`
-* `before_update`
-* `around_update`
-* `after_update`
-* `after_save`
-
-### Destroying an Object
-
-* `before_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.
-
-### `after_initialize` and `after_find`
-
-The `after_initialize` callback will be called whenever an Active Record object is instantiated, either by directly using `new` or when a record is loaded from the database. It can be useful to avoid the need to directly override your Active Record `initialize` method.
-
-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 have no `before_*` counterparts, but they can be registered just like the other Active Record callbacks.
-
-```ruby
-class User < ActiveRecord::Base
- after_initialize do |user|
- puts "You have initialized an object!"
- end
-
- after_find do |user|
- puts "You have found an object!"
- end
-end
-
->> User.new
-You have initialized an object!
-=> #<User id: nil>
-
->> User.first
-You have found an object!
-You have initialized an object!
-=> #<User id: 1>
-```
-
-Running Callbacks
------------------
-
-The following methods trigger callbacks:
-
-* `create`
-* `create!`
-* `decrement!`
-* `destroy`
-* `destroy_all`
-* `increment!`
-* `save`
-* `save!`
-* `save(validate: false)`
-* `toggle!`
-* `update`
-* `update_attribute`
-* `update_attributes`
-* `update_attributes!`
-* `valid?`
-
-Additionally, the `after_find` callback is triggered by the following finder methods:
-
-* `all`
-* `first`
-* `find`
-* `find_all_by_*`
-* `find_by_*`
-* `find_by_*!`
-* `find_by_sql`
-* `last`
-
-The `after_initialize` callback is triggered every time a new object of the class is initialized.
-
-NOTE: The `find_all_by_*`, `find_by_*` and `find_by_*!` methods are dynamic finders generated automatically for every attribute. Learn more about them at the [Dynamic finders section](active_record_querying.html#dynamic-finders)
-
-Skipping Callbacks
-------------------
-
-Just as with validations, it is also possible to skip callbacks. These methods should be used with caution, however, because important business rules and application logic may be kept in callbacks. Bypassing them without understanding the potential implications may lead to invalid data.
-
-* `decrement`
-* `decrement_counter`
-* `delete`
-* `delete_all`
-* `increment`
-* `increment_counter`
-* `toggle`
-* `touch`
-* `update_column`
-* `update_columns`
-* `update_all`
-* `update_counters`
-
-Halting Execution
------------------
-
-As you start registering new callbacks for your models, they will be queued for execution. This queue will include all your model's validations, the registered callbacks, and the database operation to be executed.
-
-The whole callback chain is wrapped in a transaction. If any <em>before</em> callback method returns exactly `false` or raises an exception, the execution chain gets halted and a ROLLBACK is issued; <em>after</em> callbacks can only accomplish that by raising an exception.
-
-WARNING. Raising an arbitrary exception may break code that expects `save` and its friends not to fail like that. The `ActiveRecord::Rollback` exception is thought precisely to tell Active Record a rollback is going on. That one is internally captured but not reraised.
-
-Relational Callbacks
---------------------
-
-Callbacks work through model relationships, and can even be defined by them. Suppose an example where a user has many posts. A user's posts should be destroyed if the user is destroyed. Let's add an `after_destroy` callback to the `User` model by way of its relationship to the `Post` model:
-
-```ruby
-class User < ActiveRecord::Base
- has_many :posts, dependent: :destroy
-end
-
-class Post < ActiveRecord::Base
- after_destroy :log_destroy_action
-
- def log_destroy_action
- puts 'Post destroyed'
- end
-end
-
->> user = User.first
-=> #<User id: 1>
->> user.posts.create!
-=> #<Post id: 1, user_id: 1>
->> user.destroy
-Post destroyed
-=> #<User id: 1>
-```
-
-Conditional Callbacks
----------------------
-
-As with validations, we can also make the calling of a callback method conditional on the satisfaction of a given predicate. We can do this using the `:if` and `:unless` options, which can take a symbol, a string, a `Proc` or an `Array`. You may use the `:if` option when you want to specify under which conditions the callback **should** be called. If you want to specify the conditions under which the callback **should not** be called, then you may use the `:unless` option.
-
-### Using `:if` and `:unless` with a `Symbol`
-
-You can associate the `:if` and `:unless` options with a symbol corresponding to the name of a predicate method that will get called right before the callback. When using the `:if` option, the callback won't be executed if the predicate method returns false; when using the `:unless` option, the callback won't be executed if the predicate method returns true. This is the most common option. Using this form of registration it is also possible to register several different predicates that should be called to check if the callback should be executed.
-
-```ruby
-class Order < ActiveRecord::Base
- before_save :normalize_card_number, if: :paid_with_card?
-end
-```
-
-### Using `:if` and `:unless` with a String
-
-You can also use a string that will be evaluated using `eval` and hence needs to contain valid Ruby code. You should use this option only when the string represents a really short condition:
-
-```ruby
-class Order < ActiveRecord::Base
- before_save :normalize_card_number, if: "paid_with_card?"
-end
-```
-
-### Using `:if` and `:unless` with a `Proc`
-
-Finally, it is possible to associate `:if` and `:unless` with a `Proc` object. This option is best suited when writing short validation methods, usually one-liners:
-
-```ruby
-class Order < ActiveRecord::Base
- before_save :normalize_card_number,
- if: Proc.new { |order| order.paid_with_card? }
-end
-```
-
-### Multiple Conditions for Callbacks
-
-When writing conditional callbacks, it is possible to mix both `:if` and `:unless` in the same callback declaration:
-
-```ruby
-class Comment < ActiveRecord::Base
- after_create :send_email_to_author, if: :author_wants_emails?,
- unless: Proc.new { |comment| comment.post.ignore_comments? }
-end
-```
-
-Callback Classes
-----------------
-
-Sometimes the callback methods that you'll write will be useful enough to be reused by other models. Active Record makes it possible to create classes that encapsulate the callback methods, so it becomes very easy to reuse them.
-
-Here's an example where we create a class with an `after_destroy` callback for a `PictureFile` model:
-
-```ruby
-class PictureFileCallbacks
- def after_destroy(picture_file)
- if File.exists?(picture_file.filepath)
- File.delete(picture_file.filepath)
- end
- end
-end
-```
-
-When declared inside a class, as above, the callback methods will receive the model object as a parameter. We can now use the callback class in the model:
-
-```ruby
-class PictureFile < ActiveRecord::Base
- after_destroy PictureFileCallbacks.new
-end
-```
-
-Note that we needed to instantiate a new `PictureFileCallbacks` object, since we declared our callback as an instance method. This is particularly useful if the callbacks make use of the state of the instantiated object. Often, however, it will make more sense to declare the callbacks as class methods:
-
-```ruby
-class PictureFileCallbacks
- def self.after_destroy(picture_file)
- if File.exists?(picture_file.filepath)
- File.delete(picture_file.filepath)
- end
- end
-end
-```
-
-If the callback method is declared this way, it won't be necessary to instantiate a `PictureFileCallbacks` object.
-
-```ruby
-class PictureFile < ActiveRecord::Base
- after_destroy PictureFileCallbacks
-end
-```
-
-You can declare as many callbacks as you want inside your callback classes.
-
-Observers
----------
-
-Observers are similar to callbacks, but with important differences. Whereas callbacks can pollute a model with code that isn't directly related to its purpose, observers allow you to add the same functionality without changing the code of the model. For example, it could be argued that a `User` model should not include code to send registration confirmation emails. Whenever you use callbacks with code that isn't directly related to your model, you may want to consider creating an observer instead.
-
-### Creating Observers
-
-For example, imagine a `User` model where we want to send an email every time a new user is created. Because sending emails is not directly related to our model's purpose, we should create an observer to contain the code implementing this functionality.
-
-```bash
-$ rails generate observer User
-```
-
-generates `app/models/user_observer.rb` containing the observer class `UserObserver`:
-
-```ruby
-class UserObserver < ActiveRecord::Observer
-end
-```
-
-You may now add methods to be called at the desired occasions:
-
-```ruby
-class UserObserver < ActiveRecord::Observer
- def after_create(model)
- # code to send confirmation email...
- end
-end
-```
-
-As with callback classes, the observer's methods receive the observed model as a parameter.
-
-### Registering Observers
-
-Observers are conventionally placed inside of your `app/models` directory and registered in your application's `config/application.rb` file. For example, the `UserObserver` above would be saved as `app/models/user_observer.rb` and registered in `config/application.rb` this way:
-
-```ruby
-# Activate observers that should always be running.
-config.active_record.observers = :user_observer
-```
-
-As usual, settings in `config/environments` take precedence over those in `config/application.rb`. So, if you prefer that an observer doesn't run in all environments, you can simply register it in a specific environment instead.
-
-### Sharing Observers
-
-By default, Rails will simply strip "Observer" from an observer's name to find the model it should observe. However, observers can also be used to add behavior to more than one model, and thus it is possible to explicitly specify the models that our observer should observe:
-
-```ruby
-class MailerObserver < ActiveRecord::Observer
- observe :registration, :user
-
- def after_create(model)
- # code to send confirmation email...
- end
-end
-```
-
-In this example, the `after_create` method will be called whenever a `Registration` or `User` is created. Note that this new `MailerObserver` would also need to be registered in `config/application.rb` in order to take effect:
-
-```ruby
-# Activate observers that should always be running.
-config.active_record.observers = :mailer_observer
-```
-
-Transaction Callbacks
----------------------
-
-There are two additional callbacks that are triggered by the completion of a database transaction: `after_commit` and `after_rollback`. These callbacks are very similar to the `after_save` callback except that they don't execute until after database changes have either been committed or rolled back. They are most useful when your active record models need to interact with external systems which are not part of the database transaction.
-
-Consider, for example, the previous example where the `PictureFile` model needs to delete a file after the corresponding record is destroyed. If anything raises an exception after the `after_destroy` callback is called and the transaction rolls back, the file will have been deleted and the model will be left in an inconsistent state. For example, suppose that `picture_file_2` in the code below is not valid and the `save!` method raises an error.
-
-```ruby
-PictureFile.transaction do
- picture_file_1.destroy
- picture_file_2.save!
-end
-```
-
-By using the `after_commit` callback we can account for this case.
-
-```ruby
-class PictureFile < ActiveRecord::Base
- attr_accessor :delete_file
-
- after_destroy do |picture_file|
- picture_file.delete_file = picture_file.filepath
- end
-
- after_commit do |picture_file|
- if picture_file.delete_file && File.exist?(picture_file.delete_file)
- File.delete(picture_file.delete_file)
- picture_file.delete_file = nil
- end
- end
-end
-```
-
-The `after_commit` and `after_rollback` callbacks are guaranteed to be called for all models created, updated, or destroyed within a transaction block. If any exceptions are raised within one of these callbacks, they will be ignored so that they don't interfere with the other callbacks. As such, if your callback code could raise an exception, you'll need to rescue it and handle it appropriately within the callback.
diff --git a/guides/source/active_support_core_extensions.md b/guides/source/active_support_core_extensions.md
index 401e6f0596..1d79ee2565 100644
--- a/guides/source/active_support_core_extensions.md
+++ b/guides/source/active_support_core_extensions.md
@@ -5,7 +5,12 @@ Active Support is the Ruby on Rails component responsible for providing Ruby lan
It offers a richer bottom-line at the language level, targeted both at the development of Rails applications, and at the development of Ruby on Rails itself.
-By referring to this guide you will learn the extensions to the Ruby core classes and modules provided by Active Support.
+After reading this guide, you will know:
+
+* What Core Extensions are.
+* How to load all extensions.
+* How to cherry-pick just the extensions you want.
+* What extensions ActiveSupport provides.
--------------------------------------------------------------------------------
@@ -1120,8 +1125,6 @@ C.subclasses # => [B, D]
The order in which these classes are returned is unspecified.
-WARNING: This method is redefined in some Rails core classes but should be all compatible in Rails 3.1.
-
NOTE: Defined in `active_support/core_ext/class/subclasses.rb`.
#### `descendants`
@@ -1157,7 +1160,7 @@ Inserting data into HTML templates needs extra care. For example, you can't just
#### Safe Strings
-Active Support has the concept of <i>(html) safe</i> strings since Rails 3. A safe string is one that is marked as being insertable into HTML as is. It is trusted, no matter whether it has been escaped or not.
+Active Support has the concept of <i>(html) safe</i> strings. A safe string is one that is marked as being insertable into HTML as is. It is trusted, no matter whether it has been escaped or not.
Strings are considered to be <i>unsafe</i> by default:
@@ -1194,10 +1197,10 @@ Safe arguments are directly appended:
"".html_safe + "<".html_safe # => "<"
```
-These methods should not be used in ordinary views. In Rails 3 unsafe values are automatically escaped:
+These methods should not be used in ordinary views. Unsafe values are automatically escaped:
```erb
-<%= @review.title %> <%# fine in Rails 3, escaped if needed %>
+<%= @review.title %> <%# fine, escaped if needed %>
```
To insert something verbatim use the `raw` helper rather than calling `html_safe`:
@@ -2067,14 +2070,6 @@ The sum of an empty receiver can be customized in this form as well:
[].sum(1) {|n| n**3} # => 1
```
-The method `ActiveRecord::Observer#observed_subclasses` for example is implemented this way:
-
-```ruby
-def observed_subclasses
- observed_classes.sum([]) { |klass| klass.send(:subclasses) }
-end
-```
-
NOTE: Defined in `active_support/core_ext/enumerable.rb`.
### `index_by`
@@ -3728,6 +3723,25 @@ The auxiliary file is written in a standard directory for temporary files, but y
NOTE: Defined in `active_support/core_ext/file/atomic.rb`.
+Extensions to `Marshal`
+-----------------------
+
+### `load`
+
+Active Support adds constant autoloading support to `load`.
+
+For example, the file cache store deserializes this way:
+
+```ruby
+File.open(file_name) { |f| Marshal.load(f) }
+```
+
+If the cached data refers to a constant that is unknown at that point, the autoloading mechanism is triggered and if it succeeds the deserialization is retried transparently.
+
+WARNING. If the argument is an `IO` it needs to respond to `rewind` to be able to retry. Regular files respond to `rewind`.
+
+NOTE: Defined in `active_support/core_ext/marshal.rb`.
+
Extensions to `Logger`
----------------------
diff --git a/guides/source/active_support_instrumentation.md b/guides/source/active_support_instrumentation.md
index 1163940f10..cf5a51fc5b 100644
--- a/guides/source/active_support_instrumentation.md
+++ b/guides/source/active_support_instrumentation.md
@@ -3,19 +3,21 @@ Active Support Instrumentation
Active Support is a part of core Rails that provides Ruby language extensions, utilities and other things. One of the things it includes is an instrumentation API that can be used inside an application to measure certain actions that occur within Ruby code, such as that inside a Rails application or the framework itself. It is not limited to Rails, however. It can be used independently in other Ruby scripts if it is so desired.
-In this guide, you will learn how to use the instrumentation API inside of ActiveSupport to measure events inside of Rails and other Ruby code. We cover:
+In this guide, you will learn how to use the instrumentation API inside of Active Support to measure events inside of Rails and other Ruby code.
-* What instrumentation can provide
-* The hooks inside the Rails framework for instrumentation
-* Adding a subscriber to a hook
-* Building a custom instrumentation implementation
+After reading this guide, you will know:
+
+* What instrumentation can provide.
+* The hooks inside the Rails framework for instrumentation.
+* Adding a subscriber to a hook.
+* Building a custom instrumentation implementation.
--------------------------------------------------------------------------------
Introduction to instrumentation
-------------------------------
-The instrumentation API provided by ActiveSupport allows developers to provide hooks which other developers may hook into. There are several of these within the Rails framework, as described below in <TODO: link to section detailing each hook point>. With this API, developers can choose to be notified when certain events occur inside their application or another piece of Ruby code.
+The instrumentation API provided by Active Support allows developers to provide hooks which other developers may hook into. There are several of these within the Rails framework, as described below in <TODO: link to section detailing each hook point>. With this API, developers can choose to be notified when certain events occur inside their application or another piece of Ruby code.
For example, there is a hook provided within Active Record that is called every time Active Record uses an SQL query on a database. This hook could be **subscribed** to, and used to track the number of queries during a certain action. There's another hook around the processing of an action of a controller. This could be used, for instance, to track how long a specific action has taken.
@@ -26,8 +28,8 @@ Rails framework hooks
Within the Ruby on Rails framework, there are a number of hooks provided for common events. These are detailed below.
-ActionController
-----------------
+Action Controller
+-----------------
### write_fragment.action_controller
@@ -187,8 +189,8 @@ INFO. Additional keys may be added by the caller.
}
```
-ActionView
-----------
+Action View
+-----------
### render_template.action_view
@@ -216,7 +218,7 @@ ActionView
}
```
-ActiveRecord
+Active Record
------------
### sql.active_record
@@ -246,8 +248,8 @@ INFO. The adapters will add their own data as well.
| `:name` | Record's class |
| `:connection_id` | `self.object_id` |
-ActionMailer
-------------
+Action Mailer
+-------------
### receive.action_mailer
@@ -312,8 +314,8 @@ ActiveResource
| `:request_uri` | Complete URI |
| `:result` | HTTP response object |
-ActiveSupport
--------------
+Active Support
+--------------
### cache_read.active_support
diff --git a/guides/source/api_documentation_guidelines.md b/guides/source/api_documentation_guidelines.md
index 72e412e701..d0499878da 100644
--- a/guides/source/api_documentation_guidelines.md
+++ b/guides/source/api_documentation_guidelines.md
@@ -3,6 +3,11 @@ API Documentation Guidelines
This guide documents the Ruby on Rails API documentation guidelines.
+After reading this guide, you will know:
+
+* How to write effective prose for documentation purposes.
+* Style guidelines for documenting different kinds of Ruby code.
+
--------------------------------------------------------------------------------
RDoc
diff --git a/guides/source/asset_pipeline.md b/guides/source/asset_pipeline.md
index 13df1965b6..ff6787dae5 100644
--- a/guides/source/asset_pipeline.md
+++ b/guides/source/asset_pipeline.md
@@ -1,14 +1,15 @@
-Asset Pipeline
-==============
+The Asset Pipeline
+==================
-This guide covers the asset pipeline introduced in Rails 3.1.
-By referring to this guide you will be able to:
+This guide covers the asset pipeline.
-* Understand what the asset pipeline is and what it does
-* Properly organize your application assets
-* Understand the benefits of the asset pipeline
-* Add a pre-processor to the pipeline
-* Package assets with a gem
+After reading this guide, you will know:
+
+* How to understand what the asset pipeline is and what it does.
+* How to properly organize your application assets.
+* How to understand the benefits of the asset pipeline.
+* How to add a pre-processor to the pipeline.
+* How to package assets with a gem.
--------------------------------------------------------------------------------
@@ -17,11 +18,9 @@ What is the Asset Pipeline?
The asset pipeline provides a framework to concatenate and minify or compress JavaScript and CSS assets. It also adds the ability to write these assets in other languages such as CoffeeScript, Sass and ERB.
-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.
-
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:
+The asset pipeline is enabled by default. It can be disabled in `config/application.rb` by putting this line inside the application class definition:
```ruby
config.assets.enabled = false
@@ -99,7 +98,24 @@ In production, Rails precompiles these files to `public/assets` by default. The
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 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] %>`.
+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 that you have to set `config.assets.precompile` in `config/environments/production.rb` if you want to precomepile them and use in production mode. You can append them one by one or do something like this:
+
+ # config/environments/production.rb
+ config.assets.precompile << Proc.new { |path|
+ if path =~ /\.(css|js)\z/
+ full_path = Rails.application.assets.resolve(path).to_path
+ app_assets_path = Rails.root.join('app', 'assets').to_path
+ if full_path.starts_with? app_assets_path
+ puts "including asset: " + full_path
+ true
+ else
+ puts "excluding asset: " + full_path
+ false
+ end
+ else
+ false
+ end
+ }
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.
@@ -113,7 +129,7 @@ Pipeline assets can be placed inside an application in one of three locations: `
* `vendor/assets` is for assets that are owned by outside entities, such as code for JavaScript plugins and CSS frameworks.
-#### Search paths
+#### Search Paths
When a file is referenced from a manifest or a helper, Sprockets searches the three default asset locations for it.
@@ -161,7 +177,7 @@ Paths are traversed in the order that they occur in the search path. By default,
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.
-#### Using index files
+#### Using Index Files
Sprockets uses files named `index` (with the relevant extensions) for a special purpose.
@@ -269,8 +285,6 @@ For example, a new Rails application includes a default `app/assets/javascripts/
In JavaScript files, the directives begin with `//=`. In this case, the file is using the `require` and the `require_tree` directives. The `require` directive is used to tell Sprockets the files that you wish to require. Here, you are requiring the files `jquery.js` and `jquery_ujs.js` that are available somewhere in the search path for Sprockets. You need not supply the extensions explicitly. Sprockets assumes you are requiring a `.js` file when done from within a `.js` file.
-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 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 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.
@@ -336,7 +350,7 @@ would generate this HTML:
The `body` param is required by Sprockets.
-### Turning Debugging off
+### Turning Debugging Off
You can turn off debug mode by updating `config/environments/development.rb` to include:
@@ -461,7 +475,7 @@ The default location for the manifest is the root of the location specified in `
NOTE: If there are missing precompiled files in production you will get an `Sprockets::Helpers::RailsHelper::AssetPaths::AssetNotPrecompiledError` exception indicating the name of the missing file(s).
-#### Far-future Expires header
+#### Far-future Expires Header
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.
@@ -491,7 +505,7 @@ location ~ ^/assets/ {
}
```
-#### GZip compression
+#### GZip Compression
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.
@@ -647,7 +661,7 @@ This can be changed to something else:
config.assets.prefix = "/some_other_path"
```
-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.
+This is a handy option if you are updating an older project that didn't use the asset pipeline and that already uses this path or you wish to use this path for a new resource.
### X-Sendfile Headers
diff --git a/guides/source/association_basics.md b/guides/source/association_basics.md
index 9bb5aa8bc2..95adb4ff0a 100644
--- a/guides/source/association_basics.md
+++ b/guides/source/association_basics.md
@@ -1,11 +1,13 @@
-A Guide to Active Record Associations
-=====================================
+Active Record Associations
+==========================
-This guide covers the association features of Active Record. By referring to this guide, you will be able to:
+This guide covers the association features of Active Record.
-* Declare associations between Active Record models
-* Understand the various types of Active Record associations
-* Use the methods added to your models by creating associations
+After reading this guide, you will know:
+
+* How to declare associations between Active Record models.
+* How to understand the various types of Active Record associations.
+* How to use the methods added to your models by creating associations.
--------------------------------------------------------------------------------
@@ -450,7 +452,7 @@ class CreateAssemblyPartJoinTable < ActiveRecord::Migration
end
```
-We pass `id: false` to `create_table` because that table does not represent a model. That's required for the association to work properly. If you observe any strange behavior in a `has_and_belongs_to_many` association like mangled models IDs, or exceptions about conflicting IDs chances are you forgot that bit.
+We pass `id: false` to `create_table` because that table does not represent a model. That's required for the association to work properly. If you observe any strange behavior in a `has_and_belongs_to_many` association like mangled models IDs, or exceptions about conflicting IDs, chances are you forgot that bit.
### Controlling Association Scope
diff --git a/guides/source/caching_with_rails.md b/guides/source/caching_with_rails.md
index 826ddd264a..773102400a 100644
--- a/guides/source/caching_with_rails.md
+++ b/guides/source/caching_with_rails.md
@@ -3,12 +3,12 @@ Caching with Rails: An overview
This guide will teach you what you need to know about avoiding that expensive round-trip to your database and returning what you need to return to the web clients in the shortest time possible.
-After reading this guide, you should be able to use and configure:
+After reading this guide, you will know:
-* Page, action, and fragment caching
-* Sweepers
-* Alternative cache stores
-* Conditional GET support
+* Page, action, and fragment caching.
+* Sweepers.
+* Alternative cache stores.
+* Conditional GET support.
--------------------------------------------------------------------------------
@@ -67,8 +67,6 @@ class ProductsController < ActionController
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.
-
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`:
@@ -106,7 +104,7 @@ Let's say you only wanted authenticated users to call actions on `ProductsContro
```ruby
class ProductsController < ActionController
- before_filter :authenticate
+ before_action :authenticate
caches_action :index
def index
@@ -176,102 +174,6 @@ This fragment is then available to all actions in the `ProductsController` using
expire_fragment('all_available_products')
```
-### Sweepers
-
-Cache sweeping is a mechanism which allows you to get around having a ton of `expire_{page,action,fragment}` calls in your code. It does this by moving all the work required to expire cached content into an `ActionController::Caching::Sweeper` subclass. This class is an observer and looks for changes to an Active Record object via callbacks, and when a change occurs it expires the caches associated with that object in an around or after filter.
-
-TIP: Sweepers rely on the use of Active Record and Active Record Observers. The object you are observing must be an Active Record model.
-
-Continuing with our Product controller example, we could rewrite it with a sweeper like this:
-
-```ruby
-class ProductSweeper < ActionController::Caching::Sweeper
- observe Product # This sweeper is going to keep an eye on the Product model
-
- # If our sweeper detects that a Product was created call this
- def after_create(product)
- expire_cache_for(product)
- end
-
- # If our sweeper detects that a Product was updated call this
- def after_update(product)
- expire_cache_for(product)
- end
-
- # If our sweeper detects that a Product was deleted call this
- def after_destroy(product)
- expire_cache_for(product)
- end
-
- private
- def expire_cache_for(product)
- # Expire the index page now that we added a new product
- expire_page(controller: 'products', action: 'index')
-
- # Expire a fragment
- expire_fragment('all_available_products')
- end
-end
-```
-
-You may notice that the actual product gets passed to the sweeper, so if we were caching the edit action for each product, we could add an expire method which specifies the page we want to expire:
-
-```ruby
-expire_action(controller: 'products', action: 'edit', id: product.id)
-```
-
-Then we add it to our controller to tell it to call the sweeper when certain actions are called. So, if we wanted to expire the cached content for the list and edit actions when the create action was called, we could do the following:
-
-```ruby
-class ProductsController < ActionController
-
- before_filter :authenticate
- caches_action :index
- cache_sweeper :product_sweeper
-
- def index
- @products = Product.all
- end
-
-end
-```
-
-Sometimes it is necessary to disambiguate the controller when you call `expire_action`, such as when there are two identically named controllers in separate namespaces:
-
-```ruby
-class ProductsController < ActionController
- caches_action :index
-
- def index
- @products = Product.all
- end
-end
-
-module Admin
- class ProductsController < ActionController
- cache_sweeper :product_sweeper
-
- def new
- @product = Product.new
- end
-
- def create
- @product = Product.create(params[:product])
- end
- end
-end
-
-class ProductSweeper < ActionController::Caching::Sweeper
- observe Product
-
- def after_create(product)
- expire_action(controller: '/products', action: 'index')
- end
-end
-```
-
-Note the use of '/products' here rather than 'products'. If you wanted to expire an action cache for the `Admin::ProductsController`, you would use 'admin/products' instead.
-
### SQL Caching
Query caching is a Rails feature that caches the result set returned by each query so that if Rails encounters the same query again for that request, it will use the cached result set as opposed to running the query against the database again.
diff --git a/guides/source/command_line.md b/guides/source/command_line.md
index 9521212581..746226fa96 100644
--- a/guides/source/command_line.md
+++ b/guides/source/command_line.md
@@ -1,20 +1,20 @@
-A Guide to The Rails Command Line
-=================================
+The Rails Command Line
+======================
Rails comes with every command line tool you'll need to
-* Create a Rails application
-* Generate models, controllers, database migrations, and unit tests
-* Start a development server
-* Experiment with objects through an interactive shell
-* Profile and benchmark your new creation
+After reading this guide, you will know:
+
+* How to create a Rails application.
+* How to generate models, controllers, database migrations, and unit tests.
+* How to start a development server.
+* How to experiment with objects through an interactive shell.
+* How to profile and benchmark your new creation.
--------------------------------------------------------------------------------
NOTE: This tutorial assumes you have basic Rails knowledge from reading the [Getting Started with Rails Guide](getting_started.html).
-WARNING. This Guide is based on Rails 3.2. Some of the code shown here will not work in earlier versions of Rails.
-
Command Line Basics
-------------------
diff --git a/guides/source/configuring.md b/guides/source/configuring.md
index ac763d6e0e..446f767f0c 100644
--- a/guides/source/configuring.md
+++ b/guides/source/configuring.md
@@ -1,10 +1,12 @@
Configuring Rails Applications
==============================
-This guide covers the configuration and initialization features available to Rails applications. By referring to this guide, you will be able to:
+This guide covers the configuration and initialization features available to Rails applications.
-* Adjust the behavior of your Rails applications
-* Add additional code to be run at application start time
+After reading this guide, you will know:
+
+* How to adjust the behavior of your Rails applications.
+* How to add additional code to be run at application start time.
--------------------------------------------------------------------------------
@@ -37,7 +39,7 @@ config.filter_parameters += [:password]
This is a setting for Rails itself. If you want to pass settings to individual Rails components, you can do so via the same `config` object in `config/application.rb`:
```ruby
-config.active_record.observers = [:hotel_observer, :review_observer]
+config.active_record.schema_format = :ruby
```
Rails will use that particular setting to configure Active Record.
@@ -133,8 +135,6 @@ These configuration methods are to be called on a `Rails::Railtie` object, such
### Configuring Assets
-Rails 3.1 and up, 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.
-
* `config.assets.enabled` a flag that controls whether the asset pipeline is enabled. It is explicitly initialized in `config/application.rb`.
* `config.assets.compress` a flag that enables the compression of compiled assets. It is explicitly set to true in `config/production.rb`.
@@ -163,7 +163,7 @@ Rails 3.1 and up, by default, is set up to use the `sprockets` gem to manage ass
### Configuring Generators
-Rails 3 allows you to alter what generators are used with the `config.generators` method. This method takes a block:
+Rails allows you to alter what generators are used with the `config.generators` method. This method takes a block:
```ruby
config.generators do |g|
@@ -614,7 +614,7 @@ Rails.application.config.before_initialize do
end
```
-WARNING: Some parts of your application, notably observers and routing, are not yet set up at the point where the `after_initialize` block is called.
+WARNING: Some parts of your application, notably routing, are not yet set up at the point where the `after_initialize` block is called.
### `Rails::Railtie#initializer`
diff --git a/guides/source/contributing_to_ruby_on_rails.md b/guides/source/contributing_to_ruby_on_rails.md
index feb32eb06f..ce2a5a4902 100644
--- a/guides/source/contributing_to_ruby_on_rails.md
+++ b/guides/source/contributing_to_ruby_on_rails.md
@@ -1,13 +1,15 @@
Contributing to Ruby on Rails
=============================
-This guide covers ways in which _you_ can become a part of the ongoing development of Ruby on Rails. After reading it, you should be familiar with:
+This guide covers ways in which _you_ can become a part of the ongoing development of Ruby on Rails.
-* Using GitHub to report issues
-* Cloning master and running the test suite
-* Helping to resolve existing issues
-* Contributing to the Ruby on Rails documentation
-* Contributing to the Ruby on Rails code
+After reading this guide, you will know:
+
+* How to use GitHub to report issues.
+* How to clone master and run the test suite.
+* How to help resolve existing issues.
+* How to contribute to the Ruby on Rails documentation.
+* How to contribute to the Ruby on Rails code.
Ruby on Rails is not "someone else's framework." Over the years, hundreds of people have contributed to Ruby on Rails ranging from a single character to massive architectural changes or significant documentation — all with the goal of making Ruby on Rails better for everyone. Even if you don't feel up to writing code or documentation yet, there are a variety of other ways that you can contribute, from reporting issues to testing patches.
@@ -89,7 +91,7 @@ You can invoke `test_jdbcmysql`, `test_jdbcsqlite3` or `test_jdbcpostgresql` als
The test suite runs with warnings enabled. Ideally, Ruby on Rails should issue no warnings, but there may be a few, as well as some from third-party libraries. Please ignore (or fix!) them, if any, and submit patches that do not issue new warnings.
-As of this writing (December, 2010) 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:
+As of this writing (December, 2010) they are especially 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:
```bash
$ RUBYOPT=-W0 bundle exec rake test
@@ -203,7 +205,7 @@ TIP: Changes that are cosmetic in nature and do not add anything substantial to
### Follow the Coding Conventions
-Rails follows a simple set of coding style conventions.
+Rails follows a simple set of coding style conventions:
* Two spaces, no tabs (for indentation).
* No trailing whitespace. Blank lines should not have any spaces.
diff --git a/guides/source/debugging_rails_applications.md b/guides/source/debugging_rails_applications.md
index d4415d9b76..addc3a63a8 100644
--- a/guides/source/debugging_rails_applications.md
+++ b/guides/source/debugging_rails_applications.md
@@ -1,12 +1,14 @@
Debugging Rails Applications
============================
-This guide introduces techniques for debugging Ruby on Rails applications. By referring to this guide, you will be able to:
+This guide introduces techniques for debugging Ruby on Rails applications.
-* Understand the purpose of debugging
-* Track down problems and issues in your application that your tests aren't identifying
-* Learn the different ways of debugging
-* Analyze the stack trace
+After reading this guide, you will know:
+
+* The purpose of debugging.
+* How to track down problems and issues in your application that your tests aren't identifying.
+* The different ways of debugging.
+* How to analyze the stack trace.
--------------------------------------------------------------------------------
diff --git a/guides/source/development_dependencies_install.md b/guides/source/development_dependencies_install.md
index 7dfb39fb81..79d59859c8 100644
--- a/guides/source/development_dependencies_install.md
+++ b/guides/source/development_dependencies_install.md
@@ -3,6 +3,8 @@ Development Dependencies Install
This guide covers how to setup an environment for Ruby on Rails core development.
+After reading this guide, you will know:
+
--------------------------------------------------------------------------------
The Easy Way
diff --git a/guides/source/documents.yaml b/guides/source/documents.yaml
index 19425765b8..d7c648681d 100644
--- a/guides/source/documents.yaml
+++ b/guides/source/documents.yaml
@@ -13,9 +13,13 @@
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 Validations
+ url: active_record_validations.html
+ description: This guide covers how you can use Active Record validations
+ -
+ name: Active Record Callbacks
+ url: active_record_callbacks.html
+ description: This guide covers how you can use Active Record callbacks.
-
name: Active Record Associations
url: association_basics.html
diff --git a/guides/source/engines.md b/guides/source/engines.md
index d8f5796dde..116a7e67cd 100644
--- a/guides/source/engines.md
+++ b/guides/source/engines.md
@@ -1,13 +1,15 @@
Getting Started with Engines
============================
-In this guide you will learn about engines and how they can be used to provide additional functionality to their host applications through a clean and very easy-to-use interface. You will learn the following things in this guide:
+In this guide you will learn about engines and how they can be used to provide additional functionality to their host applications through a clean and very easy-to-use interface.
-* What makes an engine
-* How to generate an engine
-* Building features for the engine
-* Hooking the engine into an application
-* Overriding engine functionality in the application
+After reading this guide, you will know:
+
+* What makes an engine.
+* How to generate an engine.
+* Building features for the engine.
+* Hooking the engine into an application.
+* Overriding engine functionality in the application.
--------------------------------------------------------------------------------
@@ -33,7 +35,7 @@ Finally, engines would not have been possible without the work of James Adam, Pi
Generating an engine
--------------------
-To generate an engine with Rails 3.2, you will need to run the plugin generator and pass it options as appropriate to the need. For the "blorgh" example, you will need to create a "mountable" engine, running this command in a terminal:
+To generate an engine, you will need to run the plugin generator and pass it options as appropriate to the need. For the "blorgh" example, you will need to create a "mountable" engine, running this command in a terminal:
```bash
$ rails plugin new blorgh --mountable
diff --git a/guides/source/form_helpers.md b/guides/source/form_helpers.md
index fc317d4773..ee563e72d5 100644
--- a/guides/source/form_helpers.md
+++ b/guides/source/form_helpers.md
@@ -1,17 +1,17 @@
-Rails Form helpers
-==================
+Form Helpers
+============
Forms in web applications are an essential interface for user input. However, form markup can quickly become tedious to write and maintain because of form control naming and their numerous attributes. Rails deals away with these complexities by providing view helpers for generating form markup. However, since they have different use-cases, developers are required to know all the differences between similar helper methods before putting them to use.
-In this guide you will:
+After reading this guide, you will know:
-* Create search forms and similar kind of generic forms not representing any specific model in your application
-* Make model-centric forms for creation and editing of specific database records
-* Generate select boxes from multiple types of data
-* Understand the date and time helpers Rails provides
-* Learn what makes a file upload form different
-* Learn some cases of building forms to external resources
-* Find out how to build complex forms
+* How to create search forms and similar kind of generic forms not representing any specific model in your application.
+* How to make model-centric forms for creation and editing of specific database records.
+* How to generate select boxes from multiple types of data.
+* The date and time helpers Rails provides.
+* What makes a file upload form different.
+* Some cases of building forms to external resources.
+* How to build complex forms.
--------------------------------------------------------------------------------
@@ -594,8 +594,6 @@ The following two forms both upload a file.
<% end %>
```
-NOTE: Since Rails 3.1, forms rendered using `form_for` have their encoding set to `multipart/form-data` automatically once a `file_field` is used inside the block. Previous versions required you to set this explicitly.
-
Rails provides the usual pair of helpers: the barebones `file_field_tag` and the model oriented `file_field`. The only difference with other helpers is that you cannot set a default value for file inputs as this would have no meaning. As you would expect in the first case the uploaded file is in `params[:picture]` and in the second case in `params[:person][:picture]`.
### What Gets Uploaded
diff --git a/guides/source/generators.md b/guides/source/generators.md
index d1ba19e078..62de5a70bb 100644
--- a/guides/source/generators.md
+++ b/guides/source/generators.md
@@ -3,20 +3,18 @@ Creating and Customizing Rails Generators & Templates
Rails generators are an essential tool if you plan to improve your workflow. With this guide you will learn how to create generators and customize existing ones.
-In this guide you will:
+After reading this guide, you will know:
-* Learn how to see which generators are available in your application
-* Create a generator using templates
-* Learn how Rails searches for generators before invoking them
-* Customize your scaffold by creating new generators
-* Customize your scaffold by changing generator templates
-* Learn how to use fallbacks to avoid overwriting a huge set of generators
-* Learn how to create an application template
+* How to see which generators are available in your application.
+* How to create a generator using templates.
+* How Rails searches for generators before invoking them.
+* How to customize your scaffold by creating new generators.
+* How to customize your scaffold by changing generator templates.
+* How to use fallbacks to avoid overwriting a huge set of generators.
+* How to create an application template.
--------------------------------------------------------------------------------
-NOTE: This guide is about generators in Rails 3, previous versions are not covered.
-
First Contact
-------------
diff --git a/guides/source/getting_started.md b/guides/source/getting_started.md
index 76556761f7..54200768e6 100644
--- a/guides/source/getting_started.md
+++ b/guides/source/getting_started.md
@@ -1,10 +1,11 @@
Getting Started with Rails
==========================
-This guide covers getting up and running with Ruby on Rails. After reading it,
-you should be familiar with:
+This guide covers getting up and running with Ruby on Rails.
-* Installing Rails, creating a new Rails application, and connecting your
+After reading this guide, you will know:
+
+* How to install Rails, create a new Rails application, and connect your
application to a database.
* The general layout of a Rails application.
* The basic principles of MVC (Model, View, Controller) and RESTful design.
@@ -12,9 +13,6 @@ you should be familiar with:
--------------------------------------------------------------------------------
-WARNING. This Guide is based on Rails 3.2. Some of the code shown here will not
-work in earlier versions of Rails.
-
Guide Assumptions
-----------------
@@ -24,7 +22,7 @@ with Rails. However, to get the most out of it, you need to have some
prerequisites installed:
* The [Ruby](http://www.ruby-lang.org/en/downloads) language version 1.9.3 or higher
-* The [RubyGems](http://rubyforge.org/frs/?group_id=126) packaging system
+* The [RubyGems](http://rubygems.org/) packaging system
* To learn more about RubyGems, please read the [RubyGems User Guide](http://docs.rubygems.org/read/book/1)
* A working installation of the [SQLite3 Database](http://www.sqlite.org)
@@ -77,11 +75,14 @@ TIP: The examples below use # and $ to denote superuser and regular user termina
### Installing Rails
-Open up a command line prompt. On a mac this is called terminal, on windows it is called command prompt. Any commands prefaced with a dollar sign `$` should be run in the command line. Verify sure you have a current version of Ruby installed:
+Open up a command line prompt. On Mac OS X open Terminal.app, on Windows choose
+"Run" from your Start menu and type 'cmd.exe'. Any commands prefaced with a
+dollar sign `$` should be run in the command line. Verify that you have a
+current version of Ruby installed:
```bash
$ ruby -v
-ruby 1.9.3p194
+ruby 1.9.3p327
```
To install Rails, use the `gem install` command provided by RubyGems:
@@ -100,11 +101,11 @@ To verify that you have everything installed correctly, you should be able to ru
$ rails --version
```
-If it says something like "Rails 3.2.8" you are ready to continue.
+If it says something like "Rails 3.2.9", you are ready to continue.
### Creating the Blog Application
-Rails comes with a number of generators that are designed to make your development life easier. One of these is the new application generator, which will provide you with the foundation of a Rails application so that you don't have to write it yourself.
+Rails comes with a number of scripts called generators that are designed to make your development life easier by creating everything that's necessary to start working on a particular task. One of these is the new application generator, which will provide you with the foundation of a fresh Rails application so that you don't have to write it yourself.
To use this generator, open a terminal, navigate to a directory where you have rights to create files, and type:
@@ -165,7 +166,7 @@ This will fire up WEBrick, a webserver built into Ruby by default. To see your a
![Welcome Aboard screenshot](images/rails_welcome.png)
-TIP: To stop the web server, hit Ctrl+C in the terminal window where it's running. To verify the server has stopped you should see your command prompt cursor again. For most unix like systems including mac this will be a dollar sign `$`. In development mode, Rails does not generally require you to restart the server; changes you make in files will be automatically picked up by the server.
+TIP: To stop the web server, hit Ctrl+C in the terminal window where it's running. To verify the server has stopped you should see your command prompt cursor again. For most UNIX-like systems including Mac OS X this will be a dollar sign `$`. In development mode, Rails does not generally require you to restart the server; changes you make in files will be automatically picked up by the server.
The "Welcome Aboard" page is the _smoke test_ for a new Rails application: it makes sure that you have your software configured correctly enough to serve a page. You can also click on the _About your application’s environment_ link to see a summary of your application's environment.
@@ -519,7 +520,7 @@ invoking the command: `rake db:migrate RAILS_ENV=production`.
### Saving data in the controller
Back in `posts_controller`, we need to change the `create` action
-to use the new `Post` model to save the data in the database. Open that file
+to use the new `Post` model to save the data in the database. Open `app/controllers/posts_controller.rb`
and change the `create` action to look like this:
```ruby
@@ -557,8 +558,8 @@ parameter, which in our case will be the id of the post. Note that this
time we had to specify the actual mapping, `posts#show` because
otherwise Rails would not know which action to render.
-As we did before, we need to add the `show` action in the
-`posts_controller` and its respective view.
+As we did before, we need to add the `show` action in
+`app/controllers/posts_controller.rb` and its respective view.
```ruby
def show
@@ -702,19 +703,6 @@ your Rails models for free, including basic database CRUD (Create, Read, Update,
Destroy) operations, data validation, as well as sophisticated search support
and the ability to relate multiple models to one another.
-Rails includes methods to help you secure some of your model fields.
-Open the `app/models/post.rb` file and edit it:
-
-```ruby
-class Post < ActiveRecord::Base
- attr_accessible :text, :title
-end
-```
-
-This change will ensure that all changes made through HTML forms can edit the content of the text and title fields.
-It will not be possible to define any other field value through forms. You can still define them by calling the `field=` method of course.
-Accessible attributes and the mass assignment problem is covered in details in the [Security guide](security.html#mass-assignment)
-
### Adding Some Validation
Rails includes methods to help you validate the data that you send to models.
@@ -722,8 +710,6 @@ Open the `app/models/post.rb` file and edit it:
```ruby
class Post < ActiveRecord::Base
- attr_accessible :text, :title
-
validates :title, presence: true,
length: { minimum: 5 }
end
@@ -960,35 +946,14 @@ And here's how our app looks so far:
### Using partials to clean up duplication in views
-`partials` are what Rails uses to remove duplication in views. Here's a
-simple example:
-
-```html+erb
-# app/views/user/show.html.erb
-
-<h1><%= @user.name %></h1>
-
-<%= render 'user_details' %>
-
-# app/views/user/_user_details.html.erb
-
-<%= @user.location %>
-
-<%= @user.about_me %>
-```
-
-The `users/show` template will automatically include the content of the
-`users/_user_details` template. Note that partials are prefixed by an underscore,
-as to not be confused with regular views. However, you don't include the
-underscore when including them with the `helper` method.
+Our `edit` page looks very similar to the `new` page, in fact they
+both share the same code for displaying the form. Let's remove some duplication
+by using a view partial. By convention, partial files are prefixed by an
+underscore.
TIP: You can read more about partials in the
[Layouts and Rendering in Rails](layouts_and_rendering.html) guide.
-Our `edit` action looks very similar to the `new` action, in fact they
-both share the same code for displaying the form. Let's clean them up by
-using a partial.
-
Create a new file `app/views/posts/_form.html.erb` with the following
content:
@@ -1150,7 +1115,8 @@ together.
<td><%= post.text %></td>
<td><%= link_to 'Show', action: :show, id: post.id %></td>
<td><%= link_to 'Edit', action: :edit, id: post.id %></td>
- <td><%= link_to 'Destroy', { action: :destroy, id: post.id }, method: :delete, data: { confirm: 'Are you sure?' } %></td>
+ <td><%= link_to 'Destroy', { action: :destroy, id: post.id },
+ method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
</table>
@@ -1250,12 +1216,11 @@ This command will generate four files:
| test/models/comment_test.rb | Testing harness for the comments model |
| test/fixtures/comments.yml | Sample comments for use in testing |
-First, take a look at `comment.rb`:
+First, take a look at `app/models/comment.rb`:
```ruby
class Comment < ActiveRecord::Base
belongs_to :post
- attr_accessible :body, :commenter
end
```
@@ -1312,7 +1277,7 @@ this way:
* One post can have many comments.
In fact, this is very close to the syntax that Rails uses to declare this
-association. You've already seen the line of code inside the Comment model that
+association. You've already seen the line of code inside the `Comment` model (app/models/comment.rb) that
makes each comment belong to a Post:
```ruby
@@ -1321,14 +1286,14 @@ class Comment < ActiveRecord::Base
end
```
-You'll need to edit the `post.rb` file to add the other side of the association:
+You'll need to edit `app/models/post.rb` to add the other side of the association:
```ruby
class Post < ActiveRecord::Base
+ has_many :comments
validates :title, presence: true,
length: { minimum: 5 }
-
- has_many :comments
+ [...]
end
```
@@ -1385,7 +1350,7 @@ the post show page to see their comment now listed. Due to this, our
spam comments when they arrive.
So first, we'll wire up the Post show template
-(`/app/views/posts/show.html.erb`) to let us make a new comment:
+(`app/views/posts/show.html.erb`) to let us make a new comment:
```html+erb
<p>
@@ -1428,7 +1393,7 @@ class CommentsController < ApplicationController
def create
@post = Post.find(params[:post_id])
@comment = @post.comments.create(params[:comment])
- redirect_to post_url(@post)
+ redirect_to post_path(@post)
end
end
```
@@ -1644,7 +1609,7 @@ So first, let's add the delete link in the
Clicking this new "Destroy Comment" link will fire off a `DELETE
/posts/:post_id/comments/:id` to our `CommentsController`, which can then use
this to find the comment we want to delete, so let's add a destroy action to our
-controller:
+controller (`app/controllers/comments_controller.rb`):
```ruby
class CommentsController < ApplicationController
@@ -1679,9 +1644,10 @@ model, `app/models/post.rb`, as follows:
```ruby
class Post < ActiveRecord::Base
+ has_many :comments, dependent: :destroy
validates :title, presence: true,
length: { minimum: 5 }
- has_many :comments, dependent: :destroy
+ [...]
end
```
@@ -1701,7 +1667,7 @@ action if that method allows it.
To use the authentication system, we specify it at the top of our
`PostsController`, in this case, we want the user to be authenticated on every
-action, except for `index` and `show`, so we write that:
+action, except for `index` and `show`, so we write that in `app/controllers/posts_controller.rb`:
```ruby
class PostsController < ApplicationController
@@ -1716,7 +1682,7 @@ class PostsController < ApplicationController
```
We also only want to allow authenticated users to delete comments, so in the
-`CommentsController` we write:
+`CommentsController` (`app/controllers/comments_controller.rb`) we write:
```ruby
class CommentsController < ApplicationController
diff --git a/guides/source/i18n.md b/guides/source/i18n.md
index 5ffd955f66..399a4963d7 100644
--- a/guides/source/i18n.md
+++ b/guides/source/i18n.md
@@ -7,18 +7,20 @@ The process of "internationalization" usually means to abstract all strings and
So, in the process of _internationalizing_ your Rails application you have to:
-* Ensure you have support for i18n
-* Tell Rails where to find locale dictionaries
-* Tell Rails how to set, preserve and switch locales
+* Ensure you have support for i18n.
+* Tell Rails where to find locale dictionaries.
+* Tell Rails how to set, preserve and switch locales.
In the process of _localizing_ your application you'll probably want to do the following three things:
* Replace or supplement Rails' default locale — e.g. date and time formats, month names, Active Record model names, etc.
* Abstract strings in your application into keyed dictionaries — e.g. flash messages, static text in your views, etc.
-* Store the resulting dictionaries somewhere
+* Store the resulting dictionaries somewhere.
This guide will walk you through the I18n API and contains a tutorial on how to internationalize a Rails application from the start.
+After reading this guide, you will know:
+
--------------------------------------------------------------------------------
NOTE: The Ruby I18n framework provides you with all necessary means for internationalization/localization of your Rails application. You may, however, use any of various plugins and extensions available, which add additional functionality or features. See the Rails [I18n Wiki](http://rails-i18n.org/wiki) for more information.
@@ -132,10 +134,10 @@ However, you would probably like to **provide support for more locales** in your
WARNING: You may be tempted to store the chosen locale in a _session_ or a <em>cookie</em>, however **do not do this**. The locale should be transparent and a part of the URL. This way you won't break people's basic assumptions about the web itself: if you send a URL to a friend, they should see the same page and content as you. A fancy word for this would be that you're being [<em>RESTful</em>](http://en.wikipedia.org/wiki/Representational_State_Transfer. Read more about the RESTful approach in [Stefan Tilkov's articles](http://www.infoq.com/articles/rest-introduction). Sometimes there are exceptions to this rule and those are discussed below.
-The _setting part_ is easy. You can set the locale in a `before_filter` in the `ApplicationController` like this:
+The _setting part_ is easy. You can set the locale in a `before_action` in the `ApplicationController` like this:
```ruby
-before_filter :set_locale
+before_action :set_locale
def set_locale
I18n.locale = params[:locale] || I18n.default_locale
@@ -158,7 +160,7 @@ One option you have is to set the locale from the domain name where your applica
You can implement it like this in your `ApplicationController`:
```ruby
-before_filter :set_locale
+before_action :set_locale
def set_locale
I18n.locale = extract_locale_from_tld || I18n.default_locale
@@ -201,7 +203,7 @@ This solution has aforementioned advantages, however, you may not be able or may
### Setting the Locale from the URL Params
-The most usual way of setting (and passing) the locale would be to include it in URL params, as we did in the `I18n.locale = params[:locale]` _before_filter_ in the first example. We would like to have URLs like `www.example.com/books?locale=ja` or `www.example.com/ja/books` in this case.
+The most usual way of setting (and passing) the locale would be to include it in URL params, as we did in the `I18n.locale = params[:locale]` _before_action_ in the first example. We would like to have URLs like `www.example.com/books?locale=ja` or `www.example.com/ja/books` in this case.
This approach has almost the same set of advantages as setting the locale from the domain name: namely that it's RESTful and in accord with the rest of the World Wide Web. It does require a little bit more work to implement, though.
@@ -694,7 +696,7 @@ en:
long: "%B %d, %Y"
```
-So, all of the following equivalent lookups will return the `:short` date format `"%B %d"`:
+So, all of the following equivalent lookups will return the `:short` date format `"%b %d"`:
```ruby
I18n.t 'date.formats.short'
diff --git a/guides/source/initialization.md b/guides/source/initialization.md
index 393bf51863..32df508f9c 100644
--- a/guides/source/initialization.md
+++ b/guides/source/initialization.md
@@ -4,7 +4,9 @@ The Rails Initialization Process
This guide explains the internals of the initialization process in Rails
as of Rails 4. It is an extremely in-depth guide and recommended for advanced Rails developers.
-* Using `rails server`
+After reading this guide, you will know:
+
+* How to use `rails server`.
--------------------------------------------------------------------------------
diff --git a/guides/source/layouts_and_rendering.md b/guides/source/layouts_and_rendering.md
index 141876b5a3..dbaa3ec576 100644
--- a/guides/source/layouts_and_rendering.md
+++ b/guides/source/layouts_and_rendering.md
@@ -3,10 +3,12 @@ Layouts and Rendering in Rails
This guide covers the basic layout features of Action Controller and Action View. By referring to this guide, you will be able to:
-* Use the various rendering methods built into Rails
-* Create layouts with multiple content sections
-* Use partials to DRY up your views
-* Use nested layouts (sub-templates)
+After reading this guide, you will know:
+
+* How to use the various rendering methods built into Rails.
+* How to create layouts with multiple content sections.
+* How to use partials to DRY up your views.
+* How to use nested layouts (sub-templates).
--------------------------------------------------------------------------------
@@ -158,21 +160,6 @@ def update
end
```
-To be explicit, you can use `render` with the `:action` option (though this is no longer necessary in Rails 3.0):
-
-```ruby
-def update
- @book = Book.find(params[:id])
- if @book.update_attributes(params[:book])
- redirect_to(@book)
- else
- render action: "edit"
- end
-end
-```
-
-WARNING: Using `render` with `:action` is a frequent source of confusion for Rails newcomers. The specified action is used to determine which view to render, but Rails does _not_ run any of the code for that action in the controller. Any instance variables that you require in the view must be set up in the current action before calling `render`.
-
#### Rendering an Action's Template from Another Controller
What if you want to render a template from an entirely different controller from the one that contains the action code? You can also do that with `render`, which accepts the full path (relative to `app/views`) of the template to render. For example, if you're running code in an `AdminProductsController` that lives in `app/controllers/admin`, you can render the results of an action to a template in `app/views/products` this way:
@@ -672,7 +659,7 @@ There are three tag options available for the `auto_discovery_link_tag`:
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.
+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 asset pipeline.
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)
@@ -841,7 +828,7 @@ You can even use dynamic paths such as `cache/#{current_site}/main/display`.
The `image_tag` helper builds an HTML `<img />` tag to the specified file. By default, files are loaded from `public/images`.
-WARNING: Note that you must specify the extension of the image. Previous versions of Rails would allow you to just use the image name and would append `.png` if no extension was given but Rails 3.0 does not.
+WARNING: Note that you must specify the extension of the image.
```erb
<%= image_tag "header.png" %>
@@ -1089,8 +1076,6 @@ Every partial also has a local variable with the same name as the partial (minus
Within the `customer` partial, the `customer` variable will refer to `@new_customer` from the parent view.
-WARNING: In previous versions of Rails, the default local variable would look for an instance variable with the same name as the partial in the parent. This behavior was deprecated in 2.3 and has been removed in Rails 3.0.
-
If you have an instance of a model to render into a partial, you can use a shorthand syntax:
```erb
@@ -1118,7 +1103,7 @@ Partials are very useful in rendering collections. When you pass a collection to
When a partial is called with a pluralized collection, then the individual instances of the partial have access to the member of the collection being rendered via a variable named after the partial. In this case, the partial is `_product`, and within the `_product` partial, you can refer to `product` to get the instance that is being rendered.
-In Rails 3.0, there is also a shorthand for this. Assuming `@products` is a collection of `product` instances, you can simply write this in the `index.html.erb` to produce the same result:
+There is also a shorthand for this. Assuming `@products` is a collection of `product` instances, you can simply write this in the `index.html.erb` to produce the same result:
```html+erb
<h1>Products</h1>
diff --git a/guides/source/migrations.md b/guides/source/migrations.md
index a1131f1f79..9840e7694f 100644
--- a/guides/source/migrations.md
+++ b/guides/source/migrations.md
@@ -1,41 +1,39 @@
-Migrations
-==========
+Active Record 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.
+Migrations are a feature of Active Record that allows you to evolve your
+database schema over time. Rather than write schema modifications in pure SQL,
+migrations allow you to use an easy Ruby DSL to describe changes to your
+tables.
-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. Active Record will also update your `db/schema.rb` file to match the up-to-date structure of your database.
+After reading this guide, you will know:
-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.
+* The generators you can use to create them.
+* The methods Active Record provides to manipulate your database.
+* The Rake tasks that manipulate migrations and your schema.
+* How migrations relate to `schema.rb`.
-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
-* The Rake tasks that manipulate them
-* How they relate to `schema.rb`
+Migration Overview
+------------------
---------------------------------------------------------------------------------
+Migrations are a convenient way to alter your database schema over time in a
+consistent and easy way. They use a Ruby DSL so that you don't have to write
+SQL by hand, allowing your schema and changes to be database independent.
-Anatomy of a Migration
-----------------------
+You can think of each migration as being a new 'version' of the database. A
+schema starts off with nothing in it, and each migration modifies it to add or
+remove tables, columns, or entries. Active Record knows how to update your
+schema along this timeline, bringing it from whatever point it is in the
+history to the latest version. Active Record will also update your
+`db/schema.rb` file to match the up-to-date structure of your database.
-Before we dive into the details of a migration, here are a few examples of the
-sorts of things you can do:
+Here's an example of a migration:
```ruby
class CreateProducts < ActiveRecord::Migration
- def up
+ def change
create_table :products do |t|
t.string :name
t.text :description
@@ -43,102 +41,49 @@ class CreateProducts < ActiveRecord::Migration
t.timestamps
end
end
-
- def down
- drop_table :products
- end
end
```
-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 explicitly specify it.
-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 implicitly, as it's the default primary key for all Active
+Record models. The `timestamps` macro adds two columns, `created_at` and
+`updated_at`. These special columns are automatically managed by Active Record
+if they exist.
-Migrations are not limited to changing the schema. You can also use them to fix
-bad data in the database or populate new fields:
+Note that we define the change that we want to happen moving forward in time.
+Before this migration is run, there will be no table. After, the table will
+exist. Active Record knows how to reverse this migration as well: if we roll
+this migration back, it will remove the table.
+
+On databases that support transactions with statements that change the schema ,
+migrations are wrapped in a transaction. If the database does not support this
+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.
+
+If you wish for a migration to do something that Active Record doesn't know how
+to reverse, you can use `up` and `down` instead of `change`:
```ruby
-class AddReceiveNewsletterToUsers < ActiveRecord::Migration
+class ChangeProductsPrice < ActiveRecord::Migration
def up
- change_table :users do |t|
- t.boolean :receive_newsletter, default: false
+ change_table :products do |t|
+ t.string :price, null: false
end
- User.update_all receive_newsletter: true
end
-
+
def down
- remove_column :users, :receive_newsletter
- end
-end
-```
-
-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.
-
-### Using the change method
-
-Rails 3.1 and up makes migrations smarter by providing a `change` 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
- def change
- create_table :products do |t|
- t.string :name
- t.text :description
-
- t.timestamps
+ change_table :products do |t|
+ t.integer :price, null: false
end
end
end
```
-### Migrations are Classes
-
-A migration is a subclass of `ActiveRecord::Migration` 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):
-
-* `add_column`
-* `add_reference`
-* `add_index`
-* `change_column`
-* `change_table`
-* `create_table`
-* `create_join_table`
-* `drop_table`
-* `remove_column`
-* `remove_index`
-* `rename_column`
-* `remove_reference`
-
-If you need to perform tasks specific to your database (e.g., 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 rollback
-the changes that were made by hand.
+Creating a Migration
+--------------------
-### What's in a Name
+### Creating a Standalone Migration
Migrations are stored as files in the `db/migrate` directory, one for each
migration class. The name of the file is of the form
@@ -148,119 +93,10 @@ 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
-```
-
-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. 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.
-
-### 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.
-
-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.
-
-### Supported Types
-
-Active Record supports the following database column types:
-
-* `:binary`
-* `:boolean`
-* `:date`
-* `:datetime`
-* `:decimal`
-* `:float`
-* `:integer`
-* `:primary_key`
-* `:string`
-* `:text`
-* `:time`
-* `: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 such as
-
-```ruby
-create_table :products do |t|
- t.column :name, 'polygon', null: false
-end
-```
-
-This may however hinder portability to other databases.
-
-Creating a Migration
---------------------
+`AddDetailsToProducts`.
-### 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
-
-```bash
-$ rails generate model Product name:string description:text
-```
-
-TIP: All lines starting with a dollar sign `$` are intended to be run on the command line.
-
-will create a migration that looks like this
-
-```ruby
-class CreateProducts < ActiveRecord::Migration
- def change
- create_table :products do |t|
- t.string :name
- t.text :description
-
- t.timestamps
- end
- end
-end
-```
-
-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).
-
-### Creating a Standalone Migration
-
-If you are creating migrations for other purposes (e.g., to add a column
-to an existing table) then you can also use the migration generator:
+Of course, calculating timestamps is no fun, so Active Record provides a
+generator to handle making it for you:
```bash
$ rails generate migration AddPartNumberToProducts
@@ -335,10 +171,11 @@ 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 needs to know
-the original data types defined when you made the original changes.
+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.
-Also, the generator accepts column type as `references`(also available as `belongs_to`). For instance
+Also, the generator accepts column type as `references`(also available as
+`belongs_to`). For instance
```bash
$ rails generate migration AddUserRefToProducts user:references
@@ -354,12 +191,40 @@ class AddUserRefToProducts < ActiveRecord::Migration
end
```
-This migration will create a user_id column and appropriate index.
+This migration will create a `user_id` column and appropriate index.
+
+### Model Generators
+
+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
+
+```bash
+$ rails generate model Product name:string description:text
+```
+
+will create a migration that looks like this
+
+```ruby
+class CreateProducts < ActiveRecord::Migration
+ def change
+ create_table :products do |t|
+ t.string :name
+ t.text :description
+
+ t.timestamps
+ end
+ end
+end
+```
+
+You can append as many column name/type pairs as you want.
### Supported Type Modifiers
-You can also specify some options just after the field type between curly braces. You can use the
-following modifiers:
+You can also specify some options just after the field type between curly
+braces. You can use the following modifiers:
* `limit` Sets the maximum size of the `string/text/binary/integer` fields
* `precision` Defines the precision for the `decimal` fields
@@ -391,8 +256,9 @@ get to work!
### Creating a Table
-Migration method `create_table` will be one of your workhorses. A typical use
-would be
+The `create_table` method is one of the most fundamental, but most of the time,
+will be generated for you from using a model or scaffold generator. A typical
+use would be
```ruby
create_table :products do |t|
@@ -403,31 +269,11 @@ end
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
-
-```ruby
-create_table :products do |t|
- t.column :name, :string, null: false
-end
-```
-
-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|
- t.string :name, null: false
-end
-```
-
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,
+update the corresponding model) or, if you don't want a primary key at all, 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|
@@ -447,10 +293,12 @@ would be
create_join_table :products, :categories
```
-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.
+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,
+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
@@ -458,20 +306,21 @@ create_join_table :products, :categories, table_name: :categorization
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,
+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}
```
-will create the `product_id` and `category_id` with the `:null` option as `true`.
+will create the `product_id` and `category_id` with the `:null` option as
+`true`.
### 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
+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|
@@ -485,67 +334,15 @@ end
removes the `description` and `name` columns, creates a `part_number` string
column and adds an index on it. Finally it renames the `upccode` column.
-### 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:
-
-```ruby
-create_table :products do |t|
- t.timestamps
-end
-```
-
-will create a new products table with those two columns (plus the `id` column)
-whereas
-
-```ruby
-change_table :products do |t|
- t.timestamps
-end
-```
-adds those columns to an existing table.
-
-Another helper is called `references` (also available as `belongs_to`). In its
-simplest form it just adds some readability.
+### When Helpers aren't Enough
-```ruby
-create_table :products do |t|
- t.references :category
-end
-```
-
-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
-```
-
-will add an `attachment_id` column and a string `attachment_type` column with
-a default value of 'Photo'. `references` also allows you to define an
-index directly, instead of using `add_index` after the `create_table` call:
+If the helpers provided by Active Record aren't enough you can use the `execute`
+method to execute arbitrary SQL:
```ruby
-create_table :products do |t|
- t.references :category, index: true
-end
+Products.connection.execute('UPDATE `products` SET `price`=`free` WHERE 1')
```
-will create an index identical to calling `add_index :products, :category_id`.
-
-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).
-
-If the helpers provided by Active Record aren't enough you can use the `execute`
-method to execute arbitrary SQL.
-
For more details and examples of individual methods, check the API documentation.
In particular the documentation for
[`ActiveRecord::ConnectionAdapters::SchemaStatements`](http://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/SchemaStatements.html)
@@ -558,9 +355,10 @@ and
### Using the `change` Method
-The `change` method removes the need to write both `up` and `down` methods in
-those cases that Rails knows how to revert the changes automatically. Currently,
-the `change` method supports only these migration definitions:
+The `change` method is the primary way of writing migrations. It works for the
+majority of cases, where Active Record knows how to reverse the migration
+automatically. Currently, the `change` method supports only these migration
+definitions:
* `add_column`
* `add_index`
@@ -576,12 +374,13 @@ If you're going to need to use any other methods, you'll have to write the
### 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 `up` method should describe the transformation you'd like to make to your
+schema, and 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
@@ -589,6 +388,7 @@ class ExampleMigration < ActiveRecord::Migration
create_table :products do |t|
t.references :category
end
+
#add a foreign key
execute <<-SQL
ALTER TABLE products
@@ -596,6 +396,7 @@ 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
@@ -603,10 +404,12 @@ class ExampleMigration < ActiveRecord::Migration
def down
rename_column :users, :email_address, :email
remove_column :users, :home_page_url
+
execute <<-SQL
ALTER TABLE products
DROP FOREIGN KEY fk_products_categories
SQL
+
drop_table :products
end
end
@@ -621,17 +424,16 @@ can't be done.
Running Migrations
------------------
-Rails provides a set of rake tasks to work with migrations which boil down to
-running certain sets of migrations.
+Rails provides a set of Rake tasks to run certain sets of migrations.
-The very first migration related rake task you will use will probably be
+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.
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.
+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
@@ -684,9 +486,10 @@ version to migrate to.
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. It will only use the contents
-of the current schema.rb file. If a migration can't be rolled back, 'rake db:reset'
-may not help you. To find out more about dumping the schema see [schema.rb](#schema-dumping-and-you).
+NOTE: This is not the same as running all the migrations. It will only use the
+contents of the current schema.rb file. If a migration can't be rolled back,
+'rake db:reset' may not help you. To find out more about dumping the schema see
+'[schema dumping and you](#schema-dumping-and-you).'
### Running Specific Migrations
@@ -699,13 +502,16 @@ example,
$ rake db:migrate:up VERSION=20080906120000
```
-will run the `up` method from the 20080906120000 migration. This task will first
-check whether the migration is already performed and will do nothing if Active Record believes
-that it has already been run.
+will run the `up` method from the 20080906120000 migration. This task will
+first check whether the migration is already performed and will do nothing if
+Active Record believes that it has already been run.
### Running Migrations in Different Environments
-By default running `rake db:migrate` will run in the `development` environment. To run migrations against another environment you can specify it using the `RAILS_ENV` environment variable while running the command. For example to run migrations against the `test` environment you could run:
+By default running `rake db:migrate` will run in the `development` environment.
+To run migrations against another environment you can specify it using the
+`RAILS_ENV` environment variable while running the command. For example to run
+migrations against the `test` environment you could run:
```bash
$ rake db:migrate RAILS_ENV=test
@@ -743,9 +549,12 @@ class CreateProducts < ActiveRecord::Migration
t.timestamps
end
end
+
say "Created a table"
+
suppress_messages {add_index :products, :name}
say "and an index!", true
+
say_with_time 'Waiting for a while' do
sleep 10
250
@@ -769,11 +578,29 @@ generates the following output
If you want Active Record to not output anything, then running `rake db:migrate
VERBOSE=false` will suppress all output.
+Changing Existing 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.
+
+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.
+
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
+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)
@@ -786,7 +613,7 @@ 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
+initializes it. She also adds a validation to the `Product` model for the new
column.
```ruby
@@ -835,8 +662,8 @@ Both migrations work for Alice.
Bob comes back from vacation and:
-* Updates the source - which contains both migrations and the latest version of
- the Product model.
+* Updates the source - which contains both migrations and the latest version
+ of the Product model.
* Runs outstanding migrations with `rake db:migrate`, which
includes the one that updates the `Product` model.
@@ -851,10 +678,10 @@ An error has occurred, this and all later migrations canceled:
undefined method `fuzz' for #<Product:0x000001049b14a0>
```
-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
+When using a local 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.
@@ -893,20 +720,20 @@ end
There are other ways in which the above example could have gone badly.
For example, imagine that Alice creates a migration that selectively
-updates the +description+ field on certain products. She runs the
+updates the `description` field on certain products. She runs the
migration, commits the code, and then begins working on the next feature,
-which is to add a new column +fuzz+ to the products table.
+which is to add a new column `fuzz` to the products table.
She creates two migrations for this new feature, one which adds the new
-column, and a second which selectively updates the +fuzz+ column based on
+column, and a second which selectively updates the `fuzz` column based on
other product attributes.
These migrations run just fine, but when Bob comes back from his vacation
and calls `rake db:migrate` to run all the outstanding migrations, he gets a
-subtle bug: The descriptions have defaults, and the +fuzz+ column is present,
-but +fuzz+ is nil on all products.
+subtle bug: The descriptions have defaults, and the `fuzz` column is present,
+but `fuzz` is nil on all products.
-The solution is again to use +Product.reset_column_information+ before
+The solution is again to use `Product.reset_column_information` before
referencing the Product model in a migration, ensuring the Active Record's
knowledge of the table structure is current before manipulating data in those
records.
@@ -939,12 +766,13 @@ you desire that functionality.
### 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:
+at this file you'll find that it looks an awful lot like one very big
+migration:
```ruby
ActiveRecord::Schema.define(version: 20080906171750) do
@@ -967,8 +795,8 @@ end
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.
+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
@@ -976,11 +804,11 @@ 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.
+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 PostgreSQL, 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
@@ -1001,14 +829,47 @@ 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`).
+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`).
+
+Migrations and Seed Data
+------------------------
+
+Some people use migrations to add data to the database:
+
+```ruby
+class AddInitialProducts < ActiveRecord::Migration
+ def up
+ 5.times do |i|
+ Product.create(name: "Product ##{i}", description: "A product.")
+ end
+ end
+
+ def down
+ Product.delete_all
+ end
+end
+```
+
+However, Rails has a 'seeds' feature that should be used for seeding a database
+with initial data. It's a really simple feature: just fill up `db/seeds.rb`
+with some Ruby code, and run `rake db:seed`:
+
+```ruby
+5.times do |i|
+ Product.create(name: "Product ##{i}", description: "A product.")
+end
+```
+
+This is generally a much cleaner way to set up the database of a blank
+application.
diff --git a/guides/source/nested_model_forms.md b/guides/source/nested_model_forms.md
index b5f112e6c9..2b46a9d51e 100644
--- a/guides/source/nested_model_forms.md
+++ b/guides/source/nested_model_forms.md
@@ -3,9 +3,9 @@ Rails nested model forms
Creating a form for a model _and_ its associations can become quite tedious. Therefore Rails provides helpers to assist in dealing with the complexities of generating these forms _and_ the required CRUD operations to create, update, and destroy associations.
-In this guide you will:
+After reading this guide, you will know:
-* do stuff
+* do stuff.
--------------------------------------------------------------------------------
diff --git a/guides/source/performance_testing.md b/guides/source/performance_testing.md
index 248a9643c8..182f7eb0fd 100644
--- a/guides/source/performance_testing.md
+++ b/guides/source/performance_testing.md
@@ -2,14 +2,16 @@ Performance Testing Rails Applications
======================================
This guide covers the various ways of performance testing a Ruby on Rails
-application. By referring to this guide, you will be able to:
+application.
+
+After reading this guide, you will know:
-* Understand the various types of benchmarking and profiling metrics.
-* Generate performance and benchmarking tests.
-* Install and use a GC-patched Ruby binary to measure memory usage and object
+* The various types of benchmarking and profiling metrics.
+* How to generate performance and benchmarking tests.
+* How to install and use a GC-patched Ruby binary to measure memory usage and object
allocation.
-* Understand the benchmarking information provided by Rails inside the log files.
-* Learn about various tools facilitating benchmarking and profiling.
+* The benchmarking information provided by Rails inside the log files.
+* Various tools facilitating benchmarking and profiling.
Performance testing is an integral part of the development cycle. It is very
important that you don't make your end users wait for too long before the page
@@ -557,9 +559,9 @@ Usage: rails profiler 'Ruby.code' 'Ruby.more_code' ... [OPTS]
Default: 1
-o, --output PATH Directory to use when writing the results.
Default: tmp/performance
- --metrics a,b,c Metrics to use.
+ -m, --metrics a,b,c Metrics to use.
Default: process_time,memory,objects
- -m, --formats x,y,z Formats to output to.
+ -f, --formats x,y,z Formats to output to.
Default: flat,graph_html,call_tree
```
diff --git a/guides/source/plugins.md b/guides/source/plugins.md
index c657281741..f8f04c3c67 100644
--- a/guides/source/plugins.md
+++ b/guides/source/plugins.md
@@ -7,15 +7,15 @@ A Rails plugin is either an extension or a modification of the core framework. P
* a segmented architecture so that units of code can be fixed or updated on their own release schedule
* an outlet for the core developers so that they don’t have to include every cool new feature under the sun
-After reading this guide you should be familiar with:
+After reading this guide, you will know:
-* Creating a plugin from scratch
-* Writing and running tests for the plugin
+* How to create a plugin from scratch.
+* How to write and run tests for the plugin.
This guide describes how to build a test-driven plugin that will:
-* Extend core Ruby classes like Hash and String
-* Add methods to ActiveRecord::Base in the tradition of the 'acts_as' plugins
+* Extend core Ruby classes like Hash and String.
+* Add methods to ActiveRecord::Base in the tradition of the 'acts_as' plugins.
* Give you information about where to put generators in your plugin.
For the purpose of this guide pretend for a moment that you are an avid bird watcher.
@@ -27,16 +27,13 @@ goodness.
Setup
-----
-_"vendored plugins"_ were available in previous versions of Rails, but they are deprecated in
-Rails 3.2, and will not be available in the future.
-
Currently, Rails plugins are built as gems, _gemified plugins_. They can be shared across
different rails applications using RubyGems and Bundler if desired.
### Generate a gemified plugin.
-Rails 3.1 ships with a `rails plugin new` command which creates a
+Rails ships with a `rails plugin new` command which creates a
skeleton for developing any kind of Rails extension with the ability
to run integration tests using a dummy Rails application. See usage
and options by asking for help:
diff --git a/guides/source/rails_application_templates.md b/guides/source/rails_application_templates.md
index 6cd19eb8e9..9e694acb98 100644
--- a/guides/source/rails_application_templates.md
+++ b/guides/source/rails_application_templates.md
@@ -3,10 +3,10 @@ Rails Application Templates
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:
+After reading this guide, you will know:
-* Use templates to generate/customize Rails applications
-* Write your own reusable application templates using the Rails template API
+* How to use templates to generate/customize Rails applications.
+* How to write your own reusable application templates using the Rails template API.
--------------------------------------------------------------------------------
diff --git a/guides/source/rails_on_rack.md b/guides/source/rails_on_rack.md
index afd1638ed9..1fac6d9883 100644
--- a/guides/source/rails_on_rack.md
+++ b/guides/source/rails_on_rack.md
@@ -1,12 +1,14 @@
Rails on Rack
=============
-This guide covers Rails integration with Rack and interfacing with other Rack components. By referring to this guide, you will be able to:
+This guide covers Rails integration with Rack and interfacing with other Rack components.
-* Create Rails Metal applications
-* Use Rack Middlewares in your Rails applications
-* Understand Action Pack's internal Middleware stack
-* Define a custom Middleware stack
+After reading this guide, you will know:
+
+* How to create Rails Metal applications.
+* How to use Rack Middlewares in your Rails applications.
+* Action Pack's internal Middleware stack.
+* How to define a custom Middleware stack.
--------------------------------------------------------------------------------
diff --git a/guides/source/routing.md b/guides/source/routing.md
index 53f037c25b..241a7cfec6 100644
--- a/guides/source/routing.md
+++ b/guides/source/routing.md
@@ -1,13 +1,15 @@
Rails Routing from the Outside In
=================================
-This guide covers the user-facing features of Rails routing. By referring to this guide, you will be able to:
+This guide covers the user-facing features of Rails routing.
-* Understand the code in `routes.rb`
-* Construct your own routes, using either the preferred resourceful style or the `match` method
-* Identify what parameters to expect an action to receive
-* Automatically create paths and URLs using route helpers
-* Use advanced techniques such as constraints and Rack endpoints
+After reading this guide, you will know:
+
+* How to interpret the code in `routes.rb`.
+* How to construct your own routes, using either the preferred resourceful style or the `match` method.
+* What parameters to expect an action to receive.
+* How to automatically create paths and URLs using route helpers.
+* Advanced techniques such as constraints and Rack endpoints.
--------------------------------------------------------------------------------
@@ -18,13 +20,13 @@ The Rails router recognizes URLs and dispatches them to a controller's action. I
### Connecting URLs to Code
-When your Rails application receives an incoming request
+When your Rails application receives an incoming request for:
```
GET /patients/17
```
-it asks the router to match it to a controller action. If the first matching route is
+it asks the router to match it to a controller action. If the first matching route is:
```ruby
get '/patients/:id', to: 'patients#show'
@@ -34,23 +36,25 @@ the request is dispatched to the `patients` controller's `show` action with `{ i
### Generating Paths and URLs from Code
-You can also generate paths and URLs. If the route above is modified to be
+You can also generate paths and URLs. If the route above is modified to be:
```ruby
get '/patients/:id', to: 'patients#show', as: 'patient'
```
-If your application contains this code:
+and your application contains this code in the controller:
```ruby
@patient = Patient.find(17)
```
+and this in the corresponding view:
+
```erb
<%= link_to 'Patient Record', patient_path(@patient) %>
```
-The router will generate the path `/patients/17`. This reduces the brittleness of your view and makes your code easier to understand. Note that the id does not need to be specified in the route helper.
+then the router will generate the path `/patients/17`. This reduces the brittleness of your view and makes your code easier to understand. Note that the id does not need to be specified in the route helper.
Resource Routing: the Rails Default
-----------------------------------
@@ -61,13 +65,13 @@ Resource routing allows you to quickly declare all of the common routes for a gi
Browsers request pages from Rails by making a request for a URL using a specific HTTP method, such as `GET`, `POST`, `PATCH`, `PUT` and `DELETE`. Each method is a request to perform an operation on the resource. A resource route maps a number of related requests to actions in a single controller.
-When your Rails application receives an incoming request for
+When your Rails application receives an incoming request for:
```
DELETE /photos/17
```
-it asks the router to map it to a controller action. If the first matching route is
+it asks the router to map it to a controller action. If the first matching route is:
```ruby
resources :photos
@@ -77,7 +81,7 @@ Rails would dispatch that request to the `destroy` method on the `photos` contro
### CRUD, Verbs, and Actions
-In Rails, a resourceful route provides a mapping between HTTP verbs and URLs to controller actions. By convention, each action also maps to particular CRUD operations in a database. A single entry in the routing file, such as
+In Rails, a resourceful route provides a mapping between HTTP verbs and URLs to controller actions. By convention, each action also maps to particular CRUD operations in a database. A single entry in the routing file, such as:
```ruby
resources :photos
@@ -85,7 +89,7 @@ resources :photos
creates seven different routes in your application, all mapping to the `Photos` controller:
-| HTTP Verb | Path | action | used for |
+| HTTP Verb | Path | Action | Used for |
| --------- | ---------------- | ------- | -------------------------------------------- |
| GET | /photos | index | display a list of all photos |
| GET | /photos/new | new | return an HTML form for creating a new photo |
@@ -95,9 +99,11 @@ creates seven different routes in your application, all mapping to the `Photos`
| PATCH/PUT | /photos/:id | update | update a specific photo |
| DELETE | /photos/:id | destroy | delete a specific photo |
+NOTE: Because the router uses the HTTP verb and URL to match inbound requests, four URLs map to seven different actions.
+
NOTE: Rails routes are matched in the order they are specified, so if you have a `resources :photos` above a `get 'photos/poll'` the `show` action's route for the `resources` line will be matched before the `get` line. To fix this, move the `get` line **above** the `resources` line so that it is matched first.
-### Paths and URLs
+### Path and URL Helpers
Creating a resourceful route will also expose a number of helpers to the controllers in your application. In the case of `resources :photos`:
@@ -108,8 +114,6 @@ Creating a resourceful route will also expose a number of helpers to the control
Each of these helpers has a corresponding `_url` helper (such as `photos_url`) which returns the same path prefixed with the current host, port and path prefix.
-NOTE: Because the router uses the HTTP verb and URL to match inbound requests, four URLs map to seven different actions.
-
### Defining Multiple Resources at the Same Time
If you need to create routes for more than one resource, you can save a bit of typing by defining them all with a single call to `resources`:
@@ -118,7 +122,7 @@ If you need to create routes for more than one resource, you can save a bit of t
resources :photos, :books, :videos
```
-This works exactly the same as
+This works exactly the same as:
```ruby
resources :photos
@@ -128,13 +132,13 @@ resources :videos
### Singular Resources
-Sometimes, you have a resource that clients always look up without referencing an ID. For example, you would like `/profile` to always show the profile of the currently logged in user. In this case, you can use a singular resource to map `/profile` (rather than `/profile/:id`) to the `show` action.
+Sometimes, you have a resource that clients always look up without referencing an ID. For example, you would like `/profile` to always show the profile of the currently logged in user. In this case, you can use a singular resource to map `/profile` (rather than `/profile/:id`) to the `show` action:
```ruby
get 'profile', to: 'users#show'
```
-This resourceful route
+This resourceful route:
```ruby
resource :geocoder
@@ -142,7 +146,7 @@ resource :geocoder
creates six different routes in your application, all mapping to the `Geocoders` controller:
-| HTTP Verb | Path | action | used for |
+| HTTP Verb | Path | Action | Used for |
| --------- | -------------- | ------- | --------------------------------------------- |
| GET | /geocoder/new | new | return an HTML form for creating the geocoder |
| POST | /geocoder | create | create the new geocoder |
@@ -173,7 +177,7 @@ end
This will create a number of routes for each of the `posts` and `comments` controller. For `Admin::PostsController`, Rails will create:
-| HTTP Verb | Path | action | used for |
+| HTTP Verb | Path | Action | Used for |
| --------- | --------------------- | ------- | ------------------------- |
| GET | /admin/posts | index | admin_posts_path |
| GET | /admin/posts/new | new | new_admin_post_path |
@@ -183,7 +187,7 @@ This will create a number of routes for each of the `posts` and `comments` contr
| PATCH/PUT | /admin/posts/:id | update | admin_post_path(:id) |
| DELETE | /admin/posts/:id | destroy | admin_post_path(:id) |
-If you want to route `/posts` (without the prefix `/admin`) to `Admin::PostsController`, you could use
+If you want to route `/posts` (without the prefix `/admin`) to `Admin::PostsController`, you could use:
```ruby
scope module: 'admin' do
@@ -191,13 +195,13 @@ scope module: 'admin' do
end
```
-or, for a single case
+or, for a single case:
```ruby
resources :posts, module: 'admin'
```
-If you want to route `/admin/posts` to `PostsController` (without the `Admin::` module prefix), you could use
+If you want to route `/admin/posts` to `PostsController` (without the `Admin::` module prefix), you could use:
```ruby
scope '/admin' do
@@ -205,7 +209,7 @@ scope '/admin' do
end
```
-or, for a single case
+or, for a single case:
```ruby
resources :posts, path: '/admin/posts'
@@ -213,7 +217,7 @@ resources :posts, path: '/admin/posts'
In each of these cases, the named routes remain the same as if you did not use `scope`. In the last case, the following paths map to `PostsController`:
-| HTTP Verb | Path | action | named helper |
+| HTTP Verb | Path | Action | Named Helper |
| --------- | --------------------- | ------- | ------------------- |
| GET | /admin/posts | index | posts_path |
| GET | /admin/posts/new | new | new_post_path |
@@ -247,7 +251,7 @@ end
In addition to the routes for magazines, this declaration will also route ads to an `AdsController`. The ad URLs require a magazine:
-| HTTP Verb | Path | action | used for |
+| HTTP Verb | Path | Action | Used for |
| --------- | ------------------------------------ | ------- | -------------------------------------------------------------------------- |
| GET | /magazines/:magazine_id/ads | index | display a list of all ads for a specific magazine |
| GET | /magazines/:magazine_id/ads/new | new | return an HTML form for creating a new ad belonging to a specific magazine |
@@ -271,7 +275,7 @@ resources :publishers do
end
```
-Deeply-nested resources quickly become cumbersome. In this case, for example, the application would recognize paths such as
+Deeply-nested resources quickly become cumbersome. In this case, for example, the application would recognize paths such as:
```
/publishers/1/magazines/2/photos/3
@@ -281,9 +285,94 @@ The corresponding route helper would be `publisher_magazine_photo_url`, requirin
TIP: _Resources should never be nested more than 1 level deep._
+#### Shallow Nesting
+
+One way to avoid deep nesting (as recommended above) is to generate the collection actions scoped under the parent, so as to get a sense of the hierarchy, but to not nest the member actions. In other words, to only build routes with the minimal amount of information to uniquely identify the resource, like this:
+
+```ruby
+resources :posts do
+ resources :comments, only: [:index, :new, :create]
+end
+resources :comments, only: [:show, :edit, :update, :destroy]
+```
+
+This idea strikes a balance between descriptive routes and deep nesting. There exists shorthand syntax to achieve just that, via the `:shallow` option:
+
+```ruby
+resources :posts do
+ resources :comments, shallow: true
+end
+```
+
+This will generate the exact same routes as the first example. You can also specify the `:shallow` option in the parent resource, in which case all of the nested resources will be shallow:
+
+```ruby
+resources :posts, shallow: true do
+ resources :comments
+ resources :quotes
+ resources :drafts
+end
+```
+
+The `shallow` method of the DSL creates a scope inside of which every nesting is shallow. This generates the same routes as the previous example:
+
+```ruby
+shallow do
+ resources :posts do
+ resources :comments
+ resources :quotes
+ resources :drafts
+ end
+end
+```
+
+There exists two options for `scope` to customize shallow routes. `:shallow_path` prefixes member paths with the specified parameter:
+
+```ruby
+scope shallow_path: "sekret" do
+ resources :posts do
+ resources :comments, shallow: true
+ end
+end
+```
+
+The comments resource here will have the following routes generated for it:
+
+| HTTP Verb | Path | Named Helper |
+| --------- | -------------------------------------- | ------------------- |
+| GET | /posts/:post_id/comments(.:format) | post_comments |
+| POST | /posts/:post_id/comments(.:format) | post_comments |
+| GET | /posts/:post_id/comments/new(.:format) | new_post_comment |
+| GET | /sekret/comments/:id/edit(.:format) | edit_comment |
+| GET | /sekret/comments/:id(.:format) | comment |
+| PATCH/PUT | /sekret/comments/:id(.:format) | comment |
+| DELETE | /sekret/comments/:id(.:format) | comment |
+
+The `:shallow_prefix` option adds the specified parameter to the named helpers:
+
+```ruby
+scope shallow_prefix: "sekret" do
+ resources :posts do
+ resources :comments, shallow: true
+ end
+end
+```
+
+The comments resource here will have the following routes generated for it:
+
+| HTTP Verb | Path | Named Helper |
+| --------- | -------------------------------------- | ------------------- |
+| GET | /posts/:post_id/comments(.:format) | post_comments |
+| POST | /posts/:post_id/comments(.:format) | post_comments |
+| GET | /posts/:post_id/comments/new(.:format) | new_post_comment |
+| GET | /comments/:id/edit(.:format) | edit_sekret_comment |
+| GET | /comments/:id(.:format) | sekret_comment |
+| PATCH/PUT | /comments/:id(.:format) | sekret_comment |
+| DELETE | /comments/:id(.:format) | sekret_comment |
+
### Routing concerns
-Routing Concerns allows you to declare common routes that can be reused inside others resources and routes.
+Routing Concerns allows you to declare common routes that can be reused inside others resources and routes. To define a concern:
```ruby
concern :commentable do
@@ -295,7 +384,7 @@ concern :image_attachable do
end
```
-These concerns can be used in resources to avoid code duplication and share behavior across routes.
+These concerns can be used in resources to avoid code duplication and share behavior across routes:
```ruby
resources :messages, concerns: :commentable
@@ -303,6 +392,19 @@ resources :messages, concerns: :commentable
resources :posts, concerns: [:commentable, :image_attachable]
```
+The above is equivalent to:
+
+```ruby
+resources :messages do
+ resources :comments
+end
+
+resources :posts do
+ resources :comments
+ resources :images, only: :index
+end
+```
+
Also you can use them in any place that you want inside the routes, for example in a scope or namespace call:
```ruby
@@ -321,7 +423,7 @@ resources :magazines do
end
```
-When using `magazine_ad_path`, you can pass in instances of `Magazine` and `Ad` instead of the numeric IDs.
+When using `magazine_ad_path`, you can pass in instances of `Magazine` and `Ad` instead of the numeric IDs:
```erb
<%= link_to 'Ad details', magazine_ad_path(@magazine, @ad) %>
@@ -413,9 +515,7 @@ end
This will enable Rails to recognize paths such as `/comments/new/preview` with GET, and route to the `preview` action of `CommentsController`. It will also create the `preview_new_comment_url` and `preview_new_comment_path` route helpers.
-#### A Note of Caution
-
-If you find yourself adding many extra actions to a resourceful route, it's time to stop and ask yourself whether you're disguising the presence of another resource.
+TIP: If you find yourself adding many extra actions to a resourceful route, it's time to stop and ask yourself whether you're disguising the presence of another resource.
Non-Resourceful Routes
----------------------
@@ -452,11 +552,11 @@ NOTE: You can't use `:namespace` or `:module` with a `:controller` path segment.
get ':controller(/:action(/:id))', controller: /admin\/[^\/]+/
```
-TIP: By default dynamic segments don't accept dots - this is because the dot is used as a separator for formatted routes. If you need to use a dot within a dynamic segment, add a constraint that overrides this – for example, `id: /[^\/]+/` allows anything except a slash.
+TIP: By default, dynamic segments don't accept dots - this is because the dot is used as a separator for formatted routes. If you need to use a dot within a dynamic segment, add a constraint that overrides this – for example, `id: /[^\/]+/` allows anything except a slash.
### Static Segments
-You can specify static segments when creating a route:
+You can specify static segments when creating a route by not prepending a colon to a fragment:
```ruby
get ':controller/:action/:id/with_user/:user_id'
@@ -494,7 +594,7 @@ Rails would match `photos/12` to the `show` action of `PhotosController`, and se
### Naming Routes
-You can specify a name for any route using the `:as` option.
+You can specify a name for any route using the `:as` option:
```ruby
get 'exit', to: 'sessions#destroy', as: :logout
@@ -524,7 +624,7 @@ You can match all verbs to a particular route using `via: :all`:
match 'photos', to: 'photos#show', via: :all
```
-You should avoid routing all verbs to an action unless you have a good reason to, as routing both `GET` requests and `POST` requests to a single action has security implications.
+NOTE: Routing both `GET` and `POST` requests to a single action has security implications. In general, you should avoid routing all verbs to an action unless you have a good reason to.
### Segment Constraints
@@ -534,7 +634,7 @@ You can use the `:constraints` option to enforce a format for a dynamic segment:
get 'photos/:id', to: 'photos#show', constraints: { id: /[A-Z]\d{5}/ }
```
-This route would match paths such as `/photos/A12345`. You can more succinctly express the same route this way:
+This route would match paths such as `/photos/A12345`, but not `/photos/893`. You can more succinctly express the same route this way:
```ruby
get 'photos/:id', to: 'photos#show', id: /[A-Z]\d{5}/
@@ -607,17 +707,17 @@ end
Both the `matches?` method and the lambda gets the `request` object as an argument.
-### Route Globbing
+### Route Globbing and Wildcard Segments
-Route globbing is a way to specify that a particular parameter should be matched to all the remaining parts of a route. For example
+Route globbing is a way to specify that a particular parameter should be matched to all the remaining parts of a route. For example:
```ruby
get 'photos/*other', to: 'photos#unknown'
```
-This route would match `photos/12` or `/photos/long/path/to/12`, setting `params[:other]` to `"12"` or `"long/path/to/12"`.
+This route would match `photos/12` or `/photos/long/path/to/12`, setting `params[:other]` to `"12"` or `"long/path/to/12"`. The fragments prefixed with a star are called "wildcard segments".
-Wildcard segments can occur anywhere in a route. For example,
+Wildcard segments can occur anywhere in a route. For example:
```ruby
get 'books/*section/:title', to: 'books#show'
@@ -625,7 +725,7 @@ get 'books/*section/:title', to: 'books#show'
would match `books/some/section/last-words-a-memoir` with `params[:section]` equals `'some/section'`, and `params[:title]` equals `'last-words-a-memoir'`.
-Technically a route can have even more than one wildcard segment. The matcher assigns segments to parameters in an intuitive way. For example,
+Technically, a route can have even more than one wildcard segment. The matcher assigns segments to parameters in an intuitive way. For example:
```ruby
get '*a/foo/*b', to: 'test#index'
@@ -633,12 +733,6 @@ get '*a/foo/*b', to: 'test#index'
would match `zoo/woo/foo/bar/baz` with `params[:a]` equals `'zoo/woo'`, and `params[:b]` equals `'bar/baz'`.
-NOTE: Starting from Rails 3.1, wildcard routes will always match the optional format segment by default. For example if you have this route:
-
-```ruby
-get '*pages', to: 'pages#show'
-```
-
NOTE: By requesting `'/foo/bar.json'`, your `params[:pages]` will be equals to `'foo/bar'` with the request format of JSON. If you want the old 3.0.x behavior back, you could supply `format: false` like this:
```ruby
@@ -678,7 +772,7 @@ In all of these cases, if you don't provide the leading host (`http://www.exampl
### Routing to Rack Applications
-Instead of a String, like `'posts#index'`, which corresponds to the `index` action in the `PostsController`, you can specify any <a href="rails_on_rack.html">Rack application</a> as the endpoint for a matcher.
+Instead of a String like `'posts#index'`, which corresponds to the `index` action in the `PostsController`, you can specify any <a href="rails_on_rack.html">Rack application</a> as the endpoint for a matcher:
```ruby
match '/application.js', to: Sprockets, via: :all
@@ -703,7 +797,7 @@ NOTE: The `root` route only routes `GET` requests to the action.
### Unicode character routes
-You can specify unicode character routes directly. For example
+You can specify unicode character routes directly. For example:
```ruby
get 'こんにちは', to: 'welcome#index'
@@ -724,7 +818,7 @@ resources :photos, controller: 'images'
will recognize incoming paths beginning with `/photos` but route to the `Images` controller:
-| HTTP Verb | Path | action | named helper |
+| HTTP Verb | Path | Action | Named Helper |
| --------- | ---------------- | ------- | -------------------- |
| GET | /photos | index | photos_path |
| GET | /photos/new | new | new_photo_path |
@@ -769,7 +863,7 @@ resources :photos, as: 'images'
will recognize incoming paths beginning with `/photos` and route the requests to `PhotosController`, but use the value of the :as option to name the helpers.
-| HTTP Verb | Path | action | named helper |
+| HTTP Verb | Path | Action | Named Helper |
| --------- | ---------------- | ------- | -------------------- |
| GET | /photos | index | images_path |
| GET | /photos/new | new | new_image_path |
@@ -787,7 +881,7 @@ The `:path_names` option lets you override the automatically-generated "new" and
resources :photos, path_names: { new: 'make', edit: 'change' }
```
-This would cause the routing to recognize paths such as
+This would cause the routing to recognize paths such as:
```
/photos/make
@@ -806,7 +900,7 @@ end
### Prefixing the Named Route Helpers
-You can use the `:as` option to prefix the named route helpers that Rails generates for a route. Use this option to prevent name collisions between routes using a path scope.
+You can use the `:as` option to prefix the named route helpers that Rails generates for a route. Use this option to prevent name collisions between routes using a path scope. For example:
```ruby
scope 'admin' do
@@ -874,7 +968,7 @@ end
Rails now creates routes to the `CategoriesController`.
-| HTTP Verb | Path | action | used for |
+| HTTP Verb | Path | Action | Used for |
| --------- | -------------------------- | ------- | ----------------------- |
| GET | /kategorien | index | categories_path |
| GET | /kategorien/neu | new | new_category_path |
@@ -886,7 +980,7 @@ Rails now creates routes to the `CategoriesController`.
### Overriding the Singular Form
-If you want to define the singular form of a resource, you should add additional rules to the `Inflector`.
+If you want to define the singular form of a resource, you should add additional rules to the `Inflector`:
```ruby
ActiveSupport::Inflector.inflections do |inflect|
@@ -896,7 +990,7 @@ end
### Using `:as` in Nested Resources
-The `:as` option overrides the automatically-generated name for the resource in nested route helpers. For example,
+The `:as` option overrides the automatically-generated name for the resource in nested route helpers. For example:
```ruby
resources :magazines do
@@ -911,7 +1005,7 @@ Inspecting and Testing Routes
Rails offers facilities for inspecting and testing your routes.
-### Seeing Existing Routes
+### Listing Existing Routes
To get a complete list of the available routes in your application, visit `http://localhost:3000/rails/info/routes` in your browser while your server is running in the **development** environment. You can also execute the `rake routes` command in your terminal to produce the same output.
@@ -949,7 +1043,7 @@ Routes should be included in your testing strategy (just like the rest of your a
#### The `assert_generates` Assertion
-`assert_generates` asserts that a particular set of options generate a particular path and can be used with default routes or custom routes.
+`assert_generates` asserts that a particular set of options generate a particular path and can be used with default routes or custom routes. For example:
```ruby
assert_generates '/photos/1', { controller: 'photos', action: 'show', id: '1' }
@@ -958,7 +1052,7 @@ assert_generates '/about', controller: 'pages', action: 'about'
#### The `assert_recognizes` Assertion
-`assert_recognizes` is the inverse of `assert_generates`. It asserts that a given path is recognized and routes it to a particular spot in your application.
+`assert_recognizes` is the inverse of `assert_generates`. It asserts that a given path is recognized and routes it to a particular spot in your application. For example:
```ruby
assert_recognizes({ controller: 'photos', action: 'show', id: '1' }, '/photos/1')
@@ -972,7 +1066,7 @@ assert_recognizes({ controller: 'photos', action: 'create' }, { path: 'photos',
#### The `assert_routing` Assertion
-The `assert_routing` assertion checks the route both ways: it tests that the path generates the options, and that the options generate the path. Thus, it combines the functions of `assert_generates` and `assert_recognizes`.
+The `assert_routing` assertion checks the route both ways: it tests that the path generates the options, and that the options generate the path. Thus, it combines the functions of `assert_generates` and `assert_recognizes`:
```ruby
assert_routing({ path: 'photos', method: :post }, { controller: 'photos', action: 'create' })
diff --git a/guides/source/ruby_on_rails_guides_guidelines.md b/guides/source/ruby_on_rails_guides_guidelines.md
index e589a3d093..a78711f4b2 100644
--- a/guides/source/ruby_on_rails_guides_guidelines.md
+++ b/guides/source/ruby_on_rails_guides_guidelines.md
@@ -3,6 +3,11 @@ Ruby on Rails Guides Guidelines
This guide documents guidelines for writing Ruby on Rails Guides. This guide follows itself in a graceful loop, serving itself as an example.
+After reading this guide, you will know:
+
+* About the conventions to be used in Rails documentation.
+* How to generate guides locally.
+
--------------------------------------------------------------------------------
Markdown
@@ -60,7 +65,7 @@ HTML Guides
### Generation
-To generate all the guides, just `cd` into the **`guides`** directory and execute:
+To generate all the guides, just `cd` into the **`guides`** directory, run `bundle install` and execute:
```
bundle exec rake guides:generate
@@ -72,8 +77,6 @@ or
bundle exec rake guides:generate:html
```
-(You may need to run `bundle install` first to install the required gems.)
-
To process `my_guide.md` and nothing else use the `ONLY` environment variable:
```
diff --git a/guides/source/security.md b/guides/source/security.md
index 4902f83f8a..532a1ae5cc 100644
--- a/guides/source/security.md
+++ b/guides/source/security.md
@@ -1,15 +1,17 @@
Ruby On Rails Security Guide
============================
-This manual describes common security problems in web applications and how to avoid them with Rails. After reading it, you should be familiar with:
+This manual describes common security problems in web applications and how to avoid them with Rails.
-* All countermeasures _that are highlighted_
-* The concept of sessions in Rails, what to put in there and popular attack methods
-* How just visiting a site can be a security problem (with CSRF)
-* What you have to pay attention to when working with files or providing an administration interface
-* The Rails-specific mass assignment problem
-* How to manage users: Logging in and out and attack methods on all layers
-* And the most popular injection attack methods
+After reading this guide, you will know:
+
+* All countermeasures _that are highlighted_.
+* The concept of sessions in Rails, what to put in there and popular attack methods.
+* How just visiting a site can be a security problem (with CSRF).
+* What you have to pay attention to when working with files or providing an administration interface.
+* The Rails-specific mass assignment problem.
+* How to manage users: Logging in and out and attack methods on all layers.
+* And the most popular injection attack methods.
--------------------------------------------------------------------------------
@@ -686,7 +688,7 @@ NOTE: _When sanitizing, protecting or verifying something, whitelists over black
A blacklist can be a list of bad e-mail addresses, non-public actions or bad HTML tags. This is opposed to a whitelist which lists the good e-mail addresses, public actions, good HTML tags and so on. Although sometimes it is not possible to create a whitelist (in a SPAM filter, for example), _prefer to use whitelist approaches_:
-* Use before_filter only: [...] instead of except: [...]. This way you don't forget to turn it off for newly added actions.
+* Use before_action only: [...] instead of except: [...]. This way you don't forget to turn it off for newly added actions.
* Use attr_accessible instead of attr_protected. See the mass-assignment section for details
* Allow &lt;strong&gt; instead of removing &lt;script&gt; against Cross-Site Scripting (XSS). See below for details.
* Don't try to correct user input by blacklists:
diff --git a/guides/source/testing.md b/guides/source/testing.md
index f898456d39..a9bce04522 100644
--- a/guides/source/testing.md
+++ b/guides/source/testing.md
@@ -2,11 +2,13 @@ A Guide to Testing Rails Applications
=====================================
This guide covers built-in mechanisms offered by Rails to test your
-application. By referring to this guide, you will be able to:
+application.
-* Understand Rails testing terminology
-* Write unit, functional, and integration tests for your application
-* Identify other popular testing approaches and plugins
+After reading this guide, you will know:
+
+* Rails testing terminology.
+* How to write unit, functional, and integration tests for your application.
+* Other popular testing approaches and plugins.
--------------------------------------------------------------------------------
@@ -97,9 +99,9 @@ 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
-#### Fixtures are ActiveRecord objects
+#### Fixtures are Active Record objects
-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:
+Fixtures are instances of Active Record. 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 User object for the fixture named david
diff --git a/guides/source/upgrading_ruby_on_rails.md b/guides/source/upgrading_ruby_on_rails.md
index bf81776006..bdb4730cdc 100644
--- a/guides/source/upgrading_ruby_on_rails.md
+++ b/guides/source/upgrading_ruby_on_rails.md
@@ -3,6 +3,8 @@ A Guide for Upgrading Ruby on Rails
This guide provides steps to be followed when you upgrade your applications to a newer version of Ruby on Rails. These steps are also available in individual release guides.
+After reading this guide, you will know:
+
--------------------------------------------------------------------------------
General Advice
@@ -45,7 +47,7 @@ Rails 4.0 has removed the identity map from Active Record, due to [some inconsis
The `delete` method in collection associations can now receive `Fixnum` or `String` arguments as record ids, besides records, pretty much like the `destroy` method does. Previously it raised `ActiveRecord::AssociationTypeMismatch` for such arguments. From Rails 4.0 on `delete` automatically tries to find the records matching the given ids before deleting them.
-Rails 4.0 has changed how orders get stacked in `ActiveRecord::Relation`. In previous versions of rails new order was applied after previous defined order. But this is no long true. Check [ActiveRecord Query guide](active_record_querying.html#ordering) for more information.
+Rails 4.0 has changed how orders get stacked in `ActiveRecord::Relation`. In previous versions of rails new order was applied after previous defined order. But this is no long true. Check [Active Record Query guide](active_record_querying.html#ordering) for more information.
Rails 4.0 has changed `serialized_attributes` and `attr_readonly` to class methods only. Now you shouldn't use instance methods, it's deprecated. You must change them, e.g. `self.serialized_attributes` to `self.class.serialized_attributes`.
@@ -69,14 +71,14 @@ in the `config/initializers/wrap_parameters.rb` file:
### Action Pack
-There is an upgrading cookie store UpgradeSignatureToEncryptionCookieStore which helps you upgrading apps that use +CookieStore+ to the new default +EncryptedCookieStore+. To use this CookieStore set Myapp::Application.config.session_store :upgrade_signature_to_encryption_cookie_store, key: '_myapp_session' in your config/initializers/session_store.rb. You will also need to add Myapp::Application.config.secret_key_base = 'some secret' in your config/initializers/secret_token.rb, but do not remove +Myapp::Application.config.secret_token = 'some secret'+
+There is an upgrading cookie store `UpgradeSignatureToEncryptionCookieStore` which helps you upgrading apps that use `CookieStore` to the new default `EncryptedCookieStore`. To use this CookieStore set `Myapp::Application.config.session_store :upgrade_signature_to_encryption_cookie_store, key: '_myapp_session'` in `config/initializers/session_store.rb`. Additionally, add `Myapp::Application.config.secret_key_base = 'some secret'` in config/initializers/secret_token.rb (use `rake secret` to generate a value). Do not remove `Myapp::Application.config.secret_token = 'some secret'`.
Rails 4.0 removed the `ActionController::Base.asset_path` option. Use the assets pipeline feature.
Rails 4.0 has deprecated `ActionController::Base.page_cache_extension` option. Use
`ActionController::Base.default_static_extension` instead.
-Rails 4.0 has removed Action and Page caching from ActionPack. You will need to
+Rails 4.0 has removed Action and Page caching from Action Pack. You will need to
add the `actionpack-action_caching` gem in order to use `caches_action` and
the `actionpack-page_caching` to use `caches_pages` in your controllers.
diff --git a/guides/source/working_with_javascript_in_rails.md b/guides/source/working_with_javascript_in_rails.md
index 10b9dddd02..0f5acfba3c 100644
--- a/guides/source/working_with_javascript_in_rails.md
+++ b/guides/source/working_with_javascript_in_rails.md
@@ -3,13 +3,15 @@ Working with JavaScript in Rails
This guide covers the built-in Ajax/JavaScript functionality of Rails (and
more); it will enable you to create rich and dynamic Ajax applications with
-ease! We will cover the following topics:
+ease!
-* Quick introduction to Ajax
-* Unobtrusive JavaScript
-* How Rails' built-in helpers assist you
-* Handling Ajax on the server side
-* The Turbolinks gem
+After reading this guide, you will know:
+
+* The basics of Ajax.
+* Unobtrusive JavaScript.
+* How Rails' built-in helpers assist you.
+* How to handle Ajax on the server side.
+* The Turbolinks gem.
-------------------------------------------------------------------------------