aboutsummaryrefslogtreecommitdiffstats
path: root/guides/source
diff options
context:
space:
mode:
Diffstat (limited to 'guides/source')
-rw-r--r--guides/source/3_2_release_notes.md4
-rw-r--r--guides/source/4_2_release_notes.md11
-rw-r--r--guides/source/5_0_release_notes.md768
-rw-r--r--guides/source/_welcome.html.erb10
-rw-r--r--guides/source/action_controller_overview.md14
-rw-r--r--guides/source/action_mailer_basics.md6
-rw-r--r--guides/source/action_view_overview.md57
-rw-r--r--guides/source/active_job_basics.md40
-rw-r--r--guides/source/active_model_basics.md24
-rw-r--r--guides/source/active_record_basics.md23
-rw-r--r--guides/source/active_record_callbacks.md51
-rw-r--r--guides/source/active_record_migrations.md109
-rw-r--r--guides/source/active_record_postgresql.md84
-rw-r--r--guides/source/active_record_querying.md182
-rw-r--r--guides/source/active_record_validations.md196
-rw-r--r--guides/source/active_support_core_extensions.md87
-rw-r--r--guides/source/active_support_instrumentation.md35
-rw-r--r--guides/source/api_app.md28
-rw-r--r--guides/source/api_documentation_guidelines.md10
-rw-r--r--guides/source/asset_pipeline.md26
-rw-r--r--guides/source/association_basics.md315
-rw-r--r--guides/source/autoloading_and_reloading_constants.md12
-rw-r--r--guides/source/caching_with_rails.md6
-rw-r--r--guides/source/command_line.md10
-rw-r--r--guides/source/configuring.md115
-rw-r--r--guides/source/contributing_to_ruby_on_rails.md46
-rw-r--r--guides/source/debugging_rails_applications.md57
-rw-r--r--guides/source/development_dependencies_install.md4
-rw-r--r--guides/source/engines.md65
-rw-r--r--guides/source/form_helpers.md31
-rw-r--r--guides/source/getting_started.md46
-rw-r--r--guides/source/i18n.md14
-rw-r--r--guides/source/initialization.md34
-rw-r--r--guides/source/kindle/layout.html.erb4
-rw-r--r--guides/source/kindle/toc.ncx.erb8
-rw-r--r--guides/source/layouts_and_rendering.md30
-rw-r--r--guides/source/maintenance_policy.md6
-rw-r--r--guides/source/nested_model_forms.md6
-rw-r--r--guides/source/plugins.md137
-rw-r--r--guides/source/rails_application_templates.md10
-rw-r--r--guides/source/rails_on_rack.md17
-rw-r--r--guides/source/routing.md28
-rw-r--r--guides/source/security.md71
-rw-r--r--guides/source/testing.md752
-rw-r--r--guides/source/upgrading_ruby_on_rails.md77
-rw-r--r--guides/source/working_with_javascript_in_rails.md6
46 files changed, 2473 insertions, 1199 deletions
diff --git a/guides/source/3_2_release_notes.md b/guides/source/3_2_release_notes.md
index c52c39b705..f16d509f77 100644
--- a/guides/source/3_2_release_notes.md
+++ b/guides/source/3_2_release_notes.md
@@ -154,7 +154,7 @@ Railties
rails g scaffold Post title:string:index author:uniq price:decimal{7,2}
```
- will create indexes for `title` and `author` with the latter being an unique index. Some types such as decimal accept custom options. In the example, `price` will be a decimal column with precision and scale set to 7 and 2 respectively.
+ will create indexes for `title` and `author` with the latter being a unique index. Some types such as decimal accept custom options. In the example, `price` will be a decimal column with precision and scale set to 7 and 2 respectively.
* Turn gem has been removed from default Gemfile.
@@ -327,7 +327,7 @@ Active Record
* Implemented `ActiveRecord::Relation#explain`.
-* Implements `AR::Base.silence_auto_explain` which allows the user to selectively disable automatic EXPLAINs within a block.
+* Implements `ActiveRecord::Base.silence_auto_explain` which allows the user to selectively disable automatic EXPLAINs within a block.
* Implements automatic EXPLAIN logging for slow queries. A new configuration parameter `config.active_record.auto_explain_threshold_in_seconds` determines what's to be considered a slow query. Setting that to nil disables this feature. Defaults are 0.5 in development mode, and nil in test and production modes. Rails 3.2 supports this feature in SQLite, MySQL (mysql2 adapter), and PostgreSQL.
diff --git a/guides/source/4_2_release_notes.md b/guides/source/4_2_release_notes.md
index 684bd286bc..8a59007420 100644
--- a/guides/source/4_2_release_notes.md
+++ b/guides/source/4_2_release_notes.md
@@ -227,6 +227,17 @@ restore the old behavior.
If you do this, be sure to configure your firewall properly such that only
trusted machines on your network can access your development server.
+### Changed status option symbols for `render`
+
+Due to a [change in Rack](https://github.com/rack/rack/commit/be28c6a2ac152fe4adfbef71f3db9f4200df89e8), the symbols that the `render` method accepts for the `:status` option have changed:
+
+- 306: `:reserved` has been removed.
+- 413: `:request_entity_too_large` has been renamed to `:payload_too_large`.
+- 414: `:request_uri_too_long` has been renamed to `:uri_too_long`.
+- 416: `:requested_range_not_satisfiable` has been renamed to `:range_not_satisfiable`.
+
+Keep in mind that if calling `render` with an unknown symbol, the response status will default to 500.
+
### HTML Sanitizer
The HTML sanitizer has been replaced with a new, more robust, implementation
diff --git a/guides/source/5_0_release_notes.md b/guides/source/5_0_release_notes.md
new file mode 100644
index 0000000000..2650384df3
--- /dev/null
+++ b/guides/source/5_0_release_notes.md
@@ -0,0 +1,768 @@
+**DO NOT READ THIS FILE ON GITHUB, GUIDES ARE PUBLISHED ON http://guides.rubyonrails.org.**
+
+Ruby on Rails 5.0 Release Notes
+===============================
+
+Highlights in Rails 5.0:
+
+* Action Cable
+* Rails API
+* Active Record Attributes API
+* Test Runner
+* Exclusive use of `rails` CLI over Rake
+* Sprockets 3
+* Turbolinks 5
+* Ruby 2.2.2+ required
+
+These release notes cover only the major changes. To learn 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/5-0-stable) in the main Rails
+repository on GitHub.
+
+--------------------------------------------------------------------------------
+
+Upgrading to Rails 5.0
+----------------------
+
+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 4.2 in case you
+haven't and make sure your application still runs as expected before attempting
+an update to Rails 5.0. A list of things to watch out for when upgrading is
+available in the
+[Upgrading Ruby on Rails](upgrading_ruby_on_rails.html#upgrading-from-rails-4-2-to-rails-5-0)
+guide.
+
+
+Major Features
+--------------
+
+### Action Cable
+[Pull Request](https://github.com/rails/rails/pull/22586)
+
+ToDo...
+
+### Rails API
+[Pull Request](https://github.com/rails/rails/pull/19832)
+
+ToDo...
+
+### Active Record attributes API
+
+ToDo...
+
+### Test Runner
+[Pull Request](https://github.com/rails/rails/pull/19216)
+
+ToDo...
+
+
+Railties
+--------
+
+Please refer to the [Changelog][railties] for detailed changes.
+
+### Removals
+
+* Removed debugger support, use byebug instead. `debugger` is not supported by
+ Ruby
+ 2.2. ([commit](https://github.com/rails/rails/commit/93559da4826546d07014f8cfa399b64b4a143127))
+
+* Removed deprecated `test:all` and `test:all:db` tasks.
+ ([commit](https://github.com/rails/rails/commit/f663132eef0e5d96bf2a58cec9f7c856db20be7c))
+
+* Removed deprecated `Rails::Rack::LogTailer`.
+ ([commit](https://github.com/rails/rails/commit/c564dcb75c191ab3d21cc6f920998b0d6fbca623))
+
+* Removed deprecated `RAILS_CACHE` constant.
+ ([commit](https://github.com/rails/rails/commit/b7f856ce488ef8f6bf4c12bb549f462cb7671c08))
+
+* Removed deprecated `serve_static_assets` configuration.
+ ([commit](https://github.com/rails/rails/commit/463b5d7581ee16bfaddf34ca349b7d1b5878097c))
+
+* Removed the documentation tasks `doc:app`, `doc:rails`, and `doc:guides`.
+ ([commit](https://github.com/rails/rails/commit/cd7cc5254b090ccbb84dcee4408a5acede25ef2a))
+
+* Removed `Rack::ContentLength` middleware from the default
+ stack. ([Commit](https://github.com/rails/rails/commit/56903585a099ab67a7acfaaef0a02db8fe80c450))
+
+### Deprecations
+
+* Deprecated `config.static_cache_control` in favor of
+ `config.public_file_server.headers`.
+ ([Pull Request](https://github.com/rails/rails/pull/22173))
+
+* Deprecated `config.serve_static_files` in favor of `config.public_file_server.enabled`.
+ ([Pull Request](https://github.com/rails/rails/pull/22173))
+
+### Notable changes
+
+* Added Rails test runner `bin/rails test`.
+ ([Pull Request](https://github.com/rails/rails/pull/19216))
+
+* Newly generated applications and plugins get a `README.md` in Markdown.
+ ([commit](https://github.com/rails/rails/commit/89a12c931b1f00b90e74afffcdc2fc21f14ca663),
+ [Pull Request](https://github.com/rails/rails/pull/22068))
+
+* Added `bin/rails restart` task to restart your Rails app by touching `tmp/restart.txt`.
+ ([Pull Request](https://github.com/rails/rails/pull/18965))
+
+* Added `bin/rails initializers` task to print out all defined initializers in
+ the order they are invoked by Rails.
+ ([Pull Request](https://github.com/rails/rails/pull/19323))
+
+* Added `bin/rails dev:cache` to enable or disable caching in development mode.
+ ([Pull Request](https://github.com/rails/rails/pull/20961))
+
+* Added `bin/update` script to update the development environment automatically.
+ ([Pull Request](https://github.com/rails/rails/pull/20972))
+
+* Proxy Rake tasks through `bin/rails`.
+ ([Pull Request](https://github.com/rails/rails/pull/22457),
+ [Pull Request](https://github.com/rails/rails/pull/22288))
+
+
+Action Pack
+-----------
+
+Please refer to the [Changelog][action-pack] for detailed changes.
+
+### Removals
+
+* Removed `ActionDispatch::Request::Utils.deep_munge`.
+ ([commit](https://github.com/rails/rails/commit/52cf1a71b393486435fab4386a8663b146608996))
+
+* Removed `ActionController::HideActions`.
+ ([Pull Request](https://github.com/rails/rails/pull/18371))
+
+* Removed `respond_to` and `respond_with` placeholder methods, this functionality
+ has been extracted to the
+ [responders](https://github.com/plataformatec/responders) gem.
+ ([commit](https://github.com/rails/rails/commit/afd5e9a7ff0072e482b0b0e8e238d21b070b6280))
+
+* Removed deprecated assertion files.
+ ([commit](https://github.com/rails/rails/commit/92e27d30d8112962ee068f7b14aa7b10daf0c976))
+
+* Removed deprecated usage of string keys in URL helpers.
+ ([commit](https://github.com/rails/rails/commit/34e380764edede47f7ebe0c7671d6f9c9dc7e809))
+
+* Removed deprecated `only_path` option on `*_path` helpers.
+ ([commit](https://github.com/rails/rails/commit/e4e1fd7ade47771067177254cb133564a3422b8a))
+
+* Removed deprecated `NamedRouteCollection#helpers`.
+ ([commit](https://github.com/rails/rails/commit/2cc91c37bc2e32b7a04b2d782fb8f4a69a14503f))
+
+* Removed deprecated support to define routes with `:to` option that doesn't contain `#`.
+ ([commit](https://github.com/rails/rails/commit/1f3b0a8609c00278b9a10076040ac9c90a9cc4a6))
+
+* Removed deprecated `ActionDispatch::Response#to_ary`.
+ ([commit](https://github.com/rails/rails/commit/4b19d5b7bcdf4f11bd1e2e9ed2149a958e338c01))
+
+* Removed deprecated `ActionDispatch::Request#deep_munge`.
+ ([commit](https://github.com/rails/rails/commit/7676659633057dacd97b8da66e0d9119809b343e))
+
+* Removed deprecated
+ `ActionDispatch::Http::Parameters#symbolized_path_parameters`.
+ ([commit](https://github.com/rails/rails/commit/7fe7973cd8bd119b724d72c5f617cf94c18edf9e))
+
+* Removed deprecated option `use_route` in controller tests.
+ ([commit](https://github.com/rails/rails/commit/e4cfd353a47369dd32198b0e67b8cbb2f9a1c548))
+
+* Removed `assigns` and `assert_template`. Both methods have been extracted
+ into the
+ [rails-controller-testing](https://github.com/rails/rails-controller-testing)
+ gem.
+ ([Pull Request](https://github.com/rails/rails/pull/20138))
+
+### Deprecations
+
+* Deprecated all `*_filter` callbacks in favor of `*_action` callbacks.
+ ([Pull Request](https://github.com/rails/rails/pull/18410))
+
+* Deprecated `*_via_redirect` integration test methods. Use `follow_redirect!`
+ manually after the request call for the same behavior.
+ ([Pull Request](https://github.com/rails/rails/pull/18693))
+
+* Deprecated `AbstractController#skip_action_callback` in favor of individual
+ skip_callback methods.
+ ([Pull Request](https://github.com/rails/rails/pull/19060))
+
+* Deprecated `:nothing` option for `render` method.
+ ([Pull Request](https://github.com/rails/rails/pull/20336))
+
+* Deprecated passing first parameter as `Hash` and default status code for
+ `head` method.
+ ([Pull Request](https://github.com/rails/rails/pull/20407))
+
+* Deprecated using strings or symbols for middleware class names. Use class
+ names instead.
+ ([commit](https://github.com/rails/rails/commit/83b767ce))
+
+* Deprecated accessing mime types via constants (eg. `Mime::HTML`). Use the
+ subscript operator with a symbol instead (eg. `Mime[:html]`).
+ ([Pull Request](https://github.com/rails/rails/pull/21869))
+
+* Deprecated `redirect_to :back` in favor of `redirect_back`, which accepts a
+ required `fallback_location` argument, thus eliminating the possibility of a
+ `RedirectBackError`.
+ ([Pull Request](https://github.com/rails/rails/pull/22506))
+
+### Notable changes
+
+* Added `ActionController::Renderer` to render arbitrary templates
+ outside controller actions.
+ ([Pull Request](https://github.com/rails/rails/pull/18546))
+
+* Migrating to keyword arguments syntax in `ActionController::TestCase` and
+ `ActionDispatch::Integration` HTTP request methods.
+ ([Pull Request](https://github.com/rails/rails/pull/18323))
+
+* Added `http_cache_forever` to Action Controller, so we can cache a response
+ that never gets expired.
+ ([Pull Request](https://github.com/rails/rails/pull/18394))
+
+* Provide friendlier access to request variants.
+ ([Pull Request](https://github.com/rails/rails/pull/18939))
+
+* For actions with no corresponding templates, render `head :no_content`
+ instead of raising an error.
+ ([Pull Request](https://github.com/rails/rails/pull/19377))
+
+* Added the ability to override default form builder for a controller.
+ ([Pull Request](https://github.com/rails/rails/pull/19736))
+
+* Added support for API only apps.
+ `ActionController::API` is added as a replacement of
+ `ActionController::Base` for this kind of applications.
+ ([Pull Request](https://github.com/rails/rails/pull/19832))
+
+* Make `ActionController::Parameters` no longer inherits from
+ `HashWithIndifferentAccess`.
+ ([Pull Request](https://github.com/rails/rails/pull/20868))
+
+* Make it easier to opt in to `config.force_ssl` and `config.ssl_options` by
+ making them less dangerous to try and easier to disable.
+ ([Pull Request](https://github.com/rails/rails/pull/21520))
+
+* Added the ability of returning arbitrary headers to `ActionDispatch::Static`.
+ ([Pull Request](https://github.com/rails/rails/pull/19135))
+
+* Changed the `protect_from_forgery` prepend default to `false`.
+ ([commit](https://github.com/rails/rails/commit/39794037817703575c35a75f1961b01b83791191))
+
+* `ActionController::TestCase` will be moved to it's own gem in Rails 5.1. Use
+ `ActionDispatch::IntegrationTest` instead.
+ ([commit](https://github.com/rails/rails/commit/4414c5d1795e815b102571425974a8b1d46d932d))
+
+Action View
+-------------
+
+Please refer to the [Changelog][action-view] for detailed changes.
+
+### Removals
+
+* Removed deprecated `AbstractController::Base::parent_prefixes`.
+ ([commit](https://github.com/rails/rails/commit/34bcbcf35701ca44be559ff391535c0dd865c333))
+
+* Removed `ActionView::Helpers::RecordTagHelper`, this functionality
+ has been extracted to the
+ [record_tag_helper](https://github.com/rails/record_tag_helper) gem.
+ ([Pull Request](https://github.com/rails/rails/pull/18411))
+
+* Removed `:rescue_format` option for `translate` helper since it's no longer
+ supported by I18n.
+ ([Pull Request](https://github.com/rails/rails/pull/20019))
+
+### Notable Changes
+
+* Changed the default template handler from `ERB` to `Raw`.
+ ([commit](https://github.com/rails/rails/commit/4be859f0fdf7b3059a28d03c279f03f5938efc80))
+
+* Collection rendering automatically caches and fetches multiple partials.
+ ([Pull Request](https://github.com/rails/rails/pull/18948))
+
+* Allow defining explicit collection caching using a `# Template Collection: ...`
+ directive inside templates.
+ ([Pull Request](https://github.com/rails/rails/pull/20781))
+
+* Added wildcard matching to explicit dependencies.
+ ([Pull Request](https://github.com/rails/rails/pull/20904))
+
+* Make `disable_with` the default behavior for submit tags. Disables the
+ button on submit to prevent double submits.
+ ([Pull Request](https://github.com/rails/rails/pull/21135))
+
+
+Action Mailer
+-------------
+
+Please refer to the [Changelog][action-mailer] for detailed changes.
+
+### Removals
+
+* Removed deprecated `*_path` helpers in email views.
+ ([commit](https://github.com/rails/rails/commit/d282125a18c1697a9b5bb775628a2db239142ac7))
+
+* Removed deprecated `deliver` and `deliver!` methods.
+ ([commit](https://github.com/rails/rails/commit/755dcd0691f74079c24196135f89b917062b0715))
+
+### Notable changes
+
+* Template lookup now respects default locale and I18n fallbacks.
+ ([commit](https://github.com/rails/rails/commit/ecb1981b))
+
+* Added `_mailer` suffix to mailers created via generator, following the same
+ naming convention used in controllers and jobs.
+ ([Pull Request](https://github.com/rails/rails/pull/18074))
+
+* Added `assert_enqueued_emails` and `assert_no_enqueued_emails`.
+ ([Pull Request](https://github.com/rails/rails/pull/18403))
+
+* Added `config.action_mailer.deliver_later_queue_name` configuration to set
+ the mailer queue name.
+ ([Pull Request](https://github.com/rails/rails/pull/18587))
+
+
+Active Record
+-------------
+
+Please refer to the [Changelog][active-record] for detailed changes.
+
+### Removals
+
+* Removed deprecated behavior allowing nested arrays to be passed as query
+ values. ([Pull Request](https://github.com/rails/rails/pull/17919))
+
+* Removed deprecated `ActiveRecord::Tasks::DatabaseTasks#load_schema`. This
+ method was replaced by `ActiveRecord::Tasks::DatabaseTasks#load_schema_for`.
+ ([commit](https://github.com/rails/rails/commit/ad783136d747f73329350b9bb5a5e17c8f8800da))
+
+* Removed deprecated `serialized_attributes`.
+ ([commit](https://github.com/rails/rails/commit/82043ab53cb186d59b1b3be06122861758f814b2))
+
+* Removed deprecated automatic counter caches on `has_many :through`.
+ ([commit](https://github.com/rails/rails/commit/87c8ce340c6c83342df988df247e9035393ed7a0))
+
+* Removed deprecated `sanitize_sql_hash_for_conditions`.
+ ([commit](https://github.com/rails/rails/commit/3a59dd212315ebb9bae8338b98af259ac00bbef3))
+
+* Removed deprecated `Reflection#source_macro`.
+ ([commit](https://github.com/rails/rails/commit/ede8c199a85cfbb6457d5630ec1e285e5ec49313))
+
+* Removed deprecated `symbolized_base_class` and `symbolized_sti_name`.
+ ([commit](https://github.com/rails/rails/commit/9013e28e52eba3a6ffcede26f85df48d264b8951))
+
+* Removed deprecated `ActiveRecord::Base.disable_implicit_join_references=`.
+ ([commit](https://github.com/rails/rails/commit/0fbd1fc888ffb8cbe1191193bf86933110693dfc))
+
+* Removed deprecated access to connection specification using a string accessor.
+ ([commit](https://github.com/rails/rails/commit/efdc20f36ccc37afbb2705eb9acca76dd8aabd4f))
+
+* Removed deprecated support to preload instance-dependent associations.
+ ([commit](https://github.com/rails/rails/commit/4ed97979d14c5e92eb212b1a629da0a214084078))
+
+* Removed deprecated support for PostgreSQL ranges with exclusive lower bounds.
+ ([commit](https://github.com/rails/rails/commit/a076256d63f64d194b8f634890527a5ed2651115))
+
+* Removed deprecation when modifying a relation with cached Arel.
+ This raises an `ImmutableRelation` error instead.
+ ([commit](https://github.com/rails/rails/commit/3ae98181433dda1b5e19910e107494762512a86c))
+
+* Removed `ActiveRecord::Serialization::XmlSerializer` from core. This feature
+ has been extracted into the
+ [activemodel-serializers-xml](https://github.com/rails/activemodel-serializers-xml)
+ gem. ([Pull Request](https://github.com/rails/rails/pull/21161))
+
+* Removed support for the legacy `mysql` database adapter from core. It will
+ live on in a separate gem for now, but most users should just use `mysql2`.
+
+* Removed support for the `protected_attributes` gem.
+ ([commit](https://github.com/rails/rails/commit/f4fbc0301021f13ae05c8e941c8efc4ae351fdf9))
+
+### Deprecations
+
+* Deprecated passing a class as a value in a query. Users should pass strings
+ instead. ([Pull Request](https://github.com/rails/rails/pull/17916))
+
+* Deprecated returning `false` as a way to halt Active Record callback
+ chains. The recommended way is to
+ `throw(:abort)`. ([Pull Request](https://github.com/rails/rails/pull/17227))
+
+* Deprecated `ActiveRecord::Base.errors_in_transactional_callbacks=`.
+ ([commit](https://github.com/rails/rails/commit/07d3d402341e81ada0214f2cb2be1da69eadfe72))
+
+* Deprecated passing of `start` value to `find_in_batches` and `find_each`
+ in favour of `begin_at` value.
+ ([Pull Request](https://github.com/rails/rails/pull/18961))
+
+* Deprecated `Relation#uniq` use `Relation#distinct` instead.
+ ([commit](https://github.com/rails/rails/commit/adfab2dcf4003ca564d78d4425566dd2d9cd8b4f))
+
+* Deprecated the PostgreSQL `:point` type in favor of a new one which will return
+ `Point` objects instead of an `Array`
+ ([Pull Request](https://github.com/rails/rails/pull/20448))
+
+* Deprecated force association reload by passing a truthy argument to
+ association method.
+ ([Pull Request](https://github.com/rails/rails/pull/20888))
+
+* Deprecated the keys for association `restrict_dependent_destroy` errors in favor
+ of new key names.
+ ([Pull Request](https://github.com/rails/rails/pull/20668))
+
+* Synchronize behavior of `#tables`.
+ ([Pull Request](https://github.com/rails/rails/pull/21601))
+
+* Deprecated `SchemaCache#tables`, `SchemaCache#table_exists?` and
+ `SchemaCache#clear_table_cache!` in favor of their new data source
+ counterparts.
+ ([Pull Request](https://github.com/rails/rails/pull/21715))
+
+* Deprecated `connection.tables` on the SQLite3 and MySQL adapters.
+ ([Pull Request](https://github.com/rails/rails/pull/21601))
+
+* Deprecated passing arguments to `#tables` - the `#tables` method of some
+ adapters (mysql2, sqlite3) would return both tables and views while others
+ (postgresql) just return tables. To make their behavior consistent,
+ `#tables` will return only tables in the future.
+ ([Pull Request](https://github.com/rails/rails/pull/21601))
+
+* Deprecated `table_exists?` - The `#table_exists?` method would check both
+ tables and views. To make their behavior consistent with `#tables`,
+ `#table_exists?` will check only tables in the future.
+ ([Pull Request](https://github.com/rails/rails/pull/21601))
+
+* Deprecate sending the `offset` argument to `find_nth`. Please use the
+ `offset` method on relation instead.
+ ([Pull Request](https://github.com/rails/rails/pull/22053))
+
+### Notable changes
+
+* Added a `foreign_key` option to `references` while creating the table.
+ ([commit](https://github.com/rails/rails/commit/99a6f9e60ea55924b44f894a16f8de0162cf2702))
+
+* New attributes
+ API. ([commit](https://github.com/rails/rails/commit/8c752c7ac739d5a86d4136ab1e9d0142c4041e58))
+
+* Added `:enum_prefix`/`:enum_suffix` option to `enum`
+ definition. ([Pull Request](https://github.com/rails/rails/pull/19813))
+
+* Added `#cache_key` to `ActiveRecord::Relation`.
+ ([Pull Request](https://github.com/rails/rails/pull/20884))
+
+* Added `ActiveRecord::Relation#outer_joins`.
+ ([Pull Request](https://github.com/rails/rails/pull/12071))
+
+* Require `belongs_to` by default.
+ ([Pull Request](https://github.com/rails/rails/pull/18937)) - Deprecate
+ `required` option in favor of `optional` for `belongs_to`
+
+* Changed the default `null` value for `timestamps` to `false`.
+ ([commit](https://github.com/rails/rails/commit/a939506f297b667291480f26fa32a373a18ae06a))
+
+* Added `ActiveRecord::SecureToken` in order to encapsulate generation of
+ unique tokens for attributes in a model using `SecureRandom`.
+ ([Pull Request](https://github.com/rails/rails/pull/18217))
+
+* Added `:if_exists` option for `drop_table`.
+ ([Pull Request](https://github.com/rails/rails/pull/18597))
+
+* Added `ActiveRecord::Base#accessed_fields`, which can be used to quickly
+ discover which fields were read from a model when you are looking to only
+ select the data you need from the database.
+ ([commit](https://github.com/rails/rails/commit/be9b68038e83a617eb38c26147659162e4ac3d2c))
+
+* Added the `#or` method on `ActiveRecord::Relation`, allowing use of the OR
+ operator to combine WHERE or HAVING clauses.
+ ([commit](https://github.com/rails/rails/commit/b0b37942d729b6bdcd2e3178eda7fa1de203b3d0))
+
+* Added `:time` option added for `#touch`.
+ ([Pull Request](https://github.com/rails/rails/pull/18956))
+
+* Added `ActiveRecord::Base.suppress` to prevent the receiver from being saved
+ during the given block.
+ ([Pull Request](https://github.com/rails/rails/pull/18910))
+
+* `belongs_to` will now trigger a validation error by default if the
+ association is not present. You can turn this off on a per-association basis
+ with `optional: true`.
+ ([Pull Request](https://github.com/rails/rails/pull/18937))
+
+* Added `config.active_record.dump_schemas` to configure the behavior of
+ `db:structure:dump`.
+ ([Pull Request](https://github.com/rails/rails/pull/19347))
+
+* Added `config.active_record.warn_on_records_fetched_greater_than` option.
+ ([Pull Request](https://github.com/rails/rails/pull/18846))
+
+* Added a native JSON data type support in MySQL.
+ ([Pull Request](https://github.com/rails/rails/pull/21110))
+
+* Added support for dropping indexes concurrently in PostgreSQL.
+ ([Pull Request](https://github.com/rails/rails/pull/21317))
+
+* Added `#views` and `#view_exists?` methods on connection adapters.
+ ([Pull Request](https://github.com/rails/rails/pull/21609))
+
+* Added `ActiveRecord::Base.ignored_columns` to make some columns
+ invisible from Active Record.
+ ([Pull Request](https://github.com/rails/rails/pull/21720))
+
+* Added `connection.data_sources` and `connection.data_source_exists?`.
+ These methods determine what relations can be used to back Active Record
+ models (usually tables and views).
+ ([Pull Request](https://github.com/rails/rails/pull/21715))
+
+* Allow fixtures files to set the model class in the YAML file itself.
+ ([Pull Request](https://github.com/rails/rails/pull/20574))
+
+* Added ability to default to `uuid` as primary key when generating database
+ migrations. ([Pull Request](https://github.com/rails/rails/pull/21762))
+
+* Added `ActiveRecord::Relation#left_joins` and
+ `ActiveRecord::Relation#left_outer_joins`.
+ ([Pull Request](https://github.com/rails/rails/pull/12071))
+
+* Added `after_{create,update,delete}_commit` callbacks.
+ ([Pull Request](https://github.com/rails/rails/pull/22516))
+
+* Version the API presented to migration classes, so we can change parameter
+ defaults without breaking existing migrations, or forcing them to be
+ rewritten through a deprecation cycle.
+ ([Pull Request](https://github.com/rails/rails/pull/21538))
+
+* `ApplicationRecord` is a new superclass for all app models, analogous to app
+ controllers subclassing `ApplicationController` instead of
+ `ActionController::Base`. This gives apps a single spot to configure app-wide
+ model behavior.
+ ([Pull Request](https://github.com/rails/rails/pull/22567))
+
+
+Active Model
+------------
+
+Please refer to the [Changelog][active-model] for detailed changes.
+
+### Removals
+
+* Removed deprecated `ActiveModel::Dirty#reset_#{attribute}` and
+ `ActiveModel::Dirty#reset_changes`.
+ ([Pull Request](https://github.com/rails/rails/commit/37175a24bd508e2983247ec5d011d57df836c743))
+
+* Removed XML serialization. This feature has been extracted into the
+ [activemodel-serializers-xml](https://github.com/rails/activemodel-serializers-xml) gem.
+ ([Pull Request](https://github.com/rails/rails/pull/21161))
+
+### Deprecations
+
+* Deprecated returning `false` as a way to halt Active Model and
+ `ActiveModel::Validations` callback chains. The recommended way is to
+ `throw(:abort)`. ([Pull Request](https://github.com/rails/rails/pull/17227))
+
+* Deprecated `ActiveModel::Errors#get`, `ActiveModel::Errors#set` and
+ `ActiveModel::Errors#[]=` methods that have inconsistent behavior.
+ ([Pull Request](https://github.com/rails/rails/pull/18634))
+
+* Deprecated the `:tokenizer` option for `validates_length_of`, in favor of
+ plain Ruby.
+ ([Pull Request](https://github.com/rails/rails/pull/19585))
+
+* Deprecated `ActiveModel::Errors#add_on_empty` and `ActiveModel::Errors#add_on_blank`
+ with no replacement.
+ ([Pull Request](https://github.com/rails/rails/pull/18996))
+
+### Notable changes
+
+* Added `ActiveModel::Errors#details` to determine what validator has failed.
+ ([Pull Request](https://github.com/rails/rails/pull/18322))
+
+* Extracted `ActiveRecord::AttributeAssignment` to `ActiveModel::AttributeAssignment`
+ allowing to use it for any object as an includable module.
+ ([Pull Request](https://github.com/rails/rails/pull/10776))
+
+* Added `ActiveModel::Dirty#[attr_name]_previously_changed?` and
+ `ActiveModel::Dirty#[attr_name]_previous_change` to improve access
+ to recorded changes after the model has been saved.
+ ([Pull Request](https://github.com/rails/rails/pull/19847))
+
+* Validate multiple contexts on `valid?` and `invalid?` at once.
+ ([Pull Request](https://github.com/rails/rails/pull/21069))
+
+
+Active Job
+-----------
+
+Please refer to the [Changelog][active-job] for detailed changes.
+
+### Notable changes
+
+* `ActiveJob::Base.deserialize` delegates to the job class. this allows jobs
+ to attach arbitrary metadata when they get serialized and read it back when
+ they get performed.
+ ([Pull Request](https://github.com/rails/rails/pull/18260))
+
+* A generated job now inherits from `app/jobs/application_job.rb` by default.
+ ([Pull Request](https://github.com/rails/rails/pull/19034))
+
+* Allow `DelayedJob`, `Sidekiq`, `qu`, and `que` to report the job id back to
+ `ActiveJob::Base` as `provider_job_id`.
+ ([Pull Request](https://github.com/rails/rails/pull/20064),
+ [Pull Request](https://github.com/rails/rails/pull/20056))
+
+* Implement a simple `AsyncJob` processor and associated `AsyncAdapter` that
+ queue jobs to a `concurrent-ruby` thread pool.
+ ([Pull Request](https://github.com/rails/rails/pull/21257))
+
+
+Active Support
+--------------
+
+Please refer to the [Changelog][active-support] for detailed changes.
+
+### Removals
+
+* Removed deprecated `ActiveSupport::JSON::Encoding::CircularReferenceError`.
+ ([commit](https://github.com/rails/rails/commit/d6e06ea8275cdc3f126f926ed9b5349fde374b10))
+
+* Removed deprecated methods `ActiveSupport::JSON::Encoding.encode_big_decimal_as_string=`
+ and `ActiveSupport::JSON::Encoding.encode_big_decimal_as_string`.
+ ([commit](https://github.com/rails/rails/commit/c8019c0611791b2716c6bed48ef8dcb177b7869c))
+
+* Removed deprecated `ActiveSupport::SafeBuffer#prepend`.
+ ([commit](https://github.com/rails/rails/commit/e1c8b9f688c56aaedac9466a4343df955b4a67ec))
+
+* Removed deprecated methods from `Kernel`. `silence_stderr`, `silence_stream`,
+ `capture` and `quietly`.
+ ([commit](https://github.com/rails/rails/commit/481e49c64f790e46f4aff3ed539ed227d2eb46cb))
+
+* Removed deprecated `active_support/core_ext/big_decimal/yaml_conversions`
+ file.
+ ([commit](https://github.com/rails/rails/commit/98ea19925d6db642731741c3b91bd085fac92241))
+
+* Removed deprecated methods `ActiveSupport::Cache::Store.instrument` and
+ `ActiveSupport::Cache::Store.instrument=`.
+ ([commit](https://github.com/rails/rails/commit/a3ce6ca30ed0e77496c63781af596b149687b6d7))
+
+* Removed deprecated `Class#superclass_delegating_accessor`.
+ Use `Class#class_attribute` instead.
+ ([Pull Request](https://github.com/rails/rails/pull/16938))
+
+* Removed deprecated `ThreadSafe::Cache`. Use `Concurrent::Map` instead.
+ ([Pull Request](https://github.com/rails/rails/pull/21679))
+
+### Deprecations
+
+* Deprecated `MissingSourceFile` in favor of `LoadError`.
+ ([commit](https://github.com/rails/rails/commit/734d97d2))
+
+* Deprecated `alias_method_chain` in favour of `Module#prepend` introduced in
+ Ruby 2.0.
+ ([Pull Request](https://github.com/rails/rails/pull/19434))
+
+* Deprecated `ActiveSupport::Concurrency::Latch` in favor of
+ `Concurrent::CountDownLatch` from concurrent-ruby.
+ ([Pull Request](https://github.com/rails/rails/pull/20866))
+
+* Deprecated `:prefix` option of `number_to_human_size` with no replacement.
+ ([Pull Request](https://github.com/rails/rails/pull/21191))
+
+* Deprecated `Module#qualified_const_` in favour of the builtin
+ `Module#const_` methods.
+ ([Pull Request](https://github.com/rails/rails/pull/17845))
+
+* Deprecated passing string to define callback.
+ ([Pull Request](https://github.com/rails/rails/pull/22598))
+
+* Deprecated `ActiveSupport::Cache::Store#namespaced_key`,
+ `ActiveSupport::Cache::MemCachedStore#escape_key`, and
+ `ActiveSupport::Cache::FileStore#key_file_path`.
+ Use `normalize_key` instead.
+
+ Deprecated `ActiveSupport::Cache::LocaleCache#set_cache_value` in favor of `write_cache_value`.
+ ([Pull Request](https://github.com/rails/rails/pull/22215))
+
+### Notable changes
+
+* Added `#verified` and `#valid_message?` methods to
+ `ActiveSupport::MessageVerifier`.
+ ([Pull Request](https://github.com/rails/rails/pull/17727))
+
+* Changed the way in which callback chains can be halted. The preferred method
+ to halt a callback chain from now on is to explicitly `throw(:abort)`.
+ ([Pull Request](https://github.com/rails/rails/pull/17227))
+
+* New config option
+ `config.active_support.halt_callback_chains_on_return_false` to specify
+ whether ActiveRecord, ActiveModel and ActiveModel::Validations callback
+ chains can be halted by returning `false` in a 'before' callback.
+ ([Pull Request](https://github.com/rails/rails/pull/17227))
+
+* Changed the default test order from `:sorted` to `:random`.
+ ([commit](https://github.com/rails/rails/commit/5f777e4b5ee2e3e8e6fd0e2a208ec2a4d25a960d))
+
+* Added `#on_weekend?`, `#next_weekday`, `#prev_weekday` methods to `Date`,
+ `Time`, and `DateTime`.
+ ([Pull Request](https://github.com/rails/rails/pull/18335))
+
+* Added `same_time` option to `#next_week` and `#prev_week` for `Date`, `Time`,
+ and `DateTime`.
+ ([Pull Request](https://github.com/rails/rails/pull/18335))
+
+* Added `#prev_day` and `#next_day` counterparts to `#yesterday` and
+ `#tomorrow` for `Date`, `Time`, and `DateTime`.
+ ([Pull Request](httpshttps://github.com/rails/rails/pull/18335))
+
+* Added `SecureRandom.base58` for generation of random base58 strings.
+ ([commit](https://github.com/rails/rails/commit/b1093977110f18ae0cafe56c3d99fc22a7d54d1b))
+
+* Added `file_fixture` to `ActiveSupport::TestCase`.
+ It provides a simple mechanism to access sample files in your test cases.
+ ([Pull Request](https://github.com/rails/rails/pull/18658))
+
+* Added `#without` on `Enumerable` and `Array` to return a copy of an
+ enumerable without the specified elements.
+ ([Pull Request](https://github.com/rails/rails/pull/19157))
+
+* Added `ActiveSupport::ArrayInquirer` and `Array#inquiry`.
+ ([Pull Request](https://github.com/rails/rails/pull/18939))
+
+* Added `ActiveSupport::TimeZone#strptime` to allow parsing times as if
+ from a given timezone.
+ ([commit](https://github.com/rails/rails/commit/a5e507fa0b8180c3d97458a9b86c195e9857d8f6))
+
+* Added `Integer#positive?` and `Integer#negative?` query methods
+ in the vein of `Fixnum#zero?`.
+ ([commit](https://github.com/rails/rails/commit/e54277a45da3c86fecdfa930663d7692fd083daa))
+
+* Added a bang version to `ActiveSupport::OrderedOptions` get methods which will raise
+ an `KeyError` if the value is `.blank?`.
+ ([Pull Request](https://github.com/rails/rails/pull/20208))
+
+* Added `Time.days_in_year` to return the number of days in the given year, or the
+ current year if no argument is provided.
+ ([commit](https://github.com/rails/rails/commit/2f4f4d2cf1e4c5a442459fc250daf66186d110fa))
+
+* Added an evented file watcher to asynchronously detect changes in the
+ application source code, routes, locales, etc.
+ ([Pull Request](https://github.com/rails/rails/pull/22254))
+
+* Added thread_m/cattr_accessor/reader/writer suite of methods for declaring
+ class and module variables that live per-thread.
+ ([Pull Request](https://github.com/rails/rails/pull/22630))
+
+
+Credits
+-------
+
+See the
+[full list of contributors to Rails](http://contributors.rubyonrails.org/) for
+the many people who spent many hours making Rails, the stable and robust
+framework it is. Kudos to all of them.
+
+[railties]: https://github.com/rails/rails/blob/5-0-stable/railties/CHANGELOG.md
+[action-pack]: https://github.com/rails/rails/blob/5-0-stable/actionpack/CHANGELOG.md
+[action-view]: https://github.com/rails/rails/blob/5-0-stable/actionview/CHANGELOG.md
+[action-mailer]: https://github.com/rails/rails/blob/5-0-stable/actionmailer/CHANGELOG.md
+[active-record]: https://github.com/rails/rails/blob/5-0-stable/activerecord/CHANGELOG.md
+[active-model]: https://github.com/rails/rails/blob/5-0-stable/activemodel/CHANGELOG.md
+[active-support]: https://github.com/rails/rails/blob/5-0-stable/activesupport/CHANGELOG.md
+[active-job]: https://github.com/rails/rails/blob/5-0-stable/activejob/CHANGELOG.md
diff --git a/guides/source/_welcome.html.erb b/guides/source/_welcome.html.erb
index 67f5f1cdd5..f50bcddbe7 100644
--- a/guides/source/_welcome.html.erb
+++ b/guides/source/_welcome.html.erb
@@ -16,9 +16,9 @@
<% end %>
<p>
The guides for earlier releases:
-<a href="http://guides.rubyonrails.org/v4.2.0/">Rails 4.2.0</a>,
-<a href="http://guides.rubyonrails.org/v4.1.8/">Rails 4.1.8</a>,
-<a href="http://guides.rubyonrails.org/v4.0.12/">Rails 4.0.12</a>,
-<a href="http://guides.rubyonrails.org/v3.2.21/">Rails 3.2.21</a> and
-<a href="http://guides.rubyonrails.org/v2.3.11/">Rails 2.3.11</a>.
+<a href="http://guides.rubyonrails.org/v4.2/">Rails 4.2</a>,
+<a href="http://guides.rubyonrails.org/v4.1/">Rails 4.1</a>,
+<a href="http://guides.rubyonrails.org/v4.0/">Rails 4.0</a>,
+<a href="http://guides.rubyonrails.org/v3.2/">Rails 3.2</a>, and
+<a href="http://guides.rubyonrails.org/v2.3/">Rails 2.3</a>.
</p>
diff --git a/guides/source/action_controller_overview.md b/guides/source/action_controller_overview.md
index 09fbdc0d32..d2e2d27737 100644
--- a/guides/source/action_controller_overview.md
+++ b/guides/source/action_controller_overview.md
@@ -394,7 +394,7 @@ Rails sets up (for the CookieStore) a secret key used for signing the session da
# Make sure the secret is at least 30 characters and all random,
# no regular words or you'll be exposed to dictionary attacks.
-# You can use `rake secret` to generate a secure secret key.
+# You can use `rails secret` to generate a secure secret key.
# Make sure the secrets in this file are kept private
# if you're sharing your code publicly.
@@ -810,7 +810,7 @@ The [Security Guide](security.html) has more about this and a lot of other secur
The Request and Response Objects
--------------------------------
-In every controller there are two accessor methods pointing to the request and the response objects associated with the request cycle that is currently in execution. The `request` method contains an instance of `AbstractRequest` and the `response` method returns a response object representing what is going to be sent back to the client.
+In every controller there are two accessor methods pointing to the request and the response objects associated with the request cycle that is currently in execution. The `request` method contains an instance of `ActionDispatch::Request` and the `response` method returns a response object representing what is going to be sent back to the client.
### The `request` Object
@@ -1029,7 +1029,7 @@ There are a couple of things to notice in the above example. We need to make
sure to close the response stream. Forgetting to close the stream will leave
the socket open forever. We also have to set the content type to `text/event-stream`
before we write to the response stream. This is because headers cannot be written
-after the response has been committed (when `response.committed` returns a truthy
+after the response has been committed (when `response.committed?` returns a truthy
value), which occurs when you `write` or `commit` the response stream.
#### Example Usage
@@ -1114,11 +1114,11 @@ Rescue
Most likely your application is going to contain bugs or otherwise throw an exception that needs to be handled. For example, if the user follows a link to a resource that no longer exists in the database, Active Record will throw the `ActiveRecord::RecordNotFound` exception.
-Rails' default exception handling displays a "500 Server Error" message for all exceptions. If the request was made locally, a nice traceback and some added information gets displayed so you can figure out what went wrong and deal with it. If the request was remote Rails will just display a simple "500 Server Error" message to the user, or a "404 Not Found" if there was a routing error or a record could not be found. Sometimes you might want to customize how these errors are caught and how they're displayed to the user. There are several levels of exception handling available in a Rails application:
+Rails default exception handling displays a "500 Server Error" message for all exceptions. If the request was made locally, a nice traceback and some added information gets displayed so you can figure out what went wrong and deal with it. If the request was remote Rails will just display a simple "500 Server Error" message to the user, or a "404 Not Found" if there was a routing error or a record could not be found. Sometimes you might want to customize how these errors are caught and how they're displayed to the user. There are several levels of exception handling available in a Rails application:
### The Default 500 and 404 Templates
-By default a production application will render either a 404 or a 500 error message. These messages are contained in static HTML files in the `public` folder, in `404.html` and `500.html` respectively. You can customize these files to add some extra information and layout, but remember that they are static; i.e. you can't use RHTML or layouts in them, just plain HTML.
+By default a production application will render either a 404 or a 500 error message. These messages are contained in static HTML files in the `public` folder, in `404.html` and `500.html` respectively. You can customize these files to add some extra information and style, but remember that they are static HTML; i.e. you can't use ERB, SCSS, CoffeeScript, or layouts for them.
### `rescue_from`
@@ -1150,7 +1150,7 @@ class ApplicationController < ActionController::Base
def user_not_authorized
flash[:error] = "You don't have access to this section."
- redirect_to :back
+ redirect_back(fallback_location: root_path)
end
end
@@ -1174,7 +1174,7 @@ end
WARNING: You shouldn't do `rescue_from Exception` or `rescue_from StandardError` unless you have a particular reason as it will cause serious side-effects (e.g. you won't be able to see exception details and tracebacks during development).
-NOTE: Certain exceptions are only rescuable from the `ApplicationController` class, as they are raised before the controller gets initialized and the action gets executed. See Pratik Naik's [article](http://m.onkey.org/2008/7/20/rescue-from-dispatching) on the subject for more information.
+NOTE: Certain exceptions are only rescuable from the `ApplicationController` class, as they are raised before the controller gets initialized and the action gets executed.
Force HTTPS protocol
--------------------
diff --git a/guides/source/action_mailer_basics.md b/guides/source/action_mailer_basics.md
index c39cd34e9a..cd2c13e8c1 100644
--- a/guides/source/action_mailer_basics.md
+++ b/guides/source/action_mailer_basics.md
@@ -170,7 +170,7 @@ First, let's create a simple `User` scaffold:
```bash
$ bin/rails generate scaffold user name email login
-$ bin/rake db:migrate
+$ bin/rails db:migrate
```
Now that we have a user model to play with, we will just edit the
@@ -760,8 +760,8 @@ config.action_mailer.smtp_settings = {
enable_starttls_auto: true }
```
Note: As of July 15, 2014, Google increased [its security measures](https://support.google.com/accounts/answer/6010255) and now blocks attempts from apps it deems less secure.
-You can change your gmail settings [here](https://www.google.com/settings/security/lesssecureapps) to allow the attempts or
-use another ESP to send email by replacing 'smpt.gmail.com' above with the address of your provider.
+You can change your gmail settings [here](https://www.google.com/settings/security/lesssecureapps) to allow the attempts or
+use another ESP to send email by replacing 'smtp.gmail.com' above with the address of your provider.
Mailer Testing
--------------
diff --git a/guides/source/action_view_overview.md b/guides/source/action_view_overview.md
index db7eeed19a..543937f8e5 100644
--- a/guides/source/action_view_overview.md
+++ b/guides/source/action_view_overview.md
@@ -147,6 +147,39 @@ xml.rss("version" => "2.0", "xmlns:dc" => "http://purl.org/dc/elements/1.1/") do
end
```
+#### Jbuilder
+[Jbuilder](https://github.com/rails/jbuilder) is a gem that's
+maintained by the Rails team and included in the default Rails Gemfile.
+It's similar to Builder, but is used to generate JSON, instead of XML.
+
+If you don't have it, you can add the following to your Gemfile:
+
+```ruby
+gem 'jbuilder'
+```
+
+A Jbuilder object named `json` is automatically made available to templates with
+a `.jbuilder` extension.
+
+Here is a basic example:
+
+```ruby
+json.name("Alex")
+json.email("alex@example.com")
+```
+
+would produce:
+
+```json
+{
+ "name": "Alex",
+ "email: "alex@example.com"
+}
+```
+
+See the [Jbuilder documention](https://github.com/rails/jbuilder#jbuilder) for
+more examples and information.
+
#### Template Caching
By default, Rails will compile each template to a method in order to render it. When you alter a template, Rails will check the file's modification time and recompile it in development mode.
@@ -566,7 +599,7 @@ This would add something like "Process data files (0.34523)" to the log, which y
#### cache
-A method for caching fragments of a view rather than an entire action or page. This technique is useful caching pieces like menus, lists of news topics, static HTML fragments, and so on. This method takes a block that contains the content you wish to cache. See `ActionController::Caching::Fragments` for more information.
+A method for caching fragments of a view rather than an entire action or page. This technique is useful for caching pieces like menus, lists of news topics, static HTML fragments, and so on. This method takes a block that contains the content you wish to cache. See `ActionController::Caching::Fragments` for more information.
```erb
<% cache do %>
@@ -957,11 +990,11 @@ Returns `select` and `option` tags for the collection of existing return values
Example object structure for use with this method:
```ruby
-class Article < ActiveRecord::Base
+class Article < ApplicationRecord
belongs_to :author
end
-class Author < ActiveRecord::Base
+class Author < ApplicationRecord
has_many :articles
def name_with_initial
"#{first_name.first}. #{last_name}"
@@ -993,11 +1026,11 @@ Returns `radio_button` tags for the collection of existing return values of `met
Example object structure for use with this method:
```ruby
-class Article < ActiveRecord::Base
+class Article < ApplicationRecord
belongs_to :author
end
-class Author < ActiveRecord::Base
+class Author < ApplicationRecord
has_many :articles
def name_with_initial
"#{first_name.first}. #{last_name}"
@@ -1029,11 +1062,11 @@ Returns `check_box` tags for the collection of existing return values of `method
Example object structure for use with this method:
```ruby
-class Article < ActiveRecord::Base
+class Article < ApplicationRecord
has_and_belongs_to_many :authors
end
-class Author < ActiveRecord::Base
+class Author < ApplicationRecord
has_and_belongs_to_many :articles
def name_with_initial
"#{first_name.first}. #{last_name}"
@@ -1066,12 +1099,12 @@ Returns a string of `option` tags, like `options_from_collection_for_select`, bu
Example object structure for use with this method:
```ruby
-class Continent < ActiveRecord::Base
+class Continent < ApplicationRecord
has_many :countries
# attribs: id, name
end
-class Country < ActiveRecord::Base
+class Country < ApplicationRecord
belongs_to :continent
# attribs: id, name, continent_id
end
@@ -1214,7 +1247,7 @@ file_field_tag 'attachment'
#### form_tag
-Starts a form tag that points the action to an url configured with `url_for_options` just like `ActionController::Base#url_for`.
+Starts a form tag that points the action to a url configured with `url_for_options` just like `ActionController::Base#url_for`.
```html+erb
<%= form_tag '/articles' do %>
@@ -1443,12 +1476,12 @@ Sanitizes a block of CSS code.
Strips all link tags from text leaving just the link text.
```ruby
-strip_links("<a href="http://rubyonrails.org">Ruby on Rails</a>")
+strip_links('<a href="http://rubyonrails.org">Ruby on Rails</a>')
# => Ruby on Rails
```
```ruby
-strip_links("emails to <a href="mailto:me@email.com">me@email.com</a>.")
+strip_links('emails to <a href="mailto:me@email.com">me@email.com</a>.')
# => emails to me@email.com.
```
diff --git a/guides/source/active_job_basics.md b/guides/source/active_job_basics.md
index cb25a4c5f3..76c13f0ea9 100644
--- a/guides/source/active_job_basics.md
+++ b/guides/source/active_job_basics.md
@@ -70,34 +70,41 @@ Here's what a job looks like:
class GuestsCleanupJob < ActiveJob::Base
queue_as :default
- def perform(*args)
+ def perform(*guests)
# Do something later
end
end
```
+Note that you can define `perform` with as many arguments as you want.
+
### Enqueue the Job
Enqueue a job like so:
```ruby
-# Enqueue a job to be performed as soon the queuing system is
+# Enqueue a job to be performed as soon as the queuing system is
# free.
-MyJob.perform_later record
+GuestsCleanupJob.perform_later guest
```
```ruby
# Enqueue a job to be performed tomorrow at noon.
-MyJob.set(wait_until: Date.tomorrow.noon).perform_later(record)
+GuestsCleanupJob.set(wait_until: Date.tomorrow.noon).perform_later(guest)
```
```ruby
# Enqueue a job to be performed 1 week from now.
-MyJob.set(wait: 1.week).perform_later(record)
+GuestsCleanupJob.set(wait: 1.week).perform_later(guest)
```
-That's it!
+```ruby
+# `perform_now` and `perform_later` will call `perform` under the hood so
+# you can pass as many arguments as defined in the latter.
+GuestsCleanupJob.perform_later(guest1, guest2, filter: 'some_filter')
+```
+That's it!
Job Execution
-------------
@@ -129,10 +136,19 @@ module YourApp
end
```
-NOTE: Since jobs run in parallel to your Rails application, most queuing libraries
+### Starting the Backend
+
+Since jobs run in parallel to your Rails application, most queuing libraries
require that you start a library-specific queuing service (in addition to
-starting your Rails app) for the job processing to work. For information on
-how to do that refer to the documentation of your respective library.
+starting your Rails app) for the job processing to work. Refer to library
+documentation for instructions on starting your queue backend.
+
+Here is a noncomprehensive list of documentation:
+
+- [Sidekiq](https://github.com/mperham/sidekiq/wiki/Active-Job)
+- [Resque](https://github.com/resque/resque/wiki/ActiveJob)
+- [Sucker Punch](https://github.com/brandonhilkert/sucker_punch#active-job)
+- [Queue Classic](https://github.com/QueueClassic/queue_classic#active-job)
Queues
------
@@ -158,7 +174,7 @@ module YourApp
end
end
-# app/jobs/guests_cleanup.rb
+# app/jobs/guests_cleanup_job.rb
class GuestsCleanupJob < ActiveJob::Base
queue_as :low_priority
#....
@@ -181,7 +197,7 @@ module YourApp
end
end
-# app/jobs/guests_cleanup.rb
+# app/jobs/guests_cleanup_job.rb
class GuestsCleanupJob < ActiveJob::Base
queue_as :low_priority
#....
@@ -289,7 +305,7 @@ emails asynchronously:
```ruby
I18n.locale = :eo
-UserMailer.welcome(@user).deliver_later # Email will be localized to Esparanto.
+UserMailer.welcome(@user).deliver_later # Email will be localized to Esperanto.
```
diff --git a/guides/source/active_model_basics.md b/guides/source/active_model_basics.md
index 81e2a69504..c05e20aceb 100644
--- a/guides/source/active_model_basics.md
+++ b/guides/source/active_model_basics.md
@@ -8,10 +8,10 @@ classes. Active Model allows for Action Pack helpers to interact with
plain Ruby objects. Active Model also helps build custom ORMs for use
outside of the Rails framework.
-After reading this guide, you will know:
+After reading this guide, you will know:
* How an Active Record model behaves.
-* How Callbacks and validations work.
+* How Callbacks and validations work.
* How serializers work.
* The Rails internationalization (i18n) framework.
@@ -156,7 +156,7 @@ person.changed? # => false
person.first_name = "First Name"
person.first_name # => "First Name"
-# returns if any attribute has changed.
+# returns true if any of the attributes have unsaved changes, false otherwise.
person.changed? # => true
# returns a list of attributes that have changed before saving.
@@ -197,7 +197,7 @@ person.last_name_change # => nil
### Validations
-`ActiveModel::Validations` module adds the ability to validate class objects
+The `ActiveModel::Validations` module adds the ability to validate class objects
like in Active Record.
```ruby
@@ -292,7 +292,7 @@ objects.
### Serialization
-`ActiveModel::Serialization` provides a basic serialization for your object.
+`ActiveModel::Serialization` provides basic serialization for your object.
You need to declare an attributes hash which contains the attributes you want to
serialize. Attributes must be strings, not symbols.
@@ -339,7 +339,7 @@ class Person
end
```
-With the `as_json` you have a hash representing the model.
+With the `as_json` method you have a hash representing the model.
```ruby
person = Person.new
@@ -408,7 +408,7 @@ Person.human_attribute_name('name') # => "Nome"
### Lint Tests
-`ActiveModel::Lint::Tests` allow you to test whether an object is compliant with
+`ActiveModel::Lint::Tests` allows you to test whether an object is compliant with
the Active Model API.
* app/models/person.rb
@@ -428,14 +428,14 @@ the Active Model API.
class PersonTest < ActiveSupport::TestCase
include ActiveModel::Lint::Tests
- def setup
+ setup do
@model = Person.new
end
end
```
```bash
-$ rake test
+$ rails test
Run options: --seed 14596
@@ -461,14 +461,14 @@ an accessor named `password` with certain validations on it.
#### Requirements
-`ActiveModel::SecurePassword` depends on the [`bcrypt`](https://github.com/codahale/bcrypt-ruby 'BCrypt'),
+`ActiveModel::SecurePassword` depends on [`bcrypt`](https://github.com/codahale/bcrypt-ruby 'BCrypt'),
so include this gem in your Gemfile to use `ActiveModel::SecurePassword` correctly.
In order to make this work, the model must have an accessor named `password_digest`.
The `has_secure_password` will add the following validations on the `password` accessor:
1. Password should be present.
2. Password should be equal to its confirmation.
-3. This maximum length of a password is 72 (required by `bcrypt` on which ActiveModel::SecurePassword depends)
+3. The maximum length of a password is 72 (required by `bcrypt` on which ActiveModel::SecurePassword depends)
#### Examples
@@ -489,7 +489,7 @@ person.password = 'aditya'
person.password_confirmation = 'nomatch'
person.valid? # => false
-# When the length of password, exceeds 72.
+# When the length of password exceeds 72.
person.password = person.password_confirmation = 'a' * 100
person.valid? # => false
diff --git a/guides/source/active_record_basics.md b/guides/source/active_record_basics.md
index f4baf92228..fba89f9d13 100644
--- a/guides/source/active_record_basics.md
+++ b/guides/source/active_record_basics.md
@@ -132,17 +132,17 @@ Creating Active Record Models
-----------------------------
It is very easy to create Active Record models. All you have to do is to
-subclass the `ActiveRecord::Base` class and you're good to go:
+subclass the `ApplicationRecord` class and you're good to go:
```ruby
-class Product < ActiveRecord::Base
+class Product < ApplicationRecord
end
```
This will create a `Product` model, mapped to a `products` table at the
database. By doing this you'll also have the ability to map the columns of each
row in that table with the attributes of the instances of your model. Suppose
-that the `products` table was created using an SQL sentence like:
+that the `products` table was created using an SQL statement like:
```sql
CREATE TABLE products (
@@ -168,11 +168,12 @@ What if you need to follow a different naming convention or need to use your
Rails application with a legacy database? No problem, you can easily override
the default conventions.
-You can use the `ActiveRecord::Base.table_name=` method to specify the table
-name that should be used:
+`ApplicationRecord` inherits from `ActiveRecord::Base`, which defines a
+number of helpful methods. You can use the `ActiveRecord::Base.table_name=`
+method to specify the table name that should be used:
```ruby
-class Product < ActiveRecord::Base
+class Product < ApplicationRecord
self.table_name = "my_products"
end
```
@@ -193,7 +194,7 @@ It's also possible to override the column that should be used as the table's
primary key using the `ActiveRecord::Base.primary_key=` method:
```ruby
-class Product < ActiveRecord::Base
+class Product < ApplicationRecord
self.primary_key = "product_id"
end
```
@@ -320,7 +321,7 @@ they raise the exception `ActiveRecord::RecordInvalid` if validation fails.
A quick example to illustrate:
```ruby
-class User < ActiveRecord::Base
+class User < ApplicationRecord
validates :name, presence: true
end
@@ -350,7 +351,7 @@ database that Active Record supports using `rake`. Here's a migration that
creates a table:
```ruby
-class CreatePublications < ActiveRecord::Migration
+class CreatePublications < ActiveRecord::Migration[5.0]
def change
create_table :publications do |t|
t.string :title
@@ -368,8 +369,8 @@ end
```
Rails keeps track of which files have been committed to the database and
-provides rollback features. To actually create the table, you'd run `rake db:migrate`
-and to roll it back, `rake db:rollback`.
+provides rollback features. To actually create the table, you'd run `rails db:migrate`
+and to roll it back, `rails db:rollback`.
Note that the above code is database-agnostic: it will run in MySQL,
PostgreSQL, Oracle and others. You can learn more about migrations in the
diff --git a/guides/source/active_record_callbacks.md b/guides/source/active_record_callbacks.md
index 13989a3b33..d95c6c0e78 100644
--- a/guides/source/active_record_callbacks.md
+++ b/guides/source/active_record_callbacks.md
@@ -31,7 +31,7 @@ Callbacks are methods that get called at certain moments of an object's life cyc
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
+class User < ApplicationRecord
validates :login, :email, presence: true
before_validation :ensure_login_has_a_value
@@ -48,7 +48,7 @@ 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
+class User < ApplicationRecord
validates :login, :email, presence: true
before_create do
@@ -60,7 +60,7 @@ end
Callbacks can also be registered to only fire on certain life cycle events:
```ruby
-class User < ActiveRecord::Base
+class User < ApplicationRecord
before_validation :normalize_name, on: :create
# :on takes an array as well
@@ -126,7 +126,7 @@ The `after_find` callback will be called whenever Active Record loads a record f
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
+class User < ApplicationRecord
after_initialize do |user|
puts "You have initialized an object!"
end
@@ -151,7 +151,7 @@ You have initialized an object!
The `after_touch` callback will be called whenever an Active Record object is touched.
```ruby
-class User < ActiveRecord::Base
+class User < ApplicationRecord
after_touch do |user|
puts "You have touched an object"
end
@@ -168,14 +168,14 @@ You have touched an object
It can be used along with `belongs_to`:
```ruby
-class Employee < ActiveRecord::Base
+class Employee < ApplicationRecord
belongs_to :company, touch: true
after_touch do
puts 'An Employee was touched'
end
end
-class Company < ActiveRecord::Base
+class Company < ApplicationRecord
has_many :employees
after_touch :log_when_employees_or_company_touched
@@ -266,11 +266,11 @@ Relational Callbacks
Callbacks work through model relationships, and can even be defined by them. Suppose an example where a user has many articles. A user's articles 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 `Article` model:
```ruby
-class User < ActiveRecord::Base
+class User < ApplicationRecord
has_many :articles, dependent: :destroy
end
-class Article < ActiveRecord::Base
+class Article < ApplicationRecord
after_destroy :log_destroy_action
def log_destroy_action
@@ -297,7 +297,7 @@ As with validations, we can also make the calling of a callback method condition
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
+class Order < ApplicationRecord
before_save :normalize_card_number, if: :paid_with_card?
end
```
@@ -307,7 +307,7 @@ end
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
+class Order < ApplicationRecord
before_save :normalize_card_number, if: "paid_with_card?"
end
```
@@ -317,7 +317,7 @@ end
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
+class Order < ApplicationRecord
before_save :normalize_card_number,
if: Proc.new { |order| order.paid_with_card? }
end
@@ -328,7 +328,7 @@ end
When writing conditional callbacks, it is possible to mix both `:if` and `:unless` in the same callback declaration:
```ruby
-class Comment < ActiveRecord::Base
+class Comment < ApplicationRecord
after_create :send_email_to_author, if: :author_wants_emails?,
unless: Proc.new { |comment| comment.article.ignore_comments? }
end
@@ -354,7 +354,7 @@ 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
+class PictureFile < ApplicationRecord
after_destroy PictureFileCallbacks.new
end
```
@@ -374,7 +374,7 @@ end
If the callback method is declared this way, it won't be necessary to instantiate a `PictureFileCallbacks` object.
```ruby
-class PictureFile < ActiveRecord::Base
+class PictureFile < ApplicationRecord
after_destroy PictureFileCallbacks
end
```
@@ -398,7 +398,7 @@ end
By using the `after_commit` callback we can account for this case.
```ruby
-class PictureFile < ActiveRecord::Base
+class PictureFile < ApplicationRecord
after_commit :delete_picture_file_from_disk, on: [:destroy]
def delete_picture_file_from_disk
@@ -412,4 +412,23 @@ end
NOTE: the `:on` option specifies when a callback will be fired. If you
don't supply the `:on` option the callback will fire for every action.
+Since using `after_commit` callback only on create, update or delete is
+common, there are aliases for those operations:
+
+* `after_create_commit`
+* `after_update_commit`
+* `after_destroy_commit`
+
+```ruby
+class PictureFile < ApplicationRecord
+ after_destroy_commit :delete_picture_file_from_disk
+
+ def delete_picture_file_from_disk
+ if File.exist?(filepath)
+ File.delete(filepath)
+ end
+ end
+end
+```
+
WARNING. 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_migrations.md b/guides/source/active_record_migrations.md
index 4e5902fb3d..a4a23395fb 100644
--- a/guides/source/active_record_migrations.md
+++ b/guides/source/active_record_migrations.md
@@ -35,7 +35,7 @@ history to the latest version. Active Record will also update your
Here's an example of a migration:
```ruby
-class CreateProducts < ActiveRecord::Migration
+class CreateProducts < ActiveRecord::Migration[5.0]
def change
create_table :products do |t|
t.string :name
@@ -72,7 +72,7 @@ If you wish for a migration to do something that Active Record doesn't know how
to reverse, you can use `reversible`:
```ruby
-class ChangeProductsPrice < ActiveRecord::Migration
+class ChangeProductsPrice < ActiveRecord::Migration[5.0]
def change
reversible do |dir|
change_table :products do |t|
@@ -87,7 +87,7 @@ end
Alternatively, you can use `up` and `down` instead of `change`:
```ruby
-class ChangeProductsPrice < ActiveRecord::Migration
+class ChangeProductsPrice < ActiveRecord::Migration[5.0]
def up
change_table :products do |t|
t.change :price, :string
@@ -129,7 +129,7 @@ $ bin/rails generate migration AddPartNumberToProducts
This will create an empty but appropriately named migration:
```ruby
-class AddPartNumberToProducts < ActiveRecord::Migration
+class AddPartNumberToProducts < ActiveRecord::Migration[5.0]
def change
end
end
@@ -146,7 +146,7 @@ $ bin/rails generate migration AddPartNumberToProducts part_number:string
will generate
```ruby
-class AddPartNumberToProducts < ActiveRecord::Migration
+class AddPartNumberToProducts < ActiveRecord::Migration[5.0]
def change
add_column :products, :part_number, :string
end
@@ -162,7 +162,7 @@ $ bin/rails generate migration AddPartNumberToProducts part_number:string:index
will generate
```ruby
-class AddPartNumberToProducts < ActiveRecord::Migration
+class AddPartNumberToProducts < ActiveRecord::Migration[5.0]
def change
add_column :products, :part_number, :string
add_index :products, :part_number
@@ -180,7 +180,7 @@ $ bin/rails generate migration RemovePartNumberFromProducts part_number:string
generates
```ruby
-class RemovePartNumberFromProducts < ActiveRecord::Migration
+class RemovePartNumberFromProducts < ActiveRecord::Migration[5.0]
def change
remove_column :products, :part_number, :string
end
@@ -196,7 +196,7 @@ $ bin/rails generate migration AddDetailsToProducts part_number:string price:dec
generates
```ruby
-class AddDetailsToProducts < ActiveRecord::Migration
+class AddDetailsToProducts < ActiveRecord::Migration[5.0]
def change
add_column :products, :part_number, :string
add_column :products, :price, :decimal
@@ -215,7 +215,7 @@ $ bin/rails generate migration CreateProducts name:string part_number:string
generates
```ruby
-class CreateProducts < ActiveRecord::Migration
+class CreateProducts < ActiveRecord::Migration[5.0]
def change
create_table :products do |t|
t.string :name
@@ -239,7 +239,7 @@ $ bin/rails generate migration AddUserRefToProducts user:references
generates
```ruby
-class AddUserRefToProducts < ActiveRecord::Migration
+class AddUserRefToProducts < ActiveRecord::Migration[5.0]
def change
add_reference :products, :user, index: true, foreign_key: true
end
@@ -257,7 +257,7 @@ $ bin/rails g migration CreateJoinTableCustomerProduct customer product
will produce the following migration:
```ruby
-class CreateJoinTableCustomerProduct < ActiveRecord::Migration
+class CreateJoinTableCustomerProduct < ActiveRecord::Migration[5.0]
def change
create_join_table :customers, :products do |t|
# t.index [:customer_id, :product_id]
@@ -281,7 +281,7 @@ $ bin/rails generate model Product name:string description:text
will create a migration that looks like this
```ruby
-class CreateProducts < ActiveRecord::Migration
+class CreateProducts < ActiveRecord::Migration[5.0]
def change
create_table :products do |t|
t.string :name
@@ -309,7 +309,7 @@ $ bin/rails generate migration AddDetailsToProducts 'price:decimal{5,2}' supplie
will produce a migration that looks like this
```ruby
-class AddDetailsToProducts < ActiveRecord::Migration
+class AddDetailsToProducts < ActiveRecord::Migration[5.0]
def change
add_column :products, :price, :decimal, precision: 5, scale: 2
add_reference :products, :supplier, polymorphic: true, index: true
@@ -454,8 +454,6 @@ number of digits after the decimal point.
are using a dynamic value (such as a date), the default will only be calculated
the first time (i.e. on the date the migration is applied).
* `index` Adds an index for the column.
-* `required` Adds `required: true` for `belongs_to` associations and
-`null: false` to the column in the migration.
Some adapters may support additional options; see the adapter specific API docs
for further information.
@@ -522,20 +520,27 @@ 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`
-* `add_reference`
-* `add_timestamps`
-* `add_foreign_key`
-* `create_table`
-* `create_join_table`
-* `drop_table` (must supply a block)
-* `drop_join_table` (must supply a block)
-* `remove_timestamps`
-* `rename_column`
-* `rename_index`
-* `remove_reference`
-* `rename_table`
+* add_column
+* add_foreign_key
+* add_index
+* add_reference
+* add_timestamps
+* change_column_default (must supply a :from and :to option)
+* change_column_null
+* create_join_table
+* create_table
+* disable_extension
+* drop_join_table
+* drop_table (must supply a block)
+* enable_extension
+* remove_column (must supply a type)
+* remove_foreign_key (must supply a second table)
+* remove_index
+* remove_reference
+* remove_timestamps
+* rename_column
+* rename_index
+* rename_table
`change_table` is also reversible, as long as the block does not call `change`,
`change_default` or `remove`.
@@ -558,7 +563,7 @@ to reverse. You can use `reversible` to specify what to do when running a
migration and what else to do when reverting it. For example:
```ruby
-class ExampleMigration < ActiveRecord::Migration
+class ExampleMigration < ActiveRecord::Migration[5.0]
def change
create_table :distributors do |t|
t.string :zipcode
@@ -611,7 +616,7 @@ is wise to perform the transformations in precisely the reverse order they were
made in the `up` method. The example in the `reversible` section is equivalent to:
```ruby
-class ExampleMigration < ActiveRecord::Migration
+class ExampleMigration < ActiveRecord::Migration[5.0]
def up
create_table :distributors do |t|
t.string :zipcode
@@ -652,9 +657,9 @@ can't be done.
You can use Active Record's ability to rollback migrations using the `revert` method:
```ruby
-require_relative '2012121212_example_migration'
+require_relative '20121212123456_example_migration'
-class FixupExampleMigration < ActiveRecord::Migration
+class FixupExampleMigration < ActiveRecord::Migration[5.0]
def change
revert ExampleMigration
@@ -672,7 +677,7 @@ is later decided it would be best to use Active Record validations,
in place of the `CHECK` constraint, to verify the zipcode.
```ruby
-class DontUseConstraintForZipcodeValidationMigration < ActiveRecord::Migration
+class DontUseConstraintForZipcodeValidationMigration < ActiveRecord::Migration[5.0]
def change
revert do
# copy-pasted code from ExampleMigration
@@ -715,7 +720,7 @@ Running 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
-`rake db:migrate`. In its most basic form it just runs the `change` or `up`
+`rails db:migrate`. In its most basic form it just runs the `change` or `up`
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.
@@ -729,7 +734,7 @@ is the numerical prefix on the migration's filename. For example, to migrate
to version 20080906120000 run:
```bash
-$ bin/rake db:migrate VERSION=20080906120000
+$ bin/rails db:migrate VERSION=20080906120000
```
If version 20080906120000 is greater than the current version (i.e., it is
@@ -746,7 +751,7 @@ mistake in it and wish to correct it. Rather than tracking down the version
number associated with the previous migration you can run:
```bash
-$ bin/rake db:rollback
+$ bin/rails db:rollback
```
This will rollback the latest migration, either by reverting the `change`
@@ -754,7 +759,7 @@ method or by running the `down` method. If you need to undo
several migrations you can provide a `STEP` parameter:
```bash
-$ bin/rake db:rollback STEP=3
+$ bin/rails db:rollback STEP=3
```
will revert the last 3 migrations.
@@ -764,7 +769,7 @@ back up again. As with the `db:rollback` task, you can use the `STEP` parameter
if you need to go more than one version back, for example:
```bash
-$ bin/rake db:migrate:redo STEP=3
+$ bin/rails db:migrate:redo STEP=3
```
Neither of these Rake tasks do anything you could not do with `db:migrate`. They
@@ -773,17 +778,17 @@ version to migrate to.
### Setup the Database
-The `rake db:setup` task will create the database, load the schema and initialize
+The `rails db:setup` task will create the database, load the schema and initialize
it with the seed data.
### Resetting the Database
-The `rake db:reset` task will drop the database and set it up again. This is
+The `rails db:reset` task will drop the database and set it up again. This is
functionally equivalent to `rake db:drop db:setup`.
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
+contents of the current `db/schema.rb` or `db/structure.sql` file. If a migration can't be rolled back,
+`rails db:reset` may not help you. To find out more about dumping the schema see
[Schema Dumping and You](#schema-dumping-and-you) section.
### Running Specific Migrations
@@ -794,7 +799,7 @@ the corresponding migration will have its `change`, `up` or `down` method
invoked, for example:
```bash
-$ bin/rake db:migrate:up VERSION=20080906120000
+$ bin/rails db:migrate:up VERSION=20080906120000
```
will run the 20080906120000 migration by running the `change` method (or the
@@ -810,7 +815,7 @@ To run migrations against another environment you can specify it using the
migrations against the `test` environment you could run:
```bash
-$ bin/rake db:migrate RAILS_ENV=test
+$ bin/rails db:migrate RAILS_ENV=test
```
### Changing the Output of Running Migrations
@@ -836,7 +841,7 @@ Several methods are provided in migrations that allow you to control all this:
For example, this migration:
```ruby
-class CreateProducts < ActiveRecord::Migration
+class CreateProducts < ActiveRecord::Migration[5.0]
def change
suppress_messages do
create_table :products do |t|
@@ -871,7 +876,7 @@ generates the following output
== CreateProducts: migrated (10.0054s) =======================================
```
-If you want Active Record to not output anything, then running `rake db:migrate
+If you want Active Record to not output anything, then running `rails db:migrate
VERBOSE=false` will suppress all output.
Changing Existing Migrations
@@ -880,9 +885,9 @@ 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
+nothing when you run `rails 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.
+`rails 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
@@ -964,7 +969,7 @@ 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 PostgreSQL, the `pg_dump`
+rails 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.
@@ -1010,7 +1015,7 @@ to add or modify data. This is useful in an existing database that can't be dest
and recreated, such as a production database.
```ruby
-class AddInitialProducts < ActiveRecord::Migration
+class AddInitialProducts < ActiveRecord::Migration[5.0]
def up
5.times do |i|
Product.create(name: "Product ##{i}", description: "A product.")
@@ -1027,7 +1032,7 @@ To add initial data after a database is created, Rails has a built-in
'seeds' feature that makes the process quick and easy. This is especially
useful when reloading the database frequently in development and test environments.
It's easy to get started with this feature: just fill up `db/seeds.rb` with some
-Ruby code, and run `rake db:seed`:
+Ruby code, and run `rails db:seed`:
```ruby
5.times do |i|
diff --git a/guides/source/active_record_postgresql.md b/guides/source/active_record_postgresql.md
index 9d495dfacb..b592209d4b 100644
--- a/guides/source/active_record_postgresql.md
+++ b/guides/source/active_record_postgresql.md
@@ -39,7 +39,7 @@ create_table :documents do |t|
end
# app/models/document.rb
-class Document < ActiveRecord::Base
+class Document < ApplicationRecord
end
# Usage
@@ -63,7 +63,7 @@ add_index :books, :tags, using: 'gin'
add_index :books, :ratings, using: 'gin'
# app/models/book.rb
-class Book < ActiveRecord::Base
+class Book < ApplicationRecord
end
# Usage
@@ -85,7 +85,7 @@ Book.where("array_length(ratings, 1) >= 3")
* [type definition](http://www.postgresql.org/docs/current/static/hstore.html)
-NOTE: you need to enable the `hstore` extension to use hstore.
+NOTE: You need to enable the `hstore` extension to use hstore.
```ruby
# db/migrate/20131009135255_create_profiles.rb
@@ -97,7 +97,7 @@ ActiveRecord::Schema.define do
end
# app/models/profile.rb
-class Profile < ActiveRecord::Base
+class Profile < ApplicationRecord
end
# Usage
@@ -122,7 +122,7 @@ create_table :events do |t|
end
# app/models/event.rb
-class Event < ActiveRecord::Base
+class Event < ApplicationRecord
end
# Usage
@@ -150,7 +150,7 @@ create_table :events do |t|
end
# app/models/event.rb
-class Event < ActiveRecord::Base
+class Event < ApplicationRecord
end
# Usage
@@ -200,7 +200,7 @@ create_table :contacts do |t|
end
# app/models/contact.rb
-class Contact < ActiveRecord::Base
+class Contact < ApplicationRecord
end
# Usage
@@ -220,15 +220,26 @@ normal text columns:
```ruby
# db/migrate/20131220144913_create_articles.rb
-execute <<-SQL
- CREATE TYPE article_status AS ENUM ('draft', 'published');
-SQL
-create_table :articles do |t|
- t.column :status, :article_status
+def up
+ execute <<-SQL
+ CREATE TYPE article_status AS ENUM ('draft', 'published');
+ SQL
+ create_table :articles do |t|
+ t.column :status, :article_status
+ end
+end
+
+# NOTE: It's important to drop table before dropping enum.
+def down
+ drop_table :articles
+
+ execute <<-SQL
+ DROP TYPE article_status;
+ SQL
end
# app/models/article.rb
-class Article < ActiveRecord::Base
+class Article < ApplicationRecord
end
# Usage
@@ -240,13 +251,40 @@ article.status = "published"
article.save!
```
+To add a new value before/after existing one you should use [ALTER TYPE](http://www.postgresql.org/docs/current/static/sql-altertype.html):
+
+```ruby
+# db/migrate/20150720144913_add_new_state_to_articles.rb
+# NOTE: ALTER TYPE ... ADD VALUE cannot be executed inside of a transaction block so here we are using disable_ddl_transaction!
+disable_ddl_transaction!
+
+def up
+ execute <<-SQL
+ ALTER TYPE article_status ADD VALUE IF NOT EXISTS 'archived' AFTER 'published';
+ SQL
+end
+```
+
+NOTE: ENUM values can't be dropped currently. You can read why [here](http://www.postgresql.org/message-id/29F36C7C98AB09499B1A209D48EAA615B7653DBC8A@mail2a.alliedtesting.com).
+
+Hint: to show all the values of the all enums you have, you should call this query in `bin/rails db` or `psql` console:
+
+```sql
+SELECT n.nspname AS enum_schema,
+ t.typname AS enum_name,
+ e.enumlabel AS enum_value
+ FROM pg_type t
+ JOIN pg_enum e ON t.oid = e.enumtypid
+ JOIN pg_catalog.pg_namespace n ON n.oid = t.typnamespace
+```
+
### UUID
* [type definition](http://www.postgresql.org/docs/current/static/datatype-uuid.html)
* [pgcrypto generator function](http://www.postgresql.org/docs/current/static/pgcrypto.html#AEN159361)
* [uuid-ossp generator functions](http://www.postgresql.org/docs/current/static/uuid-ossp.html)
-NOTE: you need to enable the `pgcrypto` (only PostgreSQL >= 9.4) or `uuid-ossp`
+NOTE: You need to enable the `pgcrypto` (only PostgreSQL >= 9.4) or `uuid-ossp`
extension to use uuid.
```ruby
@@ -256,7 +294,7 @@ create_table :revisions do |t|
end
# app/models/revision.rb
-class Revision < ActiveRecord::Base
+class Revision < ApplicationRecord
end
# Usage
@@ -279,12 +317,12 @@ create_table :comments, id: :uuid, default: 'gen_random_uuid()' do |t|
end
# app/models/post.rb
-class Post < ActiveRecord::Base
+class Post < ApplicationRecord
has_many :comments
end
# app/models/comment.rb
-class Comment < ActiveRecord::Base
+class Comment < ApplicationRecord
belongs_to :post
end
```
@@ -303,7 +341,7 @@ create_table :users, force: true do |t|
end
# app/models/device.rb
-class User < ActiveRecord::Base
+class User < ApplicationRecord
end
# Usage
@@ -332,7 +370,7 @@ create_table(:devices, force: true) do |t|
end
# app/models/device.rb
-class Device < ActiveRecord::Base
+class Device < ApplicationRecord
end
# Usage
@@ -361,7 +399,7 @@ A point is casted to an array containing `x` and `y` coordinates.
UUID Primary Keys
-----------------
-NOTE: you need to enable the `pgcrypto` (only PostgreSQL >= 9.4) or `uuid-ossp`
+NOTE: You need to enable the `pgcrypto` (only PostgreSQL >= 9.4) or `uuid-ossp`
extension to generate random UUIDs.
```ruby
@@ -372,7 +410,7 @@ create_table :devices, id: :uuid, default: 'gen_random_uuid()' do |t|
end
# app/models/device.rb
-class Device < ActiveRecord::Base
+class Device < ApplicationRecord
end
# Usage
@@ -396,7 +434,7 @@ end
execute "CREATE INDEX documents_idx ON documents USING gin(to_tsvector('english', title || ' ' || body));"
# app/models/document.rb
-class Document < ActiveRecord::Base
+class Document < ApplicationRecord
end
# Usage
@@ -446,7 +484,7 @@ CREATE VIEW articles AS
SQL
# app/models/article.rb
-class Article < ActiveRecord::Base
+class Article < ApplicationRecord
self.primary_key = "id"
def archive!
update_attribute :archived, true
diff --git a/guides/source/active_record_querying.md b/guides/source/active_record_querying.md
index 4b4d70d3ce..4606ac4683 100644
--- a/guides/source/active_record_querying.md
+++ b/guides/source/active_record_querying.md
@@ -10,7 +10,7 @@ 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 use dynamic finder methods.
* How to use method chaining to use multiple ActiveRecord methods together.
* How to check for the existence of particular records.
* How to perform various calculations on Active Record models.
@@ -25,7 +25,7 @@ Code examples throughout this guide will refer to one or more of the following m
TIP: All of the following models use `id` as the primary key, unless specified otherwise.
```ruby
-class Client < ActiveRecord::Base
+class Client < ApplicationRecord
has_one :address
has_many :orders
has_and_belongs_to_many :roles
@@ -33,19 +33,19 @@ end
```
```ruby
-class Address < ActiveRecord::Base
+class Address < ApplicationRecord
belongs_to :client
end
```
```ruby
-class Order < ActiveRecord::Base
+class Order < ApplicationRecord
belongs_to :client, counter_cache: true
end
```
```ruby
-class Role < ActiveRecord::Base
+class Role < ApplicationRecord
has_and_belongs_to_many :clients
end
```
@@ -69,6 +69,7 @@ The methods are:
* `having`
* `includes`
* `joins`
+* `left_outer_joins`
* `limit`
* `lock`
* `none`
@@ -80,7 +81,7 @@ The methods are:
* `reorder`
* `reverse_order`
* `select`
-* `uniq`
+* `distinct`
* `where`
All of the above methods return an instance of `ActiveRecord::Relation`.
@@ -184,6 +185,8 @@ SELECT * FROM clients ORDER BY clients.id ASC LIMIT 1
The `first` method returns `nil` if no matching record is found and no exception will be raised.
+If your [default scope](active_record_querying.html#applying-a-default-scope) contains an order method, `first` will return the first record according to this ordering.
+
You can pass in a numerical argument to the `first` method to return up to that number of results. For example
```ruby
@@ -220,6 +223,8 @@ SELECT * FROM clients ORDER BY clients.id DESC LIMIT 1
The `last` method returns `nil` if no matching record is found and no exception will be raised.
+If your [default scope](active_record_querying.html#applying-a-default-scope) contains an order method, `last` will return the last record according to this ordering.
+
You can pass in a numerical argument to the `last` method to return up to that number of results. For example
```ruby
@@ -341,8 +346,6 @@ User.find_each(begin_at: 2000, batch_size: 5000) do |user|
end
```
-Another example would be if you wanted multiple workers handling the same processing queue. You could have each worker handle 10000 records by setting the appropriate `:begin_at` option on each worker.
-
**`:end_at`**
Similar to the `:begin_at` option, `:end_at` allows you to configure the last ID of the sequence whenever the highest ID is not the one you need.
@@ -356,6 +359,10 @@ User.find_each(begin_at: 2000, end_at: 10000, batch_size: 5000) do |user|
end
```
+Another example would be if you wanted multiple workers handling the same
+processing queue. You could have each worker handle 10000 records by setting the
+appropriate `:begin_at` and `:end_at` options on each worker.
+
#### `find_in_batches`
The `find_in_batches` method is similar to `find_each`, since both retrieve batches of records. The difference is that `find_in_batches` yields _batches_ to the block as an array of models, instead of individually. The following example will yield to the supplied block an array of up to 1000 invoices at a time, with the final block containing any remaining invoices:
@@ -390,7 +397,7 @@ Now what if that number could vary, say as an argument from somewhere? The find
Client.where("orders_count = ?", params[:orders])
```
-Active Record will go through the first element in the conditions value and any additional elements will replace the question marks `(?)` in the first element.
+Active Record will take the first argument as the conditions string and any additional arguments will replace the question marks `(?)` in it.
If you want to specify multiple conditions:
@@ -418,7 +425,7 @@ TIP: For more information on the dangers of SQL injection, see the [Ruby on Rail
#### Placeholder Conditions
-Similar to the `(?)` replacement style of params, you can also specify keys/values hash in your array conditions:
+Similar to the `(?)` replacement style of params, you can also specify keys in your conditions string along with a corresponding keys/values hash:
```ruby
Client.where("created_at >= :start_date AND created_at <= :end_date",
@@ -429,7 +436,7 @@ This makes for clearer readability if you have a large number of variable condit
### Hash Conditions
-Active Record also allows you to pass in hash conditions which can increase the readability of your conditions syntax. With hash conditions, you pass in a hash with keys of the fields you want conditionalised and the values of how you want to conditionalise them:
+Active Record also allows you to pass in hash conditions which can increase the readability of your conditions syntax. With hash conditions, you pass in a hash with keys of the fields you want qualified and the values of how you want to qualify them:
NOTE: Only equality, range and subset checking are possible with Hash conditions.
@@ -529,7 +536,7 @@ Client.order("orders_count ASC, created_at DESC")
Client.order("orders_count ASC", "created_at DESC")
```
-If you want to call `order` multiple times e.g. in different context, new order will append previous one:
+If you want to call `order` multiple times, subsequent orders will be appended to the first:
```ruby
Client.order("orders_count ASC").order("created_at DESC")
@@ -617,9 +624,9 @@ SELECT * FROM clients LIMIT 5 OFFSET 30
Group
-----
-To apply a `GROUP BY` clause to the SQL fired by the finder, you can specify the `group` method on the find.
+To apply a `GROUP BY` clause to the SQL fired by the finder, you can use the `group` method.
-For example, if you want to find a collection of the dates orders were created on:
+For example, if you want to find a collection of the dates on which orders were created:
```ruby
Order.select("date(created_at) as ordered_date, sum(price) as total_price").group("date(created_at)")
@@ -637,7 +644,7 @@ GROUP BY date(created_at)
### Total of grouped items
-To get the total of grouped items on a single query call `count` after the `group`.
+To get the total of grouped items on a single query, call `count` after the `group`.
```ruby
Order.group(:status).count
@@ -673,7 +680,7 @@ GROUP BY date(created_at)
HAVING sum(price) > 100
```
-This will return single order objects for each day, but only those that are ordered more than $100 in a day.
+This returns the date and total price for each order object, grouped by the day they were ordered and where the price is more than $100.
Overriding Conditions
---------------------
@@ -703,8 +710,7 @@ Article.where(id: 10, trashed: false).unscope(where: :id)
# SELECT "articles".* FROM "articles" WHERE trashed = 0
```
-A relation which has used `unscope` will affect any relation it is
-merged in to:
+A relation which has used `unscope` will affect any relation into which it is merged:
```ruby
Article.order('id asc').merge(Article.unscope(:order))
@@ -734,7 +740,7 @@ SELECT "articles".* FROM "articles" WHERE (id > 10) ORDER BY id desc LIMIT 20
The `reorder` method overrides the default scope order. For example:
```ruby
-class Article < ActiveRecord::Base
+class Article < ApplicationRecord
has_many :comments, -> { order('posted_at DESC') }
end
@@ -748,7 +754,7 @@ SELECT * FROM articles WHERE id = 10
SELECT * FROM comments WHERE article_id = 10 ORDER BY name
```
-In case the `reorder` clause is not used, the SQL executed would be:
+In the case where the `reorder` clause is not used, the SQL executed would be:
```sql
SELECT * FROM articles WHERE id = 10
@@ -837,7 +843,7 @@ end
Readonly Objects
----------------
-Active Record provides `readonly` method on a relation to explicitly disallow modification of any of the returned objects. Any attempt to alter a readonly record will not succeed, raising an `ActiveRecord::ReadOnlyRecord` exception.
+Active Record provides the `readonly` method on a relation to explicitly disallow modification of any of the returned objects. Any attempt to alter a readonly record will not succeed, raising an `ActiveRecord::ReadOnlyRecord` exception.
```ruby
client = Client.readonly.first
@@ -883,7 +889,7 @@ This behavior can be turned off by setting `ActiveRecord::Base.lock_optimistical
To override the name of the `lock_version` column, `ActiveRecord::Base` provides a class attribute called `locking_column`:
```ruby
-class Client < ActiveRecord::Base
+class Client < ApplicationRecord
self.locking_column = :lock_client_column
end
```
@@ -934,58 +940,63 @@ end
Joining Tables
--------------
-Active Record provides a finder method called `joins` for specifying `JOIN` clauses on the resulting SQL. There are multiple ways to use the `joins` method.
+Active Record provides two finder methods for specifying `JOIN` clauses on the
+resulting SQL: `joins` and `left_outer_joins`.
+While `joins` should be used for `INNER JOIN` or custom queries,
+`left_outer_joins` is used for queries using `LEFT OUTER JOIN`.
-### Using a String SQL Fragment
+### `joins`
+
+There are multiple ways to use the `joins` method.
+
+#### Using a String SQL Fragment
You can just supply the raw SQL specifying the `JOIN` clause to `joins`:
```ruby
-Client.joins('LEFT OUTER JOIN addresses ON addresses.client_id = clients.id')
+Author.joins("INNER JOIN posts ON posts.author_id = author.id AND posts.published = 't'")
```
This will result in the following SQL:
```sql
-SELECT clients.* FROM clients LEFT OUTER JOIN addresses ON addresses.client_id = clients.id
+SELECT clients.* FROM clients INNER JOIN posts ON posts.author_id = author.id AND posts.published = 't'
```
-### Using Array/Hash of Named Associations
-
-WARNING: This method only works with `INNER JOIN`.
+#### Using Array/Hash of Named Associations
Active Record lets you use the names of the [associations](association_basics.html) defined on the model as a shortcut for specifying `JOIN` clauses for those associations when using the `joins` method.
For example, consider the following `Category`, `Article`, `Comment`, `Guest` and `Tag` models:
```ruby
-class Category < ActiveRecord::Base
+class Category < ApplicationRecord
has_many :articles
end
-class Article < ActiveRecord::Base
+class Article < ApplicationRecord
belongs_to :category
has_many :comments
has_many :tags
end
-class Comment < ActiveRecord::Base
+class Comment < ApplicationRecord
belongs_to :article
has_one :guest
end
-class Guest < ActiveRecord::Base
+class Guest < ApplicationRecord
belongs_to :comment
end
-class Tag < ActiveRecord::Base
+class Tag < ApplicationRecord
belongs_to :article
end
```
Now all of the following will produce the expected join queries using `INNER JOIN`:
-#### Joining a Single Association
+##### Joining a Single Association
```ruby
Category.joins(:articles)
@@ -998,7 +1009,7 @@ SELECT categories.* FROM categories
INNER JOIN articles ON articles.category_id = categories.id
```
-Or, in English: "return a Category object for all categories with articles". Note that you will see duplicate categories if more than one article has the same category. If you want unique categories, you can use `Category.joins(:articles).uniq`.
+Or, in English: "return a Category object for all categories with articles". Note that you will see duplicate categories if more than one article has the same category. If you want unique categories, you can use `Category.joins(:articles).distinct`.
#### Joining Multiple Associations
@@ -1016,7 +1027,7 @@ SELECT articles.* FROM articles
Or, in English: "return all articles that have a category and at least one comment". Note again that articles with multiple comments will show up multiple times.
-#### Joining Nested Associations (Single Level)
+##### Joining Nested Associations (Single Level)
```ruby
Article.joins(comments: :guest)
@@ -1032,7 +1043,7 @@ SELECT articles.* FROM articles
Or, in English: "return all articles that have a comment made by a guest."
-#### Joining Nested Associations (Multiple Level)
+##### Joining Nested Associations (Multiple Level)
```ruby
Category.joins(articles: [{ comments: :guest }, :tags])
@@ -1048,9 +1059,9 @@ SELECT categories.* FROM categories
INNER JOIN tags ON tags.article_id = articles.id
```
-### Specifying Conditions on the Joined Tables
+#### Specifying Conditions on the Joined Tables
-You can specify conditions on the joined tables using the regular [Array](#array-conditions) and [String](#pure-string-conditions) conditions. [Hash conditions](#hash-conditions) provides a special syntax for specifying conditions for the joined tables:
+You can specify conditions on the joined tables using the regular [Array](#array-conditions) and [String](#pure-string-conditions) conditions. [Hash conditions](#hash-conditions) provide a special syntax for specifying conditions for the joined tables:
```ruby
time_range = (Time.now.midnight - 1.day)..Time.now.midnight
@@ -1066,6 +1077,26 @@ Client.joins(:orders).where(orders: { created_at: time_range })
This will find all clients who have orders that were created yesterday, again using a `BETWEEN` SQL expression.
+### `left_outer_joins`
+
+If you want to select a set of records whether or not they have associated
+records you can use the `left_outer_joins` method.
+
+```ruby
+Author.left_outer_joins(:posts).uniq.select('authors.*, COUNT(posts.*) AS posts_count').group('authors.id')
+```
+
+Which produces:
+
+```sql
+SELECT DISTINCT authors.*, COUNT(posts.*) AS posts_count FROM "authors"
+LEFT OUTER JOIN posts ON posts.author_id = authors.id GROUP BY authors.id
+```
+
+Which means: "return all authors with their count of posts, whether or not they
+have any posts at all"
+
+
Eager Loading Associations
--------------------------
@@ -1089,7 +1120,7 @@ This code looks fine at the first sight. But the problem lies within the total n
Active Record lets you specify in advance all the associations that are going to be loaded. This is possible by specifying the `includes` method of the `Model.find` call. With `includes`, Active Record ensures that all of the specified associations are loaded using the minimum possible number of queries.
-Revisiting the above case, we could rewrite `Client.limit(10)` to use eager load addresses:
+Revisiting the above case, we could rewrite `Client.limit(10)` to eager load addresses:
```ruby
clients = Client.includes(:address).limit(10)
@@ -1168,7 +1199,7 @@ Scoping allows you to specify commonly-used queries which can be referenced as m
To define a simple scope, we use the `scope` method inside the class, passing the query that we'd like to run when this scope is called:
```ruby
-class Article < ActiveRecord::Base
+class Article < ApplicationRecord
scope :published, -> { where(published: true) }
end
```
@@ -1176,7 +1207,7 @@ end
This is exactly the same as defining a class method, and which you use is a matter of personal preference:
```ruby
-class Article < ActiveRecord::Base
+class Article < ApplicationRecord
def self.published
where(published: true)
end
@@ -1186,7 +1217,7 @@ end
Scopes are also chainable within scopes:
```ruby
-class Article < ActiveRecord::Base
+class Article < ApplicationRecord
scope :published, -> { where(published: true) }
scope :published_and_commented, -> { published.where("comments_count > 0") }
end
@@ -1210,7 +1241,7 @@ category.articles.published # => [published articles belonging to this category]
Your scope can take arguments:
```ruby
-class Article < ActiveRecord::Base
+class Article < ApplicationRecord
scope :created_before, ->(time) { where("created_at < ?", time) }
end
```
@@ -1224,7 +1255,7 @@ Article.created_before(Time.zone.now)
However, this is just duplicating the functionality that would be provided to you by a class method.
```ruby
-class Article < ActiveRecord::Base
+class Article < ApplicationRecord
def self.created_before(time)
where("created_at < ?", time)
end
@@ -1243,7 +1274,7 @@ If we wish for a scope to be applied across all queries to the model we can use
`default_scope` method within the model itself.
```ruby
-class Client < ActiveRecord::Base
+class Client < ApplicationRecord
default_scope { where("removed_at IS NULL") }
end
```
@@ -1259,7 +1290,7 @@ If you need to do more complex things with a default scope, you can alternativel
define it as a class method:
```ruby
-class Client < ActiveRecord::Base
+class Client < ApplicationRecord
def self.default_scope
# Should return an ActiveRecord::Relation.
end
@@ -1270,7 +1301,7 @@ NOTE: The `default_scope` is also applied while creating/building a record.
It is not applied while updating a record. E.g.:
```ruby
-class Client < ActiveRecord::Base
+class Client < ApplicationRecord
default_scope { where(active: true) }
end
@@ -1283,7 +1314,7 @@ Client.unscoped.new # => #<Client id: nil, active: nil>
Just like `where` clauses scopes are merged using `AND` conditions.
```ruby
-class User < ActiveRecord::Base
+class User < ApplicationRecord
scope :active, -> { where state: 'active' }
scope :inactive, -> { where state: 'inactive' }
end
@@ -1312,7 +1343,7 @@ One important caveat is that `default_scope` will be prepended in
`scope` and `where` conditions.
```ruby
-class User < ActiveRecord::Base
+class User < ApplicationRecord
default_scope { where state: 'pending' }
scope :active, -> { where state: 'active' }
scope :inactive, -> { where state: 'inactive' }
@@ -1343,8 +1374,15 @@ Client.unscoped.load
This method removes all scoping and will do a normal query on the table.
-Note that chaining `unscoped` with a `scope` does not work. In these cases, it is
-recommended that you use the block form of `unscoped`:
+```ruby
+Client.unscoped.all
+# SELECT "clients".* FROM "clients"
+
+Client.where(published: false).unscoped.all
+# SELECT "clients".* FROM "clients"
+```
+
+`unscoped` can also accept a block.
```ruby
Client.unscoped {
@@ -1361,6 +1399,36 @@ 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)`.
+Enums
+-----
+
+The `enum` macro maps an integer column to a set of possible values.
+
+```ruby
+class Book < ApplicationRecord
+ enum availability: [:available, :unavailable]
+end
+```
+
+This will automatically create the corresponding [scopes](#scopes) to query the
+model. Methods to transition between states and query the current state are also
+added.
+
+```ruby
+# Both examples below query just available books.
+Book.available
+# or
+Book.where(availability: :available)
+
+book = Book.new(availability: :available)
+book.available? # => true
+book.unavailable! # => true
+book.available? # => false
+```
+
+Read the full documentation about enums
+[in the Rails API docs](http://api.rubyonrails.org/classes/ActiveRecord/Enum.html).
+
Understanding The Method Chaining
---------------------------------
@@ -1426,7 +1494,7 @@ It's common that you need to find a record or create it if it doesn't exist. You
### `find_or_create_by`
-The `find_or_create_by` method checks whether a record with the attributes exists. If it doesn't, then `create` is called. Let's see an example.
+The `find_or_create_by` method checks whether a record with the specified attributes exists. If it doesn't, then `create` is called. Let's see an example.
Suppose you want to find a client named 'Andy', and if there's none, create one. You can do so by running:
@@ -1589,7 +1657,7 @@ a large or often-running query. However, any model method overrides will
not be available. For example:
```ruby
-class Client < ActiveRecord::Base
+class Client < ApplicationRecord
def name
"I am #{super}"
end
@@ -1624,7 +1692,7 @@ Person.ids
```
```ruby
-class Person < ActiveRecord::Base
+class Person < ApplicationRecord
self.primary_key = "person_id"
end
@@ -1866,6 +1934,6 @@ following pointers may be helpful:
* SQLite3: [EXPLAIN QUERY PLAN](http://www.sqlite.org/eqp.html)
-* MySQL: [EXPLAIN Output Format](http://dev.mysql.com/doc/refman/5.6/en/explain-output.html)
+* MySQL: [EXPLAIN Output Format](http://dev.mysql.com/doc/refman/5.7/en/explain-output.html)
* PostgreSQL: [Using EXPLAIN](http://www.postgresql.org/docs/current/static/using-explain.html)
diff --git a/guides/source/active_record_validations.md b/guides/source/active_record_validations.md
index 71ca7a0f66..dd7adf09a2 100644
--- a/guides/source/active_record_validations.md
+++ b/guides/source/active_record_validations.md
@@ -20,7 +20,7 @@ Validations Overview
Here's an example of a very simple validation:
```ruby
-class Person < ActiveRecord::Base
+class Person < ApplicationRecord
validates :name, presence: true
end
@@ -80,7 +80,7 @@ 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
+class Person < ApplicationRecord
end
```
@@ -149,13 +149,15 @@ false` as an argument. This technique should be used with caution.
### `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
+Before saving an ActiveRecord object, Rails runs your validations.
+If these validations produce any errors, Rails does not save the object.
+
+You can also run these validations 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
+class Person < ApplicationRecord
validates :name, presence: true
end
@@ -168,11 +170,12 @@ through the `errors.messages` instance method, which returns a collection of err
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`.
+Note that an object instantiated with `new` will not report errors
+even if it's technically invalid, because validations are automatically run
+only when the object is saved, such as with the `create` or `save` methods.
```ruby
-class Person < ActiveRecord::Base
+class Person < ApplicationRecord
validates :name, presence: true
end
@@ -218,7 +221,7 @@ 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
+class Person < ApplicationRecord
validates :name, presence: true
end
@@ -236,13 +239,13 @@ To check which validations failed on an invalid attribute, you can use
key to get the symbol of the validator:
```ruby
-class Person < ActiveRecord::Base
+class Person < ApplicationRecord
validates :name, presence: true
end
>> person = Person.new
>> person.valid?
->> person.errors.details[:name] #=> [{error: :blank}]
+>> person.errors.details[:name] # => [{error: :blank}]
```
Using `details` with custom validators is covered in the [Working with
@@ -273,12 +276,16 @@ available helpers.
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 that some text is read, 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).
+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. If
+the field does exist in your database, the `accept` option must be set to
+`true` or else the validation will not run.
```ruby
-class Person < ActiveRecord::Base
+class Person < ApplicationRecord
validates :terms_of_service, acceptance: true
end
```
@@ -290,7 +297,7 @@ 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
+class Person < ApplicationRecord
validates :terms_of_service, acceptance: { accept: 'yes' }
end
```
@@ -302,7 +309,7 @@ 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
+class Library < ApplicationRecord
has_many :books
validates_associated :books
end
@@ -325,7 +332,7 @@ 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
+class Person < ApplicationRecord
validates :email, confirmation: true
end
```
@@ -342,12 +349,22 @@ confirmation, make sure to add a presence check for the confirmation attribute
(we'll take a look at `presence` later on in this guide):
```ruby
-class Person < ActiveRecord::Base
+class Person < ApplicationRecord
validates :email, confirmation: true
validates :email_confirmation, presence: true
end
```
+There is also a `:case_sensitive` option that you can use to define whether the
+confirmation constraint will be case sensitive or not. This option defaults to
+true.
+
+```ruby
+class Person < ApplicationRecord
+ validates :email, confirmation: { case_sensitive: false }
+end
+```
+
The default error message for this helper is _"doesn't match confirmation"_.
### `exclusion`
@@ -356,7 +373,7 @@ 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
+class Account < ApplicationRecord
validates :subdomain, exclusion: { in: %w(www us ca jp),
message: "%{value} is reserved." }
end
@@ -376,7 +393,7 @@ 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
+class Product < ApplicationRecord
validates :legacy_code, format: { with: /\A[a-zA-Z]+\z/,
message: "only allows letters" }
end
@@ -392,7 +409,7 @@ 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
+class Coffee < ApplicationRecord
validates :size, inclusion: { in: %w(small medium large),
message: "%{value} is not a valid size" }
end
@@ -411,7 +428,7 @@ 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
+class Person < ApplicationRecord
validates :name, length: { minimum: 2 }
validates :bio, length: { maximum: 500 }
validates :password, length: { in: 6..20 }
@@ -434,27 +451,12 @@ 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
+class Person < ApplicationRecord
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.split(/\s+/) },
- 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 `presence: true` instead. When
@@ -481,7 +483,7 @@ WARNING. Note that the regular expression above allows a trailing newline
character.
```ruby
-class Player < ActiveRecord::Base
+class Player < ApplicationRecord
validates :points, numericality: true
validates :games_played, numericality: { only_integer: true }
end
@@ -519,7 +521,7 @@ This helper validates that the specified attributes are not empty. It uses the
is, a string that is either empty or consists of whitespace.
```ruby
-class Person < ActiveRecord::Base
+class Person < ApplicationRecord
validates :name, :login, :email, presence: true
end
```
@@ -529,7 +531,7 @@ whether the associated object itself is present, and not the foreign key used
to map the association.
```ruby
-class LineItem < ActiveRecord::Base
+class LineItem < ApplicationRecord
belongs_to :order
validates :order, presence: true
end
@@ -539,7 +541,7 @@ In order to validate associated records whose presence is required, you must
specify the `:inverse_of` option for the association:
```ruby
-class Order < ActiveRecord::Base
+class Order < ApplicationRecord
has_many :line_items, inverse_of: :order
end
```
@@ -566,7 +568,7 @@ This helper validates that the specified attributes are absent. It uses the
is, a string that is either empty or consists of whitespace.
```ruby
-class Person < ActiveRecord::Base
+class Person < ApplicationRecord
validates :name, :login, :email, absence: true
end
```
@@ -576,7 +578,7 @@ whether the associated object itself is absent, and not the foreign key used
to map the association.
```ruby
-class LineItem < ActiveRecord::Base
+class LineItem < ApplicationRecord
belongs_to :order
validates :order, absence: true
end
@@ -586,7 +588,7 @@ In order to validate associated records whose absence is required, you must
specify the `:inverse_of` option for the association:
```ruby
-class Order < ActiveRecord::Base
+class Order < ApplicationRecord
has_many :line_items, inverse_of: :order
end
```
@@ -609,7 +611,7 @@ with the same value for a column that you intend to be unique. To avoid that,
you must create a unique index on that column in your database.
```ruby
-class Account < ActiveRecord::Base
+class Account < ApplicationRecord
validates :email, uniqueness: true
end
```
@@ -621,19 +623,19 @@ There is a `:scope` option that you can use to specify one or more attributes th
are used to limit the uniqueness check:
```ruby
-class Holiday < ActiveRecord::Base
+class Holiday < ApplicationRecord
validates :name, uniqueness: { scope: :year,
message: "should happen once per year" }
end
```
-Should you wish to create a database constraint to prevent possible violations of a uniqueness validation using the `:scope` option, you must create a unique index on both columns in your database. See [the MySQL manual](http://dev.mysql.com/doc/refman/5.6/en/multiple-column-indexes.html) for more details about multiple column indexes or [the PostgreSQL manual](http://www.postgresql.org/docs/current/static/ddl-constraints.html) for examples of unique constraints that refer to a group of columns.
+Should you wish to create a database constraint to prevent possible violations of a uniqueness validation using the `:scope` option, you must create a unique index on both columns in your database. See [the MySQL manual](http://dev.mysql.com/doc/refman/5.7/en/multiple-column-indexes.html) for more details about multiple column indexes or [the PostgreSQL manual](http://www.postgresql.org/docs/current/static/ddl-constraints.html) for examples of unique constraints that refer to a group of columns.
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
+class Person < ApplicationRecord
validates :name, uniqueness: { case_sensitive: false }
end
```
@@ -656,7 +658,7 @@ class GoodnessValidator < ActiveModel::Validator
end
end
-class Person < ActiveRecord::Base
+class Person < ApplicationRecord
validates_with GoodnessValidator
end
```
@@ -684,7 +686,7 @@ class GoodnessValidator < ActiveModel::Validator
end
end
-class Person < ActiveRecord::Base
+class Person < ApplicationRecord
validates_with GoodnessValidator, fields: [:first_name, :last_name]
end
```
@@ -697,7 +699,7 @@ If your validator is complex enough that you want instance variables, you can
easily use a plain old Ruby object instead:
```ruby
-class Person < ActiveRecord::Base
+class Person < ApplicationRecord
validate do |person|
GoodnessValidator.new(person).validate
end
@@ -726,7 +728,7 @@ 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
+class Person < ApplicationRecord
validates_each :name, :surname do |record, attr, value|
record.errors.add(attr, 'must start with upper case') if value =~ /\A[[:lower:]]/
end
@@ -749,7 +751,7 @@ The `:allow_nil` option skips the validation when the value being validated is
`nil`.
```ruby
-class Coffee < ActiveRecord::Base
+class Coffee < ApplicationRecord
validates :size, inclusion: { in: %w(small medium large),
message: "%{value} is not a valid size" }, allow_nil: true
end
@@ -762,7 +764,7 @@ will let validation pass if the attribute's value is `blank?`, like `nil` or an
empty string for example.
```ruby
-class Topic < ActiveRecord::Base
+class Topic < ApplicationRecord
validates :title, length: { is: 5 }, allow_blank: true
end
@@ -775,7 +777,36 @@ Topic.create(title: nil).valid? # => true
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.
+for each validation helper. The `:message` option accepts a `String` or `Proc`.
+
+A `String` `:message` value can optionally contain any/all of `%{value}`,
+`%{attribute}`, and `%{model}` which will be dynamically replaced when
+validation fails.
+
+A `Proc` `:message` value is given two arguments: a message key for i18n, and
+a hash with `:model`, `:attribute`, and `:value` key-value pairs.
+
+```ruby
+class Person < ApplicationRecord
+ # Hard-coded message
+ validates :name, presence: { message: "must be given please" }
+
+ # Message with dynamic attribute value. %{value} will be replaced with
+ # the actual value of the attribute. %{attribute} and %{model} also
+ # available.
+ validates :age, numericality: { message: "%{value} seems wrong" }
+
+ # Proc
+ validates :username,
+ uniqueness: {
+ # key = "activerecord.errors.models.person.attributes.username.taken"
+ # data = { model: "Person", attribute: "Username", value: <username> }
+ message: ->(key, data) do
+ "#{data[:value]} taken! Try again #{Time.zone.tomorrow}"
+ end
+ }
+end
+```
### `:on`
@@ -787,7 +818,7 @@ new record is created or `on: :update` to run the validation only when a record
is updated.
```ruby
-class Person < ActiveRecord::Base
+class Person < ApplicationRecord
# it will be possible to update email with a duplicated value
validates :email, uniqueness: true, on: :create
@@ -806,7 +837,7 @@ You can also specify validations to be strict and raise
`ActiveModel::StrictValidationFailed` when the object is invalid.
```ruby
-class Person < ActiveRecord::Base
+class Person < ApplicationRecord
validates :name, presence: { strict: true }
end
@@ -816,7 +847,7 @@ Person.new.valid? # => ActiveModel::StrictValidationFailed: Name can't be blank
There is also the ability to pass a custom exception to the `:strict` option.
```ruby
-class Person < ActiveRecord::Base
+class Person < ApplicationRecord
validates :token, presence: true, uniqueness: true, strict: TokenGenerationException
end
@@ -840,7 +871,7 @@ 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
+class Order < ApplicationRecord
validates :card_number, presence: true, if: :paid_with_card?
def paid_with_card?
@@ -856,7 +887,7 @@ contain valid Ruby code. You should use this option only when the string
represents a really short condition.
```ruby
-class Person < ActiveRecord::Base
+class Person < ApplicationRecord
validates :surname, presence: true, if: "name.nil?"
end
```
@@ -869,7 +900,7 @@ inline condition instead of a separate method. This option is best suited for
one-liners.
```ruby
-class Account < ActiveRecord::Base
+class Account < ApplicationRecord
validates :password, confirmation: true,
unless: Proc.new { |a| a.password.blank? }
end
@@ -881,7 +912,7 @@ Sometimes it is useful to have multiple validations use one condition. It can
be easily achieved using `with_options`.
```ruby
-class User < ActiveRecord::Base
+class User < ApplicationRecord
with_options if: :is_admin? do |admin|
admin.validates :password, length: { minimum: 10 }
admin.validates :email, presence: true
@@ -899,7 +930,7 @@ should happen, an `Array` can be used. Moreover, you can apply both `:if` and
`:unless` to the same validation.
```ruby
-class Computer < ActiveRecord::Base
+class Computer < ApplicationRecord
validates :mouse, presence: true,
if: ["market.retail?", :desktop?],
unless: Proc.new { |c| c.trackpad.present? }
@@ -953,7 +984,7 @@ class EmailValidator < ActiveModel::EachValidator
end
end
-class Person < ActiveRecord::Base
+class Person < ApplicationRecord
validates :email, presence: true, email: true
end
```
@@ -972,8 +1003,12 @@ 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.
+The `valid?` method will verify that the errors collection is empty,
+so your custom validation methods should add errors to it when you
+wish validation to fail:
+
```ruby
-class Invoice < ActiveRecord::Base
+class Invoice < ApplicationRecord
validate :expiration_date_cannot_be_in_the_past,
:discount_cannot_be_greater_than_total_value
@@ -991,12 +1026,13 @@ class Invoice < ActiveRecord::Base
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`.
+By default, such validations will run every time you call `valid?`
+or save the object. But 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
+class Invoice < ApplicationRecord
validate :active_customer, on: :create
def active_customer
@@ -1017,7 +1053,7 @@ The following is a list of the most commonly used methods. Please refer to the `
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
+class Person < ApplicationRecord
validates :name, presence: true, length: { minimum: 3 }
end
@@ -1036,7 +1072,7 @@ person.errors.messages # => {}
`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
+class Person < ApplicationRecord
validates :name, presence: true, length: { minimum: 3 }
end
@@ -1061,7 +1097,7 @@ The `add` method lets you add an error message related to a particular attribute
The `errors.full_messages` method (or its equivalent, `errors.to_a`) returns the error messages in a user-friendly format, with the capitalized attribute name prepended to each message, as shown in the examples below.
```ruby
-class Person < ActiveRecord::Base
+class Person < ApplicationRecord
def a_method_used_for_validation_purposes
errors.add(:name, "cannot contain the characters !@#%*()_-+=")
end
@@ -1079,7 +1115,7 @@ person.errors.full_messages
An equivalent to `errors#add` is to use `<<` to append a message to the `errors.messages` array for an attribute:
```ruby
- class Person < ActiveRecord::Base
+ class Person < ApplicationRecord
def a_method_used_for_validation_purposes
errors.messages[:name] << "cannot contain the characters !@#%*()_-+="
end
@@ -1100,7 +1136,7 @@ You can specify a validator type to the returned error details hash using the
`errors.add` method.
```ruby
-class Person < ActiveRecord::Base
+class Person < ApplicationRecord
def a_method_used_for_validation_purposes
errors.add(:name, :invalid_characters)
end
@@ -1116,7 +1152,7 @@ To improve the error details to contain the unallowed characters set for instanc
you can pass additional keys to `errors.add`.
```ruby
-class Person < ActiveRecord::Base
+class Person < ApplicationRecord
def a_method_used_for_validation_purposes
errors.add(:name, :invalid_characters, not_allowed: "!@#%*()_-+=")
end
@@ -1136,7 +1172,7 @@ validator type.
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
+class Person < ApplicationRecord
def a_method_used_for_validation_purposes
errors[:base] << "This person is invalid because ..."
end
@@ -1148,7 +1184,7 @@ end
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
+class Person < ApplicationRecord
validates :name, presence: true, length: { minimum: 3 }
end
@@ -1171,7 +1207,7 @@ p.errors[:name]
The `size` method returns the total number of error messages for the object.
```ruby
-class Person < ActiveRecord::Base
+class Person < ApplicationRecord
validates :name, presence: true, length: { minimum: 3 }
end
diff --git a/guides/source/active_support_core_extensions.md b/guides/source/active_support_core_extensions.md
index 01bf928407..0aca6db9b6 100644
--- a/guides/source/active_support_core_extensions.md
+++ b/guides/source/active_support_core_extensions.md
@@ -172,7 +172,7 @@ NOTE: Defined in `active_support/core_ext/object/duplicable.rb`.
### `deep_dup`
-The `deep_dup` method returns deep copy of a given object. Normally, when you `dup` an object that contains other objects, Ruby does not `dup` them, so it creates a shallow copy of the object. If you have an array with a string, for example, it will look like this:
+The `deep_dup` method returns a deep copy of a given object. Normally, when you `dup` an object that contains other objects, Ruby does not `dup` them, so it creates a shallow copy of the object. If you have an array with a string, for example, it will look like this:
```ruby
array = ['string']
@@ -248,6 +248,13 @@ end
@person.try { |p| "#{p.first_name} #{p.last_name}" }
```
+Note that `try` will swallow no-method errors, returning nil instead. If you want to protect against typos, use `try!` instead:
+
+```ruby
+@number.try(:nest) # => nil
+@number.try!(:nest) # NoMethodError: undefined method `nest' for 1:Fixnum
+```
+
NOTE: Defined in `active_support/core_ext/object/try.rb`.
### `class_eval(*args, &block)`
@@ -390,7 +397,7 @@ The method `with_options` provides a way to factor out common options in a serie
Given a default options hash, `with_options` yields a proxy object to a block. Within the block, methods called on the proxy are forwarded to the receiver with their options merged. For example, you get rid of the duplication in:
```ruby
-class Account < ActiveRecord::Base
+class Account < ApplicationRecord
has_many :customers, dependent: :destroy
has_many :products, dependent: :destroy
has_many :invoices, dependent: :destroy
@@ -401,7 +408,7 @@ end
this way:
```ruby
-class Account < ActiveRecord::Base
+class Account < ApplicationRecord
with_options dependent: :destroy do |assoc|
assoc.has_many :customers
assoc.has_many :products
@@ -453,7 +460,7 @@ NOTE: Defined in `active_support/core_ext/object/instance_variables.rb`.
#### `instance_variable_names`
-The method `instance_variable_names` returns an array. Each name includes the "@" sign.
+The method `instance_variable_names` returns an array. Each name includes the "@" sign.
```ruby
class C
@@ -510,17 +517,17 @@ Extensions to `Module`
Using plain Ruby you can wrap methods with other methods, that's called _alias chaining_.
-For example, let's say you'd like params to be strings in functional tests, as they are in real requests, but still want the convenience of assigning integers and other kind of values. To accomplish that you could wrap `ActionController::TestCase#process` this way in `test/test_helper.rb`:
+For example, let's say you'd like params to be strings in functional tests, as they are in real requests, but still want the convenience of assigning integers and other kind of values. To accomplish that you could wrap `ActionDispatch::IntegrationTest#process` this way in `test/test_helper.rb`:
```ruby
-ActionController::TestCase.class_eval do
+ActionDispatch::IntegrationTest.class_eval do
# save a reference to the original process method
alias_method :original_process, :process
# now redefine process and delegate to original_process
- def process(action, params=nil, session=nil, flash=nil, http_method='GET')
+ def process('GET', path, params: nil, headers: nil, env: nil, xhr: false)
params = Hash[*params.map {|k, v| [k, v.to_s]}.flatten]
- original_process(action, params, session, flash, http_method)
+ original_process('GET', path, params: params)
end
end
```
@@ -530,10 +537,10 @@ That's the method `get`, `post`, etc., delegate the work to.
That technique has a risk, it could be the case that `:original_process` was taken. To try to avoid collisions people choose some label that characterizes what the chaining is about:
```ruby
-ActionController::TestCase.class_eval do
+ActionDispatch::IntegrationTest.class_eval do
def process_with_stringified_params(...)
params = Hash[*params.map {|k, v| [k, v.to_s]}.flatten]
- process_without_stringified_params(action, params, session, flash, http_method)
+ process_without_stringified_params(method, path, params: params)
end
alias_method :process_without_stringified_params, :process
alias_method :process, :process_with_stringified_params
@@ -543,10 +550,10 @@ end
The method `alias_method_chain` provides a shortcut for that pattern:
```ruby
-ActionController::TestCase.class_eval do
+ActionDispatch::IntegrationTest.class_eval do
def process_with_stringified_params(...)
params = Hash[*params.map {|k, v| [k, v.to_s]}.flatten]
- process_without_stringified_params(action, params, session, flash, http_method)
+ process_without_stringified_params(method, path, params: params)
end
alias_method_chain :process, :stringified_params
end
@@ -561,7 +568,7 @@ NOTE: Defined in `active_support/core_ext/module/aliasing.rb`.
Model attributes have a reader, a writer, and a predicate. You can alias a model attribute having the corresponding three methods defined for you in one shot. As in other aliasing methods, the new name is the first argument, and the old name is the second (one mnemonic is that they go in the same order as if you did an assignment):
```ruby
-class User < ActiveRecord::Base
+class User < ApplicationRecord
# You can refer to the email column as "login".
# This can be meaningful for authentication code.
alias_attribute :login, :email
@@ -869,7 +876,7 @@ The macro `delegate` offers an easy way to forward methods.
Let's imagine that users in some application have login information in the `User` model but name and other data in a separate `Profile` model:
```ruby
-class User < ActiveRecord::Base
+class User < ApplicationRecord
has_one :profile
end
```
@@ -877,7 +884,7 @@ end
With that configuration you get a user's name via their profile, `user.profile.name`, but it could be handy to still be able to access such attribute directly:
```ruby
-class User < ActiveRecord::Base
+class User < ApplicationRecord
has_one :profile
def name
@@ -889,7 +896,7 @@ end
That is what `delegate` does for you:
```ruby
-class User < ActiveRecord::Base
+class User < ApplicationRecord
has_one :profile
delegate :name, to: :profile
@@ -1703,6 +1710,20 @@ The method `parameterize` normalizes its receiver in a way that can be used in p
"Kurt Gödel".parameterize # => "kurt-godel"
```
+To preserve the case of the string, set the `preserve_case` argument to true. By default, `preserve_case` is set to false.
+
+```ruby
+"John Smith".parameterize(preserve_case: true) # => "John-Smith"
+"Kurt Gödel".parameterize(preserve_case: true) # => "Kurt-Godel"
+```
+
+To use a custom separator, override the `separator` argument.
+
+```ruby
+"John Smith".parameterize(separator: "_") # => "john\_smith"
+"Kurt Gödel".parameterize(separator: "_") # => "kurt\_godel"
+```
+
In fact, the result string is wrapped in an instance of `ActiveSupport::Multibyte::Chars`.
NOTE: Defined in `active_support/core_ext/string/inflections.rb`.
@@ -1865,15 +1886,15 @@ The methods `to_date`, `to_time`, and `to_datetime` are basically convenience wr
```ruby
"2010-07-27".to_date # => Tue, 27 Jul 2010
-"2010-07-27 23:37:00".to_time # => Tue Jul 27 23:37:00 UTC 2010
+"2010-07-27 23:37:00".to_time # => 2010-07-27 23:37:00 +0200
"2010-07-27 23:37:00".to_datetime # => Tue, 27 Jul 2010 23:37:00 +0000
```
`to_time` receives an optional argument `:utc` or `:local`, to indicate which time zone you want the time in:
```ruby
-"2010-07-27 23:42:00".to_time(:utc) # => Tue Jul 27 23:42:00 UTC 2010
-"2010-07-27 23:42:00".to_time(:local) # => Tue Jul 27 23:42:00 +0200 2010
+"2010-07-27 23:42:00".to_time(:utc) # => 2010-07-27 23:42:00 UTC
+"2010-07-27 23:42:00".to_time(:local) # => 2010-07-27 23:42:00 +0200
```
Default is `:utc`.
@@ -2003,12 +2024,14 @@ Produce a string representation of a number rounded to a precision:
Produce a string representation of a number as a human-readable number of bytes:
```ruby
-123.to_s(:human_size) # => 123 Bytes
-1234.to_s(:human_size) # => 1.21 KB
-12345.to_s(:human_size) # => 12.1 KB
-1234567.to_s(:human_size) # => 1.18 MB
-1234567890.to_s(:human_size) # => 1.15 GB
-1234567890123.to_s(:human_size) # => 1.12 TB
+123.to_s(:human_size) # => 123 Bytes
+1234.to_s(:human_size) # => 1.21 KB
+12345.to_s(:human_size) # => 12.1 KB
+1234567.to_s(:human_size) # => 1.18 MB
+1234567890.to_s(:human_size) # => 1.15 GB
+1234567890123.to_s(:human_size) # => 1.12 TB
+1234567890123456.to_s(:human_size) # => 1.1 PB
+1234567890123456789.to_s(:human_size) # => 1.07 EB
```
Produce a string representation of a number in human-readable words:
@@ -2073,30 +2096,22 @@ Extensions to `BigDecimal`
--------------------------
### `to_s`
-The method `to_s` is aliased to `to_formatted_s`. This provides a convenient way to display a BigDecimal value in floating-point notation:
+The method `to_s` provides a default specifier of "F". This means that a simple call to `to_s` will result in floating point representation instead of engineering notation:
```ruby
BigDecimal.new(5.00, 6).to_s # => "5.0"
```
-### `to_formatted_s`
-
-Te method `to_formatted_s` provides a default specifier of "F". This means that a simple call to `to_formatted_s` or `to_s` will result in floating point representation instead of engineering notation:
-
-```ruby
-BigDecimal.new(5.00, 6).to_formatted_s # => "5.0"
-```
-
and that symbol specifiers are also supported:
```ruby
-BigDecimal.new(5.00, 6).to_formatted_s(:db) # => "5.0"
+BigDecimal.new(5.00, 6).to_s(:db) # => "5.0"
```
Engineering notation is still supported:
```ruby
-BigDecimal.new(5.00, 6).to_formatted_s("e") # => "0.5E1"
+BigDecimal.new(5.00, 6).to_s("e") # => "0.5E1"
```
Extensions to `Enumerable`
diff --git a/guides/source/active_support_instrumentation.md b/guides/source/active_support_instrumentation.md
index cd44c685ba..0fd0112c9f 100644
--- a/guides/source/active_support_instrumentation.md
+++ b/guides/source/active_support_instrumentation.md
@@ -232,6 +232,7 @@ Active Record
| `:sql` | SQL statement |
| `:name` | Name of the operation |
| `:connection_id` | `self.object_id` |
+| `:binds` | Bind parameters |
INFO. The adapters will add their own data as well.
@@ -395,6 +396,38 @@ INFO. Cache stores may add their own keys
}
```
+Active Job
+--------
+
+### enqueue_at.active_job
+
+| Key | Value |
+| ------------ | -------------------------------------- |
+| `:adapter` | QueueAdapter object processing the job |
+| `:job` | Job object |
+
+### enqueue.active_job
+
+| Key | Value |
+| ------------ | -------------------------------------- |
+| `:adapter` | QueueAdapter object processing the job |
+| `:job` | Job object |
+
+### perform_start.active_job
+
+| Key | Value |
+| ------------ | -------------------------------------- |
+| `:adapter` | QueueAdapter object processing the job |
+| `:job` | Job object |
+
+### perform.active_job
+
+| Key | Value |
+| ------------ | -------------------------------------- |
+| `:adapter` | QueueAdapter object processing the job |
+| `:job` | Job object |
+
+
Railties
--------
@@ -425,7 +458,7 @@ The block receives the following arguments:
* The name of the event
* Time when it started
* Time when it finished
-* An unique ID for this event
+* A unique ID for this event
* The payload (described in previous sections)
```ruby
diff --git a/guides/source/api_app.md b/guides/source/api_app.md
index 29ca872254..86baa9ee84 100644
--- a/guides/source/api_app.md
+++ b/guides/source/api_app.md
@@ -163,6 +163,14 @@ class definition:
config.api_only = true
```
+Optionally, in `config/environments/development.rb` add the following line
+to render error responses using the API format (JSON by default) when it
+is a local request:
+
+```ruby
+config.debug_exception_response_format = :api
+```
+
Finally, inside `app/controllers/application_controller.rb`, instead of:
```ruby
@@ -194,7 +202,6 @@ An API application comes with the following middlewares by default:
- `ActionDispatch::RemoteIp`
- `ActionDispatch::Reloader`
- `ActionDispatch::Callbacks`
-- `ActionDispatch::ParamsParser`
- `Rack::Head`
- `Rack::ConditionalGet`
- `Rack::ETag`
@@ -209,7 +216,7 @@ building, and make sense in an API-only Rails application.
You can get a list of all middlewares in your application via:
```bash
-$ rake middleware
+$ rails middleware
```
### Using the Cache Middleware
@@ -222,7 +229,7 @@ For instance, using the `stale?` method:
```ruby
def show
- @post = Post.find(params[:id])
+ @post = Post.find(params[:id])
if stale?(last_modified: @post.updated_at)
render json: @post
@@ -241,7 +248,7 @@ cross-client caching in the call to `stale?`:
```ruby
def show
- @post = Post.find(params[:id])
+ @post = Post.find(params[:id])
if stale?(last_modified: @post.updated_at, public: true)
render json: @post
@@ -292,9 +299,9 @@ instructions in the `Rack::Sendfile` documentation.
NOTE: The `Rack::Sendfile` middleware is always outside of the `Rack::Lock`
mutex, even in single-threaded applications.
-### Using ActionDispatch::ParamsParser
+### Using ActionDispatch::Request
-`ActionDispatch::ParamsParser` will take parameters from the client in the JSON
+`ActionDispatch::Request#params` will take parameters from the client in the JSON
format and make them available in your controller inside `params`.
To use this, your client will need to make a request with JSON-encoded parameters
@@ -313,7 +320,7 @@ jQuery.ajax({
});
```
-`ActionDispatch::ParamsParser` will see the `Content-Type` and your parameters
+`ActionDispatch::Request` will see the `Content-Type` and your parameters
will be:
```ruby
@@ -363,11 +370,8 @@ controller modules by default:
- `ActionController::Renderers::All`: Support for `render :json` and friends.
- `ActionController::ConditionalGet`: Support for `stale?`.
- `ActionController::ForceSSL`: Support for `force_ssl`.
-- `ActionController::RackDelegation`: Support for the `request` and `response`
- methods returning `ActionDispatch::Request` and `ActionDispatch::Response`
- objects.
- `ActionController::DataStreaming`: Support for `send_file` and `send_data`.
-- `AbstractController::Callbacks`: Support for `before_filter` and friends.
+- `AbstractController::Callbacks`: Support for `before_action` and friends.
- `ActionController::Instrumentation`: Support for the instrumentation
hooks defined by Action Controller (see [the instrumentation
guide](active_support_instrumentation.html#action-controller)).
@@ -397,7 +401,7 @@ Some common modules you might want to add:
- `AbstractController::Translation`: Support for the `l` and `t` localization
and translation methods.
-- `ActionController::HTTPAuthentication::Basic` (or `Digest` or `Token`): Support
+- `ActionController::HttpAuthentication::Basic` (or `Digest` or `Token`): Support
for basic, digest or token HTTP authentication.
- `AbstractController::Layouts`: Support for layouts when rendering.
- `ActionController::MimeResponds`: Support for `respond_to`.
diff --git a/guides/source/api_documentation_guidelines.md b/guides/source/api_documentation_guidelines.md
index 46c9013087..cd208c2e13 100644
--- a/guides/source/api_documentation_guidelines.md
+++ b/guides/source/api_documentation_guidelines.md
@@ -20,7 +20,7 @@ The [Rails API documentation](http://api.rubyonrails.org) is generated with
in the rails root directory, run `bundle install` and execute:
```bash
- bundle exec rake rdoc
+ ./bin/rails rdoc
```
Resulting HTML files can be found in the ./doc/rdoc directory.
@@ -84,6 +84,12 @@ English
Please use American English (*color*, *center*, *modularize*, etc). See [a list of American and British English spelling differences here](http://en.wikipedia.org/wiki/American_and_British_English_spelling_differences).
+Oxford Comma
+------------
+
+Please use the [Oxford comma](http://en.wikipedia.org/wiki/Serial_comma)
+("red, white, and blue", instead of "red, white and blue").
+
Example Code
------------
@@ -234,7 +240,7 @@ You can quickly test the RDoc output with the following command:
```
$ echo "+:to_param+" | rdoc --pipe
-#=> <p><code>:to_param</code></p>
+# => <p><code>:to_param</code></p>
```
### Regular Font
diff --git a/guides/source/asset_pipeline.md b/guides/source/asset_pipeline.md
index fc7dd3a6c6..0083fc0e6c 100644
--- a/guides/source/asset_pipeline.md
+++ b/guides/source/asset_pipeline.md
@@ -169,7 +169,7 @@ directory. Files in this directory are served by the Sprockets middleware.
Assets can still be placed in the `public` hierarchy. Any assets under `public`
will be served as static files by the application or web server when
-`config.serve_static_files` is set to true. You should use `app/assets` for
+`config.public_file_server.enabled` is set to true. You should use `app/assets` for
files that must undergo some pre-processing before they are served.
In production, Rails precompiles these files to `public/assets` by default. The
@@ -403,13 +403,13 @@ When using the asset pipeline, paths to assets must be re-written and
underscored in Ruby) for the following asset classes: image, font, video, audio,
JavaScript and stylesheet.
-* `url(/assets/rails.png)` becomes `image-url("rails.png")`
-* `"/assets/rails.png"` becomes `image-path("rails.png")` .
+* `image-url("rails.png")` returns `url(/assets/rails.png)`
+* `image-path("rails.png")` returns `"/assets/rails.png"`
The more generic form can also be used:
-* `url(/assets/rails.png)` becomes `asset-url("rails.png")`
-* `"/assets/rails.png"` becomes `asset-path("rails.png")`
+* `asset-url("rails.png")` returns `url(/assets/rails.png)`
+* `asset-path("rails.png")` returns `"/assets/rails.png"`
#### JavaScript/CoffeeScript and ERB
@@ -662,7 +662,7 @@ generates something like this:
rel="stylesheet" />
```
-Note: with the Asset Pipeline the :cache and :concat options aren't used
+NOTE: with the Asset Pipeline the `:cache` and `:concat` options aren't used
anymore, delete these options from the `javascript_include_tag` and
`stylesheet_link_tag`.
@@ -676,7 +676,7 @@ content changes.
### Precompiling Assets
-Rails comes bundled with a rake task to compile the asset manifests and other
+Rails comes bundled with a task to compile the asset manifests and other
files in the pipeline.
Compiled assets are written to the location specified in `config.assets.prefix`.
@@ -686,10 +686,10 @@ You can call this task on the server during deployment to create compiled
versions of your assets directly on the server. See the next section for
information on compiling locally.
-The rake task is:
+The task is:
```bash
-$ RAILS_ENV=production bin/rake assets:precompile
+$ RAILS_ENV=production bin/rails assets:precompile
```
Capistrano (v2.15.1 and above) includes a recipe to handle this in deployment.
@@ -731,7 +731,7 @@ Rails.application.config.assets.precompile += ['admin.js', 'admin.css', 'swfObje
NOTE. Always specify an expected compiled filename that ends with .js or .css,
even if you want to add Sass or CoffeeScript files to the precompile array.
-The rake task also generates a `manifest-md5hash.json` that contains a list with
+The task also generates a `manifest-md5hash.json` that contains a list with
all your assets and their respective fingerprints. This is used by the Rails
helper methods to avoid handing the mapping requests back to Sprockets. A
typical manifest file looks like:
@@ -1021,7 +1021,7 @@ header](http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9) is a W3C
specification that describes how a request can be cached. When no CDN is used, a
browser will use this information to cache contents. This is very helpful for
assets that are not modified so that a browser does not need to re-download a
-website's CSS or javascript on every request. Generally we want our Rails server
+website's CSS or JavaScript on every request. Generally we want our Rails server
to tell our CDN (and browser) that the asset is "public", that means any cache
can store the request. Also we commonly want to set `max-age` which is how long
the cache will store the object before invalidating the cache. The `max-age`
@@ -1029,7 +1029,9 @@ value is set to seconds with a maximum possible value of `31536000` which is one
year. You can do this in your rails application by setting
```
-config.static_cache_control = "public, max-age=31536000"
+config.public_file_server.headers = {
+ 'Cache-Control' => 'public, max-age=31536000'
+}
```
Now when your application serves an asset in production, the CDN will store the
diff --git a/guides/source/association_basics.md b/guides/source/association_basics.md
index 1191f5edfe..d83dda7228 100644
--- a/guides/source/association_basics.md
+++ b/guides/source/association_basics.md
@@ -16,13 +16,13 @@ After reading this guide, you will know:
Why Associations?
-----------------
-Why do we need associations between models? Because they make common operations simpler and easier in your code. For example, consider a simple Rails application that includes a model for customers and a model for orders. Each customer can have many orders. Without associations, the model declarations would look like this:
+In Rails, an _association_ is a connection between two Active Record models. Why do we need associations between models? Because they make common operations simpler and easier in your code. For example, consider a simple Rails application that includes a model for customers and a model for orders. Each customer can have many orders. Without associations, the model declarations would look like this:
```ruby
-class Customer < ActiveRecord::Base
+class Customer < ApplicationRecord
end
-class Order < ActiveRecord::Base
+class Order < ApplicationRecord
end
```
@@ -45,11 +45,11 @@ end
With Active Record associations, we can streamline these - and other - operations by declaratively telling Rails that there is a connection between the two models. Here's the revised code for setting up customers and orders:
```ruby
-class Customer < ActiveRecord::Base
+class Customer < ApplicationRecord
has_many :orders, dependent: :destroy
end
-class Order < ActiveRecord::Base
+class Order < ApplicationRecord
belongs_to :customer
end
```
@@ -71,7 +71,7 @@ To learn more about the different types of associations, read the next section o
The Types of Associations
-------------------------
-In Rails, an _association_ is a connection between two Active Record models. Associations are implemented using macro-style calls, so that you can declaratively add features to your models. For example, by declaring that one model `belongs_to` another, you instruct Rails to maintain Primary Key-Foreign Key information between instances of the two models, and you also get a number of utility methods added to your model. Rails supports six types of associations:
+Rails supports six types of associations:
* `belongs_to`
* `has_one`
@@ -80,6 +80,8 @@ In Rails, an _association_ is a connection between two Active Record models. Ass
* `has_one :through`
* `has_and_belongs_to_many`
+Associations are implemented using macro-style calls, so that you can declaratively add features to your models. For example, by declaring that one model `belongs_to` another, you instruct Rails to maintain [Primary Key](https://en.wikipedia.org/wiki/Unique_key)-[Foreign Key](https://en.wikipedia.org/wiki/Foreign_key) information between instances of the two models, and you also get a number of utility methods added to your model.
+
In the remainder of this guide, you'll learn how to declare and use the various forms of associations. But first, a quick introduction to the situations where each association type is appropriate.
### The `belongs_to` Association
@@ -87,7 +89,7 @@ In the remainder of this guide, you'll learn how to declare and use the various
A `belongs_to` association sets up a one-to-one connection with another model, such that each instance of the declaring model "belongs to" one instance of the other model. For example, if your application includes customers and orders, and each order can be assigned to exactly one customer, you'd declare the order model this way:
```ruby
-class Order < ActiveRecord::Base
+class Order < ApplicationRecord
belongs_to :customer
end
```
@@ -99,7 +101,7 @@ NOTE: `belongs_to` associations _must_ use the singular term. If you used the pl
The corresponding migration might look like this:
```ruby
-class CreateOrders < ActiveRecord::Migration
+class CreateOrders < ActiveRecord::Migration[5.0]
def change
create_table :customers do |t|
t.string :name
@@ -120,7 +122,7 @@ end
A `has_one` association also sets up a one-to-one connection with another model, but with somewhat different semantics (and consequences). This association indicates that each instance of a model contains or possesses one instance of another model. For example, if each supplier in your application has only one account, you'd declare the supplier model like this:
```ruby
-class Supplier < ActiveRecord::Base
+class Supplier < ApplicationRecord
has_one :account
end
```
@@ -130,7 +132,7 @@ end
The corresponding migration might look like this:
```ruby
-class CreateSuppliers < ActiveRecord::Migration
+class CreateSuppliers < ActiveRecord::Migration[5.0]
def change
create_table :suppliers do |t|
t.string :name
@@ -162,7 +164,7 @@ end
A `has_many` association indicates a one-to-many connection with another model. You'll often find this association on the "other side" of a `belongs_to` association. This association indicates that each instance of the model has zero or more instances of another model. For example, in an application containing customers and orders, the customer model could be declared like this:
```ruby
-class Customer < ActiveRecord::Base
+class Customer < ApplicationRecord
has_many :orders
end
```
@@ -174,7 +176,7 @@ NOTE: The name of the other model is pluralized when declaring a `has_many` asso
The corresponding migration might look like this:
```ruby
-class CreateCustomers < ActiveRecord::Migration
+class CreateCustomers < ActiveRecord::Migration[5.0]
def change
create_table :customers do |t|
t.string :name
@@ -195,17 +197,17 @@ end
A `has_many :through` association is often used to set up a many-to-many connection with another model. This association indicates that the declaring model can be matched with zero or more instances of another model by proceeding _through_ a third model. For example, consider a medical practice where patients make appointments to see physicians. The relevant association declarations could look like this:
```ruby
-class Physician < ActiveRecord::Base
+class Physician < ApplicationRecord
has_many :appointments
has_many :patients, through: :appointments
end
-class Appointment < ActiveRecord::Base
+class Appointment < ApplicationRecord
belongs_to :physician
belongs_to :patient
end
-class Patient < ActiveRecord::Base
+class Patient < ApplicationRecord
has_many :appointments
has_many :physicians, through: :appointments
end
@@ -216,7 +218,7 @@ end
The corresponding migration might look like this:
```ruby
-class CreateAppointments < ActiveRecord::Migration
+class CreateAppointments < ActiveRecord::Migration[5.0]
def change
create_table :physicians do |t|
t.string :name
@@ -238,30 +240,32 @@ class CreateAppointments < ActiveRecord::Migration
end
```
-The collection of join models can be managed via the API. For example, if you assign
+The collection of join models can be managed via the [`has_many` association methods](#has-many-association-reference).
+For example, if you assign:
```ruby
physician.patients = patients
```
-new join models are created for newly associated objects, and if some are gone their rows are deleted.
+Then new join models are automatically created for the newly associated objects.
+If some that existed previously are now missing, then their join rows are automatically deleted.
WARNING: Automatic deletion of join models is direct, no destroy callbacks are triggered.
The `has_many :through` association is also useful for setting up "shortcuts" through nested `has_many` associations. For example, if a document has many sections, and a section has many paragraphs, you may sometimes want to get a simple collection of all paragraphs in the document. You could set that up this way:
```ruby
-class Document < ActiveRecord::Base
+class Document < ApplicationRecord
has_many :sections
has_many :paragraphs, through: :sections
end
-class Section < ActiveRecord::Base
+class Section < ApplicationRecord
belongs_to :document
has_many :paragraphs
end
-class Paragraph < ActiveRecord::Base
+class Paragraph < ApplicationRecord
belongs_to :section
end
```
@@ -280,17 +284,17 @@ For example, if each supplier has one account, and each account is associated wi
supplier model could look like this:
```ruby
-class Supplier < ActiveRecord::Base
+class Supplier < ApplicationRecord
has_one :account
has_one :account_history, through: :account
end
-class Account < ActiveRecord::Base
+class Account < ApplicationRecord
belongs_to :supplier
has_one :account_history
end
-class AccountHistory < ActiveRecord::Base
+class AccountHistory < ApplicationRecord
belongs_to :account
end
```
@@ -300,7 +304,7 @@ end
The corresponding migration might look like this:
```ruby
-class CreateAccountHistories < ActiveRecord::Migration
+class CreateAccountHistories < ActiveRecord::Migration[5.0]
def change
create_table :suppliers do |t|
t.string :name
@@ -327,11 +331,11 @@ end
A `has_and_belongs_to_many` association creates a direct many-to-many connection with another model, with no intervening model. For example, if your application includes assemblies and parts, with each assembly having many parts and each part appearing in many assemblies, you could declare the models this way:
```ruby
-class Assembly < ActiveRecord::Base
+class Assembly < ApplicationRecord
has_and_belongs_to_many :parts
end
-class Part < ActiveRecord::Base
+class Part < ApplicationRecord
has_and_belongs_to_many :assemblies
end
```
@@ -341,7 +345,7 @@ end
The corresponding migration might look like this:
```ruby
-class CreateAssembliesAndParts < ActiveRecord::Migration
+class CreateAssembliesAndParts < ActiveRecord::Migration[5.0]
def change
create_table :assemblies do |t|
t.string :name
@@ -368,11 +372,11 @@ If you want to set up a one-to-one relationship between two models, you'll need
The distinction is in where you place the foreign key (it goes on the table for the class declaring the `belongs_to` association), but you should give some thought to the actual meaning of the data as well. The `has_one` relationship says that one of something is yours - that is, that something points back to you. For example, it makes more sense to say that a supplier owns an account than that an account owns a supplier. This suggests that the correct relationships are like this:
```ruby
-class Supplier < ActiveRecord::Base
+class Supplier < ApplicationRecord
has_one :account
end
-class Account < ActiveRecord::Base
+class Account < ApplicationRecord
belongs_to :supplier
end
```
@@ -380,7 +384,7 @@ end
The corresponding migration might look like this:
```ruby
-class CreateSuppliers < ActiveRecord::Migration
+class CreateSuppliers < ActiveRecord::Migration[5.0]
def change
create_table :suppliers do |t|
t.string :name
@@ -405,11 +409,11 @@ NOTE: Using `t.integer :supplier_id` makes the foreign key naming obvious and ex
Rails offers two different ways to declare a many-to-many relationship between models. The simpler way is to use `has_and_belongs_to_many`, which allows you to make the association directly:
```ruby
-class Assembly < ActiveRecord::Base
+class Assembly < ApplicationRecord
has_and_belongs_to_many :parts
end
-class Part < ActiveRecord::Base
+class Part < ApplicationRecord
has_and_belongs_to_many :assemblies
end
```
@@ -417,17 +421,17 @@ end
The second way to declare a many-to-many relationship is to use `has_many :through`. This makes the association indirectly, through a join model:
```ruby
-class Assembly < ActiveRecord::Base
+class Assembly < ApplicationRecord
has_many :manifests
has_many :parts, through: :manifests
end
-class Manifest < ActiveRecord::Base
+class Manifest < ApplicationRecord
belongs_to :assembly
belongs_to :part
end
-class Part < ActiveRecord::Base
+class Part < ApplicationRecord
has_many :manifests
has_many :assemblies, through: :manifests
end
@@ -442,15 +446,15 @@ You should use `has_many :through` if you need validations, callbacks or extra a
A slightly more advanced twist on associations is the _polymorphic association_. With polymorphic associations, a model can belong to more than one other model, on a single association. For example, you might have a picture model that belongs to either an employee model or a product model. Here's how this could be declared:
```ruby
-class Picture < ActiveRecord::Base
+class Picture < ApplicationRecord
belongs_to :imageable, polymorphic: true
end
-class Employee < ActiveRecord::Base
+class Employee < ApplicationRecord
has_many :pictures, as: :imageable
end
-class Product < ActiveRecord::Base
+class Product < ApplicationRecord
has_many :pictures, as: :imageable
end
```
@@ -462,7 +466,7 @@ Similarly, you can retrieve `@product.pictures`.
If you have an instance of the `Picture` model, you can get to its parent via `@picture.imageable`. To make this work, you need to declare both a foreign key column and a type column in the model that declares the polymorphic interface:
```ruby
-class CreatePictures < ActiveRecord::Migration
+class CreatePictures < ActiveRecord::Migration[5.0]
def change
create_table :pictures do |t|
t.string :name
@@ -479,7 +483,7 @@ end
This migration can be simplified by using the `t.references` form:
```ruby
-class CreatePictures < ActiveRecord::Migration
+class CreatePictures < ActiveRecord::Migration[5.0]
def change
create_table :pictures do |t|
t.string :name
@@ -497,7 +501,7 @@ end
In designing a data model, you will sometimes find a model that should have a relation to itself. For example, you may want to store all employees in a single database model, but be able to trace relationships such as between manager and subordinates. This situation can be modeled with self-joining associations:
```ruby
-class Employee < ActiveRecord::Base
+class Employee < ApplicationRecord
has_many :subordinates, class_name: "Employee",
foreign_key: "manager_id"
@@ -510,7 +514,7 @@ With this setup, you can retrieve `@employee.subordinates` and `@employee.manage
In your migrations/schema, you will add a references column to the model itself.
```ruby
-class CreateEmployees < ActiveRecord::Migration
+class CreateEmployees < ActiveRecord::Migration[5.0]
def change
create_table :employees do |t|
t.references :manager, index: true
@@ -563,7 +567,7 @@ Associations are extremely useful, but they are not magic. You are responsible f
When you declare a `belongs_to` association, you need to create foreign keys as appropriate. For example, consider this model:
```ruby
-class Order < ActiveRecord::Base
+class Order < ApplicationRecord
belongs_to :customer
end
```
@@ -571,7 +575,7 @@ end
This declaration needs to be backed up by the proper foreign key declaration on the orders table:
```ruby
-class CreateOrders < ActiveRecord::Migration
+class CreateOrders < ActiveRecord::Migration[5.0]
def change
create_table :orders do |t|
t.datetime :order_date
@@ -595,11 +599,11 @@ WARNING: The precedence between model names is calculated using the `<=>` operat
Whatever the name, you must manually generate the join table with an appropriate migration. For example, consider these associations:
```ruby
-class Assembly < ActiveRecord::Base
+class Assembly < ApplicationRecord
has_and_belongs_to_many :parts
end
-class Part < ActiveRecord::Base
+class Part < ApplicationRecord
has_and_belongs_to_many :assemblies
end
```
@@ -607,7 +611,7 @@ end
These need to be backed up by a migration to create the `assemblies_parts` table. This table should be created without a primary key:
```ruby
-class CreateAssembliesPartsJoinTable < ActiveRecord::Migration
+class CreateAssembliesPartsJoinTable < ActiveRecord::Migration[5.0]
def change
create_table :assemblies_parts, id: false do |t|
t.integer :assembly_id
@@ -625,7 +629,7 @@ We pass `id: false` to `create_table` because that table does not represent a mo
You can also use the method `create_join_table`
```ruby
-class CreateAssembliesPartsJoinTable < ActiveRecord::Migration
+class CreateAssembliesPartsJoinTable < ActiveRecord::Migration[5.0]
def change
create_join_table :assemblies, :parts do |t|
t.index :assembly_id
@@ -642,11 +646,11 @@ By default, associations look for objects only within the current module's scope
```ruby
module MyApplication
module Business
- class Supplier < ActiveRecord::Base
+ class Supplier < ApplicationRecord
has_one :account
end
- class Account < ActiveRecord::Base
+ class Account < ApplicationRecord
belongs_to :supplier
end
end
@@ -658,13 +662,13 @@ This will work fine, because both the `Supplier` and the `Account` class are def
```ruby
module MyApplication
module Business
- class Supplier < ActiveRecord::Base
+ class Supplier < ApplicationRecord
has_one :account
end
end
module Billing
- class Account < ActiveRecord::Base
+ class Account < ApplicationRecord
belongs_to :supplier
end
end
@@ -676,14 +680,14 @@ To associate a model with a model in a different namespace, you must specify the
```ruby
module MyApplication
module Business
- class Supplier < ActiveRecord::Base
+ class Supplier < ApplicationRecord
has_one :account,
class_name: "MyApplication::Billing::Account"
end
end
module Billing
- class Account < ActiveRecord::Base
+ class Account < ApplicationRecord
belongs_to :supplier,
class_name: "MyApplication::Business::Supplier"
end
@@ -696,11 +700,11 @@ end
It's normal for associations to work in two directions, requiring declaration on two different models:
```ruby
-class Customer < ActiveRecord::Base
+class Customer < ApplicationRecord
has_many :orders
end
-class Order < ActiveRecord::Base
+class Order < ApplicationRecord
belongs_to :customer
end
```
@@ -718,11 +722,11 @@ c.first_name == o.customer.first_name # => false
This happens because `c` and `o.customer` are two different in-memory representations of the same data, and neither one is automatically refreshed from changes to the other. Active Record provides the `:inverse_of` option so that you can inform it of these relations:
```ruby
-class Customer < ActiveRecord::Base
+class Customer < ApplicationRecord
has_many :orders, inverse_of: :customer
end
-class Order < ActiveRecord::Base
+class Order < ApplicationRecord
belongs_to :customer, inverse_of: :orders
end
```
@@ -768,7 +772,7 @@ The `belongs_to` association creates a one-to-one match with another model. In d
When you declare a `belongs_to` association, the declaring class automatically gains five methods related to the association:
-* `association(force_reload = false)`
+* `association`
* `association=(associate)`
* `build_association(attributes = {})`
* `create_association(attributes = {})`
@@ -777,7 +781,7 @@ When you declare a `belongs_to` association, the declaring class automatically g
In all of these methods, `association` is replaced with the symbol passed as the first argument to `belongs_to`. For example, given the declaration:
```ruby
-class Order < ActiveRecord::Base
+class Order < ApplicationRecord
belongs_to :customer
end
```
@@ -794,7 +798,7 @@ create_customer!
NOTE: When initializing a new `has_one` or `belongs_to` association you must use the `build_` prefix to build the association, rather than the `association.build` method that would be used for `has_many` or `has_and_belongs_to_many` associations. To create one, use the `create_` prefix.
-##### `association(force_reload = false)`
+##### `association`
The `association` method returns the associated object, if any. If no associated object is found, it returns `nil`.
@@ -802,7 +806,11 @@ The `association` method returns the associated object, if any. If no associated
@customer = @order.customer
```
-If the associated object has already been retrieved from the database for this object, the cached version will be returned. To override this behavior (and force a database read), pass `true` as the `force_reload` argument.
+If the associated object has already been retrieved from the database for this object, the cached version will be returned. To override this behavior (and force a database read), call `#reload` on the parent object.
+
+```ruby
+@customer = @order.reload.customer
+```
##### `association=(associate)`
@@ -840,7 +848,7 @@ Does the same as `create_association` above, but raises `ActiveRecord::RecordInv
While Rails uses intelligent defaults that will work well in most situations, there may be times when you want to customize the behavior of the `belongs_to` association reference. Such customizations can easily be accomplished by passing options and scope blocks when you create the association. For example, this association uses two such options:
```ruby
-class Order < ActiveRecord::Base
+class Order < ApplicationRecord
belongs_to :customer, dependent: :destroy,
counter_cache: true
end
@@ -869,7 +877,7 @@ If you set the `:autosave` option to `true`, Rails will save any loaded members
If the name of the other model cannot be derived from the association name, you can use the `:class_name` option to supply the model name. For example, if an order belongs to a customer, but the actual name of the model containing customers is `Patron`, you'd set things up this way:
```ruby
-class Order < ActiveRecord::Base
+class Order < ApplicationRecord
belongs_to :customer, class_name: "Patron"
end
```
@@ -879,10 +887,10 @@ end
The `:counter_cache` option can be used to make finding the number of belonging objects more efficient. Consider these models:
```ruby
-class Order < ActiveRecord::Base
+class Order < ApplicationRecord
belongs_to :customer
end
-class Customer < ActiveRecord::Base
+class Customer < ApplicationRecord
has_many :orders
end
```
@@ -890,10 +898,10 @@ end
With these declarations, asking for the value of `@customer.orders.size` requires making a call to the database to perform a `COUNT(*)` query. To avoid this call, you can add a counter cache to the _belonging_ model:
```ruby
-class Order < ActiveRecord::Base
+class Order < ApplicationRecord
belongs_to :customer, counter_cache: true
end
-class Customer < ActiveRecord::Base
+class Customer < ApplicationRecord
has_many :orders
end
```
@@ -910,10 +918,10 @@ the `counter_cache` declaration instead of `true`. For example, to use
`count_of_orders` instead of `orders_count`:
```ruby
-class Order < ActiveRecord::Base
+class Order < ApplicationRecord
belongs_to :customer, counter_cache: :count_of_orders
end
-class Customer < ActiveRecord::Base
+class Customer < ApplicationRecord
has_many :orders
end
```
@@ -928,8 +936,11 @@ If you set the `:dependent` option to:
* `:destroy`, when the object is destroyed, `destroy` will be called on its
associated objects.
-* `:delete`, when the object is destroyed, all its associated objects will be
+* `:delete_all`, when the object is destroyed, all its associated objects will be
deleted directly from the database without calling their `destroy` method.
+* `:nullify`, causes the foreign key to be set to `NULL`. Callbacks are not executed.
+* `:restrict_with_exception`, causes an exception to be raised if there is an associated record
+* `:restrict_with_error`, causes an error to be added to the owner if there is an associated object
WARNING: You should not specify this option on a `belongs_to` association that is connected with a `has_many` association on the other class. Doing so can lead to orphaned records in your database.
@@ -938,7 +949,7 @@ WARNING: You should not specify this option on a `belongs_to` association that i
By convention, Rails assumes that the column used to hold the foreign key on this model is the name of the association with the suffix `_id` added. The `:foreign_key` option lets you set the name of the foreign key directly:
```ruby
-class Order < ActiveRecord::Base
+class Order < ApplicationRecord
belongs_to :customer, class_name: "Patron",
foreign_key: "patron_id"
end
@@ -954,11 +965,11 @@ of its tables. The `:primary_key` option allows you to specify a different colum
For example, given we have a `users` table with `guid` as the primary key. If we want a separate `todos` table to hold the foreign key `user_id` in the `guid` column, then we can use `primary_key` to achieve this like so:
```ruby
-class User < ActiveRecord::Base
+class User < ApplicationRecord
self.primary_key = 'guid' # primary key is guid and not id
end
-class Todo < ActiveRecord::Base
+class Todo < ApplicationRecord
belongs_to :user, primary_key: 'guid'
end
```
@@ -971,11 +982,11 @@ When we execute `@user.todos.create` then the `@todo` record will have its
The `:inverse_of` option specifies the name of the `has_many` or `has_one` association that is the inverse of this association. Does not work in combination with the `:polymorphic` options.
```ruby
-class Customer < ActiveRecord::Base
+class Customer < ApplicationRecord
has_many :orders, inverse_of: :customer
end
-class Order < ActiveRecord::Base
+class Order < ApplicationRecord
belongs_to :customer, inverse_of: :orders
end
```
@@ -989,11 +1000,11 @@ Passing `true` to the `:polymorphic` option indicates that this is a polymorphic
If you set the `:touch` option to `true`, then the `updated_at` or `updated_on` timestamp on the associated object will be set to the current time whenever this object is saved or destroyed:
```ruby
-class Order < ActiveRecord::Base
+class Order < ApplicationRecord
belongs_to :customer, touch: true
end
-class Customer < ActiveRecord::Base
+class Customer < ApplicationRecord
has_many :orders
end
```
@@ -1001,7 +1012,7 @@ end
In this case, saving or destroying an order will update the timestamp on the associated customer. You can also specify a particular timestamp attribute to update:
```ruby
-class Order < ActiveRecord::Base
+class Order < ApplicationRecord
belongs_to :customer, touch: :orders_updated_at
end
```
@@ -1020,7 +1031,7 @@ object won't be validated. By default, this option is set to `false`.
There may be times when you wish to customize the query used by `belongs_to`. Such customizations can be achieved via a scope block. For example:
```ruby
-class Order < ActiveRecord::Base
+class Order < ApplicationRecord
belongs_to :customer, -> { where active: true },
dependent: :destroy
end
@@ -1038,7 +1049,7 @@ You can use any of the standard [querying methods](active_record_querying.html)
The `where` method lets you specify the conditions that the associated object must meet.
```ruby
-class Order < ActiveRecord::Base
+class Order < ApplicationRecord
belongs_to :customer, -> { where active: true }
end
```
@@ -1048,16 +1059,16 @@ end
You can use the `includes` method to specify second-order associations that should be eager-loaded when this association is used. For example, consider these models:
```ruby
-class LineItem < ActiveRecord::Base
+class LineItem < ApplicationRecord
belongs_to :order
end
-class Order < ActiveRecord::Base
+class Order < ApplicationRecord
belongs_to :customer
has_many :line_items
end
-class Customer < ActiveRecord::Base
+class Customer < ApplicationRecord
has_many :orders
end
```
@@ -1065,16 +1076,16 @@ end
If you frequently retrieve customers directly from line items (`@line_item.order.customer`), then you can make your code somewhat more efficient by including customers in the association from line items to orders:
```ruby
-class LineItem < ActiveRecord::Base
+class LineItem < ApplicationRecord
belongs_to :order, -> { includes :customer }
end
-class Order < ActiveRecord::Base
+class Order < ApplicationRecord
belongs_to :customer
has_many :line_items
end
-class Customer < ActiveRecord::Base
+class Customer < ApplicationRecord
has_many :orders
end
```
@@ -1113,7 +1124,7 @@ The `has_one` association creates a one-to-one match with another model. In data
When you declare a `has_one` association, the declaring class automatically gains five methods related to the association:
-* `association(force_reload = false)`
+* `association`
* `association=(associate)`
* `build_association(attributes = {})`
* `create_association(attributes = {})`
@@ -1122,7 +1133,7 @@ When you declare a `has_one` association, the declaring class automatically gain
In all of these methods, `association` is replaced with the symbol passed as the first argument to `has_one`. For example, given the declaration:
```ruby
-class Supplier < ActiveRecord::Base
+class Supplier < ApplicationRecord
has_one :account
end
```
@@ -1139,7 +1150,7 @@ create_account!
NOTE: When initializing a new `has_one` or `belongs_to` association you must use the `build_` prefix to build the association, rather than the `association.build` method that would be used for `has_many` or `has_and_belongs_to_many` associations. To create one, use the `create_` prefix.
-##### `association(force_reload = false)`
+##### `association`
The `association` method returns the associated object, if any. If no associated object is found, it returns `nil`.
@@ -1147,7 +1158,11 @@ The `association` method returns the associated object, if any. If no associated
@account = @supplier.account
```
-If the associated object has already been retrieved from the database for this object, the cached version will be returned. To override this behavior (and force a database read), pass `true` as the `force_reload` argument.
+If the associated object has already been retrieved from the database for this object, the cached version will be returned. To override this behavior (and force a database read), call `#reload` on the parent object.
+
+```ruby
+@account = @supplier.reload.account
+```
##### `association=(associate)`
@@ -1182,7 +1197,7 @@ Does the same as `create_association` above, but raises `ActiveRecord::RecordInv
While Rails uses intelligent defaults that will work well in most situations, there may be times when you want to customize the behavior of the `has_one` association reference. Such customizations can easily be accomplished by passing options when you create the association. For example, this association uses two such options:
```ruby
-class Supplier < ActiveRecord::Base
+class Supplier < ApplicationRecord
has_one :account, class_name: "Billing", dependent: :nullify
end
```
@@ -1214,7 +1229,7 @@ If you set the `:autosave` option to `true`, Rails will save any loaded members
If the name of the other model cannot be derived from the association name, you can use the `:class_name` option to supply the model name. For example, if a supplier has an account, but the actual name of the model containing accounts is `Billing`, you'd set things up this way:
```ruby
-class Supplier < ActiveRecord::Base
+class Supplier < ApplicationRecord
has_one :account, class_name: "Billing"
end
```
@@ -1240,7 +1255,7 @@ unallowed `NULL` value.
By convention, Rails assumes that the column used to hold the foreign key on the other model is the name of this model with the suffix `_id` added. The `:foreign_key` option lets you set the name of the foreign key directly:
```ruby
-class Supplier < ActiveRecord::Base
+class Supplier < ApplicationRecord
has_one :account, foreign_key: "supp_id"
end
```
@@ -1252,11 +1267,11 @@ TIP: In any case, Rails will not create foreign key columns for you. You need to
The `:inverse_of` option specifies the name of the `belongs_to` association that is the inverse of this association. Does not work in combination with the `:through` or `:as` options.
```ruby
-class Supplier < ActiveRecord::Base
+class Supplier < ApplicationRecord
has_one :account, inverse_of: :supplier
end
-class Account < ActiveRecord::Base
+class Account < ApplicationRecord
belongs_to :supplier, inverse_of: :account
end
```
@@ -1286,7 +1301,7 @@ If you set the `:validate` option to `true`, then associated objects will be val
There may be times when you wish to customize the query used by `has_one`. Such customizations can be achieved via a scope block. For example:
```ruby
-class Supplier < ActiveRecord::Base
+class Supplier < ApplicationRecord
has_one :account, -> { where active: true }
end
```
@@ -1303,7 +1318,7 @@ You can use any of the standard [querying methods](active_record_querying.html)
The `where` method lets you specify the conditions that the associated object must meet.
```ruby
-class Supplier < ActiveRecord::Base
+class Supplier < ApplicationRecord
has_one :account, -> { where "confirmed = 1" }
end
```
@@ -1313,16 +1328,16 @@ end
You can use the `includes` method to specify second-order associations that should be eager-loaded when this association is used. For example, consider these models:
```ruby
-class Supplier < ActiveRecord::Base
+class Supplier < ApplicationRecord
has_one :account
end
-class Account < ActiveRecord::Base
+class Account < ApplicationRecord
belongs_to :supplier
belongs_to :representative
end
-class Representative < ActiveRecord::Base
+class Representative < ApplicationRecord
has_many :accounts
end
```
@@ -1330,16 +1345,16 @@ end
If you frequently retrieve representatives directly from suppliers (`@supplier.account.representative`), then you can make your code somewhat more efficient by including representatives in the association from suppliers to accounts:
```ruby
-class Supplier < ActiveRecord::Base
+class Supplier < ApplicationRecord
has_one :account, -> { includes :representative }
end
-class Account < ActiveRecord::Base
+class Account < ApplicationRecord
belongs_to :supplier
belongs_to :representative
end
-class Representative < ActiveRecord::Base
+class Representative < ApplicationRecord
has_many :accounts
end
```
@@ -1380,7 +1395,7 @@ The `has_many` association creates a one-to-many relationship with another model
When you declare a `has_many` association, the declaring class automatically gains 16 methods related to the association:
-* `collection(force_reload = false)`
+* `collection`
* `collection<<(object, ...)`
* `collection.delete(object, ...)`
* `collection.destroy(object, ...)`
@@ -1400,7 +1415,7 @@ When you declare a `has_many` association, the declaring class automatically gai
In all of these methods, `collection` is replaced with the symbol passed as the first argument to `has_many`, and `collection_singular` is replaced with the singularized version of that symbol. For example, given the declaration:
```ruby
-class Customer < ActiveRecord::Base
+class Customer < ApplicationRecord
has_many :orders
end
```
@@ -1408,7 +1423,7 @@ end
Each instance of the `Customer` model will have these methods:
```ruby
-orders(force_reload = false)
+orders
orders<<(object, ...)
orders.delete(object, ...)
orders.destroy(object, ...)
@@ -1426,7 +1441,7 @@ orders.create(attributes = {})
orders.create!(attributes = {})
```
-##### `collection(force_reload = false)`
+##### `collection`
The `collection` method returns an array of all of the associated objects. If there are no associated objects, it returns an empty array.
@@ -1567,7 +1582,7 @@ Does the same as `collection.create` above, but raises `ActiveRecord::RecordInva
While Rails uses intelligent defaults that will work well in most situations, there may be times when you want to customize the behavior of the `has_many` association reference. Such customizations can easily be accomplished by passing options when you create the association. For example, this association uses two such options:
```ruby
-class Customer < ActiveRecord::Base
+class Customer < ApplicationRecord
has_many :orders, dependent: :delete_all, validate: false
end
```
@@ -1600,7 +1615,7 @@ If you set the `:autosave` option to `true`, Rails will save any loaded members
If the name of the other model cannot be derived from the association name, you can use the `:class_name` option to supply the model name. For example, if a customer has many orders, but the actual name of the model containing orders is `Transaction`, you'd set things up this way:
```ruby
-class Customer < ActiveRecord::Base
+class Customer < ApplicationRecord
has_many :orders, class_name: "Transaction"
end
```
@@ -1624,7 +1639,7 @@ Controls what happens to the associated objects when their owner is destroyed:
By convention, Rails assumes that the column used to hold the foreign key on the other model is the name of this model with the suffix `_id` added. The `:foreign_key` option lets you set the name of the foreign key directly:
```ruby
-class Customer < ActiveRecord::Base
+class Customer < ApplicationRecord
has_many :orders, foreign_key: "cust_id"
end
```
@@ -1636,11 +1651,11 @@ TIP: In any case, Rails will not create foreign key columns for you. You need to
The `:inverse_of` option specifies the name of the `belongs_to` association that is the inverse of this association. Does not work in combination with the `:through` or `:as` options.
```ruby
-class Customer < ActiveRecord::Base
+class Customer < ApplicationRecord
has_many :orders, inverse_of: :customer
end
-class Order < ActiveRecord::Base
+class Order < ApplicationRecord
belongs_to :customer, inverse_of: :orders
end
```
@@ -1655,7 +1670,7 @@ hold the `guid` column value as the foreign key and not `id`
value. This can be achieved like this:
```ruby
-class User < ActiveRecord::Base
+class User < ApplicationRecord
has_many :todos, primary_key: :guid
end
```
@@ -1685,7 +1700,7 @@ If you set the `:validate` option to `false`, then associated objects will not b
There may be times when you wish to customize the query used by `has_many`. Such customizations can be achieved via a scope block. For example:
```ruby
-class Customer < ActiveRecord::Base
+class Customer < ApplicationRecord
has_many :orders, -> { where processed: true }
end
```
@@ -1708,7 +1723,7 @@ You can use any of the standard [querying methods](active_record_querying.html)
The `where` method lets you specify the conditions that the associated object must meet.
```ruby
-class Customer < ActiveRecord::Base
+class Customer < ApplicationRecord
has_many :confirmed_orders, -> { where "confirmed = 1" },
class_name: "Order"
end
@@ -1717,7 +1732,7 @@ end
You can also set conditions via a hash:
```ruby
-class Customer < ActiveRecord::Base
+class Customer < ApplicationRecord
has_many :confirmed_orders, -> { where confirmed: true },
class_name: "Order"
end
@@ -1734,7 +1749,7 @@ The `extending` method specifies a named module to extend the association proxy.
The `group` method supplies an attribute name to group the result set by, using a `GROUP BY` clause in the finder SQL.
```ruby
-class Customer < ActiveRecord::Base
+class Customer < ApplicationRecord
has_many :line_items, -> { group 'orders.id' },
through: :orders
end
@@ -1745,16 +1760,16 @@ end
You can use the `includes` method to specify second-order associations that should be eager-loaded when this association is used. For example, consider these models:
```ruby
-class Customer < ActiveRecord::Base
+class Customer < ApplicationRecord
has_many :orders
end
-class Order < ActiveRecord::Base
+class Order < ApplicationRecord
belongs_to :customer
has_many :line_items
end
-class LineItem < ActiveRecord::Base
+class LineItem < ApplicationRecord
belongs_to :order
end
```
@@ -1762,16 +1777,16 @@ end
If you frequently retrieve line items directly from customers (`@customer.orders.line_items`), then you can make your code somewhat more efficient by including line items in the association from customers to orders:
```ruby
-class Customer < ActiveRecord::Base
+class Customer < ApplicationRecord
has_many :orders, -> { includes :line_items }
end
-class Order < ActiveRecord::Base
+class Order < ApplicationRecord
belongs_to :customer
has_many :line_items
end
-class LineItem < ActiveRecord::Base
+class LineItem < ApplicationRecord
belongs_to :order
end
```
@@ -1781,7 +1796,7 @@ end
The `limit` method lets you restrict the total number of objects that will be fetched through an association.
```ruby
-class Customer < ActiveRecord::Base
+class Customer < ApplicationRecord
has_many :recent_orders,
-> { order('order_date desc').limit(100) },
class_name: "Order",
@@ -1797,7 +1812,7 @@ The `offset` method lets you specify the starting offset for fetching objects vi
The `order` method dictates the order in which associated objects will be received (in the syntax used by an SQL `ORDER BY` clause).
```ruby
-class Customer < ActiveRecord::Base
+class Customer < ApplicationRecord
has_many :orders, -> { order "date_confirmed DESC" }
end
```
@@ -1818,7 +1833,7 @@ Use the `distinct` method to keep the collection free of duplicates. This is
mostly useful together with the `:through` option.
```ruby
-class Person < ActiveRecord::Base
+class Person < ApplicationRecord
has_many :readings
has_many :articles, through: :readings
end
@@ -1892,7 +1907,7 @@ The `has_and_belongs_to_many` association creates a many-to-many relationship wi
When you declare a `has_and_belongs_to_many` association, the declaring class automatically gains 16 methods related to the association:
-* `collection(force_reload = false)`
+* `collection`
* `collection<<(object, ...)`
* `collection.delete(object, ...)`
* `collection.destroy(object, ...)`
@@ -1912,7 +1927,7 @@ When you declare a `has_and_belongs_to_many` association, the declaring class au
In all of these methods, `collection` is replaced with the symbol passed as the first argument to `has_and_belongs_to_many`, and `collection_singular` is replaced with the singularized version of that symbol. For example, given the declaration:
```ruby
-class Part < ActiveRecord::Base
+class Part < ApplicationRecord
has_and_belongs_to_many :assemblies
end
```
@@ -1920,7 +1935,7 @@ end
Each instance of the `Part` model will have these methods:
```ruby
-assemblies(force_reload = false)
+assemblies
assemblies<<(object, ...)
assemblies.delete(object, ...)
assemblies.destroy(object, ...)
@@ -1945,7 +1960,7 @@ If the join table for a `has_and_belongs_to_many` association has additional col
WARNING: The use of extra attributes on the join table in a `has_and_belongs_to_many` association is deprecated. If you require this sort of complex behavior on the table that joins two models in a many-to-many relationship, you should use a `has_many :through` association instead of `has_and_belongs_to_many`.
-##### `collection(force_reload = false)`
+##### `collection`
The `collection` method returns an array of all of the associated objects. If there are no associated objects, it returns an empty array.
@@ -2066,7 +2081,7 @@ Does the same as `collection.create`, but raises `ActiveRecord::RecordInvalid` i
While Rails uses intelligent defaults that will work well in most situations, there may be times when you want to customize the behavior of the `has_and_belongs_to_many` association reference. Such customizations can easily be accomplished by passing options when you create the association. For example, this association uses two such options:
```ruby
-class Parts < ActiveRecord::Base
+class Parts < ApplicationRecord
has_and_belongs_to_many :assemblies, -> { readonly },
autosave: true
end
@@ -2088,7 +2103,7 @@ By convention, Rails assumes that the column in the join table used to hold the
TIP: The `:foreign_key` and `:association_foreign_key` options are useful when setting up a many-to-many self-join. For example:
```ruby
-class User < ActiveRecord::Base
+class User < ApplicationRecord
has_and_belongs_to_many :friends,
class_name: "User",
foreign_key: "this_user_id",
@@ -2105,7 +2120,7 @@ If you set the `:autosave` option to `true`, Rails will save any loaded members
If the name of the other model cannot be derived from the association name, you can use the `:class_name` option to supply the model name. For example, if a part has many assemblies, but the actual name of the model containing assemblies is `Gadget`, you'd set things up this way:
```ruby
-class Parts < ActiveRecord::Base
+class Parts < ApplicationRecord
has_and_belongs_to_many :assemblies, class_name: "Gadget"
end
```
@@ -2115,7 +2130,7 @@ end
By convention, Rails assumes that the column in the join table used to hold the foreign key pointing to this model is the name of this model with the suffix `_id` added. The `:foreign_key` option lets you set the name of the foreign key directly:
```ruby
-class User < ActiveRecord::Base
+class User < ApplicationRecord
has_and_belongs_to_many :friends,
class_name: "User",
foreign_key: "this_user_id",
@@ -2136,7 +2151,7 @@ If you set the `:validate` option to `false`, then associated objects will not b
There may be times when you wish to customize the query used by `has_and_belongs_to_many`. Such customizations can be achieved via a scope block. For example:
```ruby
-class Parts < ActiveRecord::Base
+class Parts < ApplicationRecord
has_and_belongs_to_many :assemblies, -> { where active: true }
end
```
@@ -2152,14 +2167,14 @@ You can use any of the standard [querying methods](active_record_querying.html)
* `order`
* `readonly`
* `select`
-* `uniq`
+* `distinct`
##### `where`
The `where` method lets you specify the conditions that the associated object must meet.
```ruby
-class Parts < ActiveRecord::Base
+class Parts < ApplicationRecord
has_and_belongs_to_many :assemblies,
-> { where "factory = 'Seattle'" }
end
@@ -2168,7 +2183,7 @@ end
You can also set conditions via a hash:
```ruby
-class Parts < ActiveRecord::Base
+class Parts < ApplicationRecord
has_and_belongs_to_many :assemblies,
-> { where factory: 'Seattle' }
end
@@ -2185,7 +2200,7 @@ The `extending` method specifies a named module to extend the association proxy.
The `group` method supplies an attribute name to group the result set by, using a `GROUP BY` clause in the finder SQL.
```ruby
-class Parts < ActiveRecord::Base
+class Parts < ApplicationRecord
has_and_belongs_to_many :assemblies, -> { group "factory" }
end
```
@@ -2199,7 +2214,7 @@ You can use the `includes` method to specify second-order associations that shou
The `limit` method lets you restrict the total number of objects that will be fetched through an association.
```ruby
-class Parts < ActiveRecord::Base
+class Parts < ApplicationRecord
has_and_belongs_to_many :assemblies,
-> { order("created_at DESC").limit(50) }
end
@@ -2214,7 +2229,7 @@ The `offset` method lets you specify the starting offset for fetching objects vi
The `order` method dictates the order in which associated objects will be received (in the syntax used by an SQL `ORDER BY` clause).
```ruby
-class Parts < ActiveRecord::Base
+class Parts < ApplicationRecord
has_and_belongs_to_many :assemblies,
-> { order "assembly_name ASC" }
end
@@ -2228,9 +2243,9 @@ If you use the `readonly` method, then the associated objects will be read-only
The `select` method lets you override the SQL `SELECT` clause that is used to retrieve data about the associated objects. By default, Rails retrieves all columns.
-##### `uniq`
+##### `distinct`
-Use the `uniq` method to remove duplicates from the collection.
+Use the `distinct` method to remove duplicates from the collection.
#### When are Objects Saved?
@@ -2256,7 +2271,7 @@ Association callbacks are similar to normal callbacks, but they are triggered by
You define association callbacks by adding options to the association declaration. For example:
```ruby
-class Customer < ActiveRecord::Base
+class Customer < ApplicationRecord
has_many :orders, before_add: :check_credit_limit
def check_credit_limit(order)
@@ -2270,7 +2285,7 @@ Rails passes the object being added or removed to the callback.
You can stack callbacks on a single event by passing them as an array:
```ruby
-class Customer < ActiveRecord::Base
+class Customer < ApplicationRecord
has_many :orders,
before_add: [:check_credit_limit, :calculate_shipping_charges]
@@ -2291,7 +2306,7 @@ If a `before_add` callback throws an exception, the object does not get added to
You're not limited to the functionality that Rails automatically builds into association proxy objects. You can also extend these objects through anonymous modules, adding new finders, creators, or other methods. For example:
```ruby
-class Customer < ActiveRecord::Base
+class Customer < ApplicationRecord
has_many :orders do
def find_by_order_prefix(order_number)
find_by(region_id: order_number[0..2])
@@ -2309,11 +2324,11 @@ module FindRecentExtension
end
end
-class Customer < ActiveRecord::Base
+class Customer < ApplicationRecord
has_many :orders, -> { extending FindRecentExtension }
end
-class Supplier < ActiveRecord::Base
+class Supplier < ApplicationRecord
has_many :deliveries, -> { extending FindRecentExtension }
end
```
diff --git a/guides/source/autoloading_and_reloading_constants.md b/guides/source/autoloading_and_reloading_constants.md
index 2b6d7e4044..de0fa2fdc0 100644
--- a/guides/source/autoloading_and_reloading_constants.md
+++ b/guides/source/autoloading_and_reloading_constants.md
@@ -181,14 +181,14 @@ constant.
That is,
```ruby
-class Project < ActiveRecord::Base
+class Project < ApplicationRecord
end
```
performs a constant assignment equivalent to
```ruby
-Project = Class.new(ActiveRecord::Base)
+Project = Class.new(ApplicationRecord)
```
including setting the name of the class as a side-effect:
@@ -685,7 +685,7 @@ to trigger the heuristic is defined in the conflicting place.
### Automatic Modules
When a module acts as a namespace, Rails does not require the application to
-defines a file for it, a directory matching the namespace is enough.
+define a file for it, a directory matching the namespace is enough.
Suppose an application has a back office whose controllers are stored in
`app/controllers/admin`. If the `Admin` module is not yet loaded when
@@ -790,7 +790,7 @@ Constant Reloading
When `config.cache_classes` is false Rails is able to reload autoloaded
constants.
-For example, in you're in a console session and edit some file behind the
+For example, if you're in a console session and edit some file behind the
scenes, the code can be reloaded with the `reload!` command:
```
@@ -912,7 +912,7 @@ these classes:
```ruby
# app/models/polygon.rb
-class Polygon < ActiveRecord::Base
+class Polygon < ApplicationRecord
end
# app/models/triangle.rb
@@ -987,7 +987,7 @@ root class:
```ruby
# app/models/polygon.rb
-class Polygon < ActiveRecord::Base
+class Polygon < ApplicationRecord
end
require_dependency ‘square’
```
diff --git a/guides/source/caching_with_rails.md b/guides/source/caching_with_rails.md
index 9a56233e4a..3a1a1ccfe6 100644
--- a/guides/source/caching_with_rails.md
+++ b/guides/source/caching_with_rails.md
@@ -175,11 +175,11 @@ your app will serve stale data. To fix this, we tie the models together with
the `touch` method:
```ruby
-class Product < ActiveRecord::Base
+class Product < ApplicationRecord
has_many :games
end
-class Game < ActiveRecord::Base
+class Game < ApplicationRecord
belongs_to :product, touch: true
end
```
@@ -284,7 +284,7 @@ The most efficient way to implement low-level caching is using the `Rails.cache.
Consider the following example. An application has a `Product` model with an instance method that looks up the product’s price on a competing website. The data returned by this method would be perfect for low-level caching:
```ruby
-class Product < ActiveRecord::Base
+class Product < ApplicationRecord
def competing_price
Rails.cache.fetch("#{cache_key}/competing_price", expires_in: 12.hours) do
Competitor::API.find_price(id)
diff --git a/guides/source/command_line.md b/guides/source/command_line.md
index cd265331d6..5240b5f343 100644
--- a/guides/source/command_line.md
+++ b/guides/source/command_line.md
@@ -39,7 +39,7 @@ INFO: You can install the rails gem by typing `gem install rails`, if you don't
```bash
$ rails new commandsapp
create
- create README.rdoc
+ create README.md
create Rakefile
create config.ru
create .gitignore
@@ -392,7 +392,7 @@ rake assets:clobber # Remove compiled assets
rake assets:precompile # Compile all the assets named in config.assets.precompile
rake db:create # Create the database from config/database.yml for the current Rails.env
...
-rake log:clear # Truncates all *.log files in log/ to zero bytes (specify which logs with LOGS=test,development)
+rake log:clear # Truncates all/specified *.log files in log/ to zero bytes (specify which logs with LOGS=test,development)
rake middleware # Prints out your Rack middleware stack
...
rake tmp:clear # Clear cache and socket files from tmp/ (narrow w/ tmp:cache:clear, tmp:sockets:clear)
@@ -412,7 +412,7 @@ Ruby version 2.2.2 (x86_64-linux)
RubyGems version 2.4.6
Rack version 1.6
JavaScript Runtime Node.js (V8)
-Middleware Rack::Sendfile, ActionDispatch::Static, Rack::Lock, #<ActiveSupport::Cache::Strategy::LocalCache::Middleware:0x007ffd131a7c88>, Rack::Runtime, Rack::MethodOverride, ActionDispatch::RequestId, Rails::Rack::Logger, ActionDispatch::ShowExceptions, ActionDispatch::DebugExceptions, ActionDispatch::RemoteIp, ActionDispatch::Reloader, ActionDispatch::Callbacks, ActiveRecord::Migration::CheckPending, ActiveRecord::ConnectionAdapters::ConnectionManagement, ActiveRecord::QueryCache, ActionDispatch::Cookies, ActionDispatch::Session::CookieStore, ActionDispatch::Flash, ActionDispatch::ParamsParser, Rack::Head, Rack::ConditionalGet, Rack::ETag
+Middleware Rack::Sendfile, ActionDispatch::Static, Rack::Lock, #<ActiveSupport::Cache::Strategy::LocalCache::Middleware:0x007ffd131a7c88>, Rack::Runtime, Rack::MethodOverride, ActionDispatch::RequestId, Rails::Rack::Logger, ActionDispatch::ShowExceptions, ActionDispatch::DebugExceptions, ActionDispatch::RemoteIp, ActionDispatch::Reloader, ActionDispatch::Callbacks, ActiveRecord::Migration::CheckPending, ActiveRecord::ConnectionAdapters::ConnectionManagement, ActiveRecord::QueryCache, ActionDispatch::Cookies, ActionDispatch::Session::CookieStore, ActionDispatch::Flash, Rack::Head, Rack::ConditionalGet, Rack::ETag
Application root /home/foobar/commandsapp
Environment development
Database adapter sqlite3
@@ -584,8 +584,8 @@ $ rails new . --git --database=postgresql
create tmp/pids
create Rakefile
add 'Rakefile'
- create README.rdoc
-add 'README.rdoc'
+ create README.md
+add 'README.md'
create app/controllers/application_controller.rb
add 'app/controllers/application_controller.rb'
create app/helpers/application_helper.rb
diff --git a/guides/source/configuring.md b/guides/source/configuring.md
index 47c275609e..0b24d4d06a 100644
--- a/guides/source/configuring.md
+++ b/guides/source/configuring.md
@@ -35,7 +35,7 @@ In general, the work of configuring Rails means configuring the components of Ra
For example, the `config/application.rb` file includes this setting:
```ruby
-config.autoload_paths += %W(#{config.root}/extras)
+config.time_zone = 'Central Time (US & Canada)'
```
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`:
@@ -98,13 +98,13 @@ application. Accepts a valid week day symbol (e.g. `:monday`).
* `config.exceptions_app` sets the exceptions application invoked by the ShowException middleware when an exception happens. Defaults to `ActionDispatch::PublicExceptions.new(Rails.public_path)`.
-* `config.file_watcher` the class used to detect file updates in the filesystem when `config.reload_classes_only_on_change` is true. Must conform to `ActiveSupport::FileUpdateChecker` API.
+* `config.file_watcher` is the class used to detect file updates in the file system when `config.reload_classes_only_on_change` is true. Rails ships with `ActiveSupport::FileUpdateChecker`, the default, and `ActiveSupport::EventedFileUpdateChecker` (this one depends on the [listen](https://github.com/guard/listen) gem). Custom classes must conform to the `ActiveSupport::FileUpdateChecker` API.
* `config.filter_parameters` used for filtering out the parameters that
you don't want shown in the logs, such as passwords or credit card
numbers. New applications filter out passwords by adding the following `config.filter_parameters+=[:password]` in `config/initializers/filter_parameter_logging.rb`.
-* `config.force_ssl` forces all requests to be under HTTPS protocol by using `ActionDispatch::SSL` middleware.
+* `config.force_ssl` forces all requests to be served over HTTPS by using the `ActionDispatch::SSL` middleware. This can be configured by setting `config.ssl_options` - see the [ActionDispatch::SSL documentation](http://edgeapi.rubyonrails.org/classes/ActionDispatch/SSL.html) for details.
* `config.log_formatter` defines the formatter of the Rails logger. This option defaults to an instance of `ActiveSupport::Logger::SimpleFormatter` for all modes except production, where it defaults to `Logger::Formatter`.
@@ -122,7 +122,7 @@ defaults to `:debug` for all environments. The available log levels are: `:debug
* `secrets.secret_key_base` is used for specifying a key which allows sessions for the application to be verified against a known secure key to prevent tampering. Applications get `secrets.secret_key_base` initialized to a random key present in `config/secrets.yml`.
-* `config.serve_static_files` configures Rails to serve static files. This option defaults to true, but in the production environment it is set to false because the server software (e.g. NGINX or Apache) used to run the application should serve static files instead. If you are running or testing your app in production mode using WEBrick (it is not recommended to use WEBrick in production) set the option to true. Otherwise, you won't be able to use page caching and request for files that exist under the public directory.
+* `config.public_file_server.enabled` configures Rails to serve static files from the public directory. This option defaults to true, but in the production environment it is set to false because the server software (e.g. NGINX or Apache) used to run the application should serve static files instead. If you are running or testing your app in production mode using WEBrick (it is not recommended to use WEBrick in production) set the option to true. Otherwise, you won't be able to use page caching and request for files that exist under the public directory.
* `config.session_store` is usually set up in `config/initializers/session_store.rb` and specifies what class to use to store the session. Possible values are `:cookie_store` which is the default, `:mem_cache_store`, and `:disabled`. The last one tells Rails not to deal with sessions. Custom session stores can also be specified:
@@ -198,8 +198,8 @@ The full set of methods that can be used in this block are as follows:
Every Rails application comes with a standard set of middleware which it uses in this order in the development environment:
-* `ActionDispatch::SSL` forces every request to be under HTTPS protocol. Will be available if `config.force_ssl` is set to `true`. Options passed to this can be configured by using `config.ssl_options`.
-* `ActionDispatch::Static` is used to serve static assets. Disabled if `config.serve_static_files` is `false`. Set `config.static_index` if you need to serve a static directory index file that is not named `index`. For example, to serve `main.html` instead of `index.html` for directory requests, set `config.static_index` to `"main"`.
+* `ActionDispatch::SSL` forces every request to be served using HTTPS. Enabled if `config.force_ssl` is set to `true`. Options passed to this can be configured by setting `config.ssl_options`.
+* `ActionDispatch::Static` is used to serve static assets. Disabled if `config.public_file_server.enabled` is `false`. Set `config.public_file_server.index_name` if you need to serve a static directory index file that is not named `index`. For example, to serve `main.html` instead of `index.html` for directory requests, set `config.public_file_server.index_name` to `"main"`.
* `Rack::Lock` wraps the app in mutex so it can only be called by a single thread at a time. Only enabled when `config.cache_classes` is `false`.
* `ActiveSupport::Cache::Strategy::LocalCache` serves as a basic memory backed cache. This cache is not thread safe and is intended only for serving as a temporary memory cache for a single thread.
* `Rack::Runtime` sets an `X-Runtime` header, containing the time (in seconds) taken to execute the request.
@@ -214,7 +214,6 @@ Every Rails application comes with a standard set of middleware which it uses in
* `ActionDispatch::Cookies` sets cookies for the request.
* `ActionDispatch::Session::CookieStore` is responsible for storing the session in cookies. An alternate middleware can be used for this by changing the `config.action_controller.session_store` to an alternate value. Additionally, options passed to this can be configured by using `config.action_controller.session_options`.
* `ActionDispatch::Flash` sets up the `flash` keys. Only available if `config.action_controller.session_store` is set to a value.
-* `ActionDispatch::ParamsParser` parses out parameters from the request into `params`.
* `Rack::MethodOverride` allows the method to be overridden if `params[:_method]` is set. This is the middleware which supports the PATCH, PUT, and DELETE HTTP method types.
* `Rack::Head` converts HEAD requests to GET requests and serves them as so.
@@ -245,7 +244,7 @@ config.middleware.swap ActionController::Failsafe, Lifo::Failsafe
They can also be removed from the stack completely:
```ruby
-config.middleware.delete "Rack::MethodOverride"
+config.middleware.delete Rack::MethodOverride
```
### Configuring i18n
@@ -267,8 +266,8 @@ All these configuration options are delegated to the `I18n` library.
* `config.active_record.logger` accepts a logger conforming to the interface of Log4r or the default Ruby Logger class, which is then passed on to any new database connections made. You can retrieve this logger by calling `logger` on either an Active Record model class or an Active Record model instance. Set to `nil` to disable logging.
* `config.active_record.primary_key_prefix_type` lets you adjust the naming for primary key columns. By default, Rails assumes that primary key columns are named `id` (and this configuration option doesn't need to be set.) There are two other choices:
-** `:table_name` would make the primary key for the Customer class `customerid`
-** `:table_name_with_underscore` would make the primary key for the Customer class `customer_id`
+ * `:table_name` would make the primary key for the Customer class `customerid`
+ * `:table_name_with_underscore` would make the primary key for the Customer class `customer_id`
* `config.active_record.table_name_prefix` lets you set a global string to be prepended to table names. If you set this to `northwest_`, then the Customer class will look for `northwest_customers` as its table. The default is an empty string.
@@ -305,16 +304,22 @@ All these configuration options are delegated to the `I18n` library.
`:all` which always dumps all schemas regardless of the schema_search_path,
or a string of comma separated schemas.
-* `config.active_record.belongs_to_required_by_default` is a boolean value and controls whether `belongs_to` association is required by default.
+* `config.active_record.belongs_to_required_by_default` is a boolean value and
+ controls whether a record fails validation if `belongs_to` association is not
+ present.
* `config.active_record.warn_on_records_fetched_greater_than` allows setting a
warning threshold for query result size. If the number of records returned
by a query exceeds the threshold, a warning is logged. This can be used to
identify queries which might be causing memory bloat.
+* `config.active_record.index_nested_attribute_errors` allows errors for nested
+ has_many relationships to be displayed with an index as well as the error.
+ Defaults to false.
+
The MySQL adapter adds one additional configuration option:
-* `ActiveRecord::ConnectionAdapters::MysqlAdapter.emulate_booleans` controls whether Active Record will consider all `tinyint(1)` columns in a MySQL database to be booleans and is true by default.
+* `ActiveRecord::ConnectionAdapters::Mysql2Adapter.emulate_booleans` controls whether Active Record will consider all `tinyint(1)` columns in a MySQL database to be booleans and is true by default.
The schema dumper adds one additional configuration option:
@@ -330,8 +335,6 @@ The schema dumper adds one additional configuration option:
* `config.action_controller.default_static_extension` configures the extension used for cached pages. Defaults to `.html`.
-* `config.action_controller.default_charset` specifies the default character set for all renders. The default is "utf-8".
-
* `config.action_controller.include_all_helpers` configures whether all view helpers are available everywhere or are scoped to the corresponding controller. If set to `false`, `UsersHelper` methods are only available for views rendered as part of `UsersController`. If `true`, `UsersHelper` methods are available everywhere. The default is `true`.
* `config.action_controller.logger` accepts a logger conforming to the interface of Log4r or the default Ruby Logger class, which is then used to log information from Action Controller. Set to `nil` to disable logging.
@@ -340,6 +343,10 @@ The schema dumper adds one additional configuration option:
* `config.action_controller.allow_forgery_protection` enables or disables CSRF protection. By default this is `false` in test mode and `true` in all other modes.
+* `config.action_controller.forgery_protection_origin_check` configures whether the HTTP `Origin` header should be checked against the site's origin as an additional CSRF defense.
+
+* `config.action_controller.per_form_csrf_tokens` configures whether CSRF tokens are only valid for the method/action they were generated for.
+
* `config.action_controller.relative_url_root` can be used to tell Rails that you are [deploying to a subdirectory](configuring.html#deploy-to-a-subdirectory-relative-url-root). The default is `ENV['RAILS_RELATIVE_URL_ROOT']`.
* `config.action_controller.permit_all_parameters` sets all the parameters for mass assignment to be permitted by default. The default value is `false`.
@@ -362,6 +369,8 @@ The schema dumper adds one additional configuration option:
}
```
+* `config.action_dispatch.default_charset` specifies the default character set for all renders. Defaults to `nil`.
+
* `config.action_dispatch.tld_length` sets the TLD (top-level domain) length for the application. Defaults to `1`.
* `config.action_dispatch.http_auth_salt` sets the HTTP Auth salt value. Defaults
@@ -451,6 +460,11 @@ encrypted cookies salt value. Defaults to `'signed encrypted cookie'`.
* `config.action_view.raise_on_missing_translations` determines whether an
error should be raised for missing translations.
+* `config.action_view.automatically_disable_submit_tag` determines whether
+ submit_tag should automatically disable on click, this defaults to true.
+
+* `config.action_view.debug_missing_translation` determins whether to wrap the missing translations key in a `<span>` tag or not. This defaults to true.
+
### Configuring Action Mailer
There are a number of settings available on `config.action_mailer`:
@@ -533,7 +547,7 @@ There are a few configuration options available in Active Support:
* `config.active_support.time_precision` sets the precision of JSON encoded time values. Defaults to `3`.
-* `config.active_support.halt_callback_chains_on_return_false` specifies whether ActiveRecord, ActiveModel and ActiveModel::Validations callback chains can be halted by returning `false` in a 'before' callback. Defaults to `true`.
+* `ActiveSupport.halt_callback_chains_on_return_false` specifies whether Active Record and Active Model callback chains can be halted by returning `false` in a 'before' callback. When set to `false`, callback chains are halted only when explicitly done so with `throw(:abort)`. When set to `true`, callback chains are halted when a callback returns false (the previous behavior before Rails 5) and a deprecation warning is given. Defaults to `true` during the deprecation period. New Rails 5 apps generate an initializer file called `callback_terminator.rb` which sets the value to `false`. This file is *not* added when running `rake rails:update`, so returning `false` will still work on older apps ported to Rails 5 and display a deprecation warning to prompt users to update their code.
* `ActiveSupport::Logger.silencer` is set to `false` to disable the ability to silence logging in a block. The default is `true`.
@@ -639,7 +653,7 @@ TIP: You don't have to update the database configurations manually. If you look
### Connection Preference
-Since there are two ways to set your connection, via environment variable it is important to understand how the two can interact.
+Since there are two ways to configure your connection (using `config/database.yml` or using an environment variable) it is important to understand how they can interact.
If you have an empty `config/database.yml` file but your `ENV['DATABASE_URL']` is present, then Rails will connect to the database via your environment variable:
@@ -1035,9 +1049,9 @@ Below is a comprehensive list of all the initializers found in Rails in the orde
* `action_mailer.compile_config_methods` Initializes methods for the config settings specified so that they are quicker to access.
-* `set_load_path` This initializer runs before `bootstrap_hook`. Adds the `vendor`, `lib`, all directories of `app` and any paths specified by `config.load_paths` to `$LOAD_PATH`.
+* `set_load_path` This initializer runs before `bootstrap_hook`. Adds paths specified by `config.load_paths` and all autoload paths to `$LOAD_PATH`.
-* `set_autoload_paths` This initializer runs before `bootstrap_hook`. Adds all sub-directories of `app` and paths specified by `config.autoload_paths` to `ActiveSupport::Dependencies.autoload_paths`.
+* `set_autoload_paths` This initializer runs before `bootstrap_hook`. Adds all sub-directories of `app` and paths specified by `config.autoload_paths`, `config.eager_load_paths` and `config.autoload_once_paths` to `ActiveSupport::Dependencies.autoload_paths`.
* `add_routing_paths` Loads (by default) all `config/routes.rb` files (in the application and railties, including engines) and sets up the routes for the application.
@@ -1093,7 +1107,7 @@ you and wait for a connection from the pool. If it cannot get a connection, a
timeout error similar to that given below will be thrown.
```ruby
-ActiveRecord::ConnectionTimeoutError - could not obtain a database connection within 5 seconds. The max pool size is currently 5; consider increasing it:
+ActiveRecord::ConnectionTimeoutError - could not obtain a database connection within 5.000 seconds (waited 5.000 seconds)
```
If you get the above error, you might want to increase the size of the
@@ -1108,18 +1122,45 @@ Custom configuration
You can configure your own code through the Rails configuration object with custom configuration. It works like this:
```ruby
- config.x.payment_processing.schedule = :daily
- config.x.payment_processing.retries = 3
- config.x.super_debugger = true
+ config.payment_processing.schedule = :daily
+ config.payment_processing.retries = 3
+ config.super_debugger = true
```
These configuration points are then available through the configuration object:
```ruby
- Rails.configuration.x.payment_processing.schedule # => :daily
- Rails.configuration.x.payment_processing.retries # => 3
- Rails.configuration.x.super_debugger # => true
- Rails.configuration.x.super_debugger.not_set # => nil
+ Rails.configuration.payment_processing.schedule # => :daily
+ Rails.configuration.payment_processing.retries # => 3
+ Rails.configuration.super_debugger # => true
+ Rails.configuration.super_debugger.not_set # => nil
+ ```
+
+You can also use `Rails::Application.config_for` to load whole configuration files:
+
+ ```ruby
+ # config/payment.yml:
+ production:
+ environment: production
+ merchant_id: production_merchant_id
+ public_key: production_public_key
+ private_key: production_private_key
+ development:
+ environment: sandbox
+ merchant_id: development_merchant_id
+ public_key: development_public_key
+ private_key: development_private_key
+
+ # config/application.rb
+ module MyApp
+ class Application < Rails::Application
+ config.payment = config_for(:payment)
+ end
+ end
+ ```
+
+ ```ruby
+ Rails.configuration.payment['merchant_id'] # => production_merchant_id or development_merchant_id
```
Search Engines Indexing
@@ -1141,3 +1182,25 @@ Disallow: /
To block just specific pages, it's necessary to use a more complex syntax. Learn
it on the [official documentation](http://www.robotstxt.org/robotstxt.html).
+
+Evented File System Monitor
+---------------------------
+
+If the [listen gem](https://github.com/guard/listen) is loaded Rails uses an
+evented file system monitor to detect changes when `config.cache_classes` is
+false:
+
+```ruby
+group :development do
+ gem 'listen', '~> 3.0.4'
+end
+```
+
+Otherwise, in every request Rails walks the application tree to check if
+anything has changed.
+
+On Linux and Mac OS X no additional gems are needed, but some are required
+[for *BSD](https://github.com/guard/listen#on-bsd) and
+[for Windows](https://github.com/guard/listen#on-windows).
+
+Note that [some setups are unsupported](https://github.com/guard/listen#issues--limitations).
diff --git a/guides/source/contributing_to_ruby_on_rails.md b/guides/source/contributing_to_ruby_on_rails.md
index 3b944f1274..cbc304c87f 100644
--- a/guides/source/contributing_to_ruby_on_rails.md
+++ b/guides/source/contributing_to_ruby_on_rails.md
@@ -15,6 +15,9 @@ After reading this guide, you will know:
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.
+As mentioned in [Rails
+README](https://github.com/rails/rails/blob/master/README.md), everyone interacting in Rails and its sub-projects' codebases, issue trackers, chat rooms, and mailing lists is expected to follow the Rails [code of conduct](http://rubyonrails.org/conduct/).
+
--------------------------------------------------------------------------------
Reporting an Issue
@@ -125,11 +128,11 @@ Contributing to the Rails Documentation
Ruby on Rails has two main sets of documentation: the guides, which help you
learn about Ruby on Rails, and the API, which serves as a reference.
-You can help improve the Rails guides by making them more coherent, consistent or readable, adding missing information, correcting factual errors, fixing typos, or bringing it up to date with the latest edge Rails. To get involved in the translation of Rails guides, please see [Translating Rails Guides](https://wiki.github.com/rails/docrails/translating-rails-guides).
+You can help improve the Rails guides by making them more coherent, consistent or readable, adding missing information, correcting factual errors, fixing typos, or bringing them up to date with the latest edge Rails.
You can either open a pull request to [Rails](http://github.com/rails/rails) or
ask the [Rails core team](http://rubyonrails.org/core) for commit access on
-[docrails](http://github.com/rails/docrails) if you contribute regularly.
+docrails if you contribute regularly.
Please do not open pull requests in docrails, if you'd like to get feedback on your
change, ask for it in [Rails](http://github.com/rails/rails) instead.
@@ -145,6 +148,42 @@ NOTE: To help our CI servers you should add [ci skip] to your documentation comm
WARNING: Docrails has a very strict policy: no code can be touched whatsoever, no matter how trivial or small the change. Only RDoc and guides can be edited via docrails. Also, CHANGELOGs should never be edited in docrails.
+Translating Rails Guides
+------------------------
+
+We are happy to have people volunteer to translate the Rails guides into their own language.
+If you want to translate the Rails guides in your own language, follows these steps:
+
+* Fork the project (rails/rails).
+* Add a source folder for your own language, for example: *guides/source/it-IT* for Italian.
+* Copy the contents of *guides/source* into your own language directory and translate them.
+* Do NOT translate the HTML files, as they are automatically generated.
+
+To generate the guides in HTML format cd into the *guides* direcotry then run (eg. for it-IT):
+
+```bash
+$ bundle install
+$ bundle exec rake guides:generate:html GUIDES_LANGUAGE=it-IT
+```
+
+This will generate the guides in an *output* directory.
+
+NOTE: The instructions are for Rails > 4. The Redcarpet Gem doesn't work with JRuby.
+
+Translation efforts we know about (various versions):
+
+* **Italian**: [https://github.com/rixlabs/docrails](https://github.com/rixlabs/docrails)
+* **Spanish**: [http://wiki.github.com/gramos/docrails](http://wiki.github.com/gramos/docrails)
+* **Polish**: [http://github.com/apohllo/docrails/tree/master](http://github.com/apohllo/docrails/tree/master)
+* **French** : [http://github.com/railsfrance/docrails](http://github.com/railsfrance/docrails)
+* **Czech** : [https://github.com/rubyonrails-cz/docrails/tree/czech](https://github.com/rubyonrails-cz/docrails/tree/czech)
+* **Turkish** : [https://github.com/ujk/docrails/tree/master](https://github.com/ujk/docrails/tree/master)
+* **Korean** : [https://github.com/rorlakr/rails-guides](https://github.com/rorlakr/rails-guides)
+* **Simplified Chinese** : [https://github.com/ruby-china/guides](https://github.com/ruby-china/guides)
+* **Traditional Chinese** : [https://github.com/docrails-tw/guides](https://github.com/docrails-tw/guides)
+* **Russian** : [https://github.com/morsbox/rusrails](https://github.com/morsbox/rusrails)
+* **Japanese** : [https://github.com/yasslab/railsguides.jp](https://github.com/yasslab/railsguides.jp)
+
Contributing to the Rails Code
------------------------------
@@ -315,10 +354,9 @@ $ cd activerecord
$ bundle exec rake test:sqlite3
```
-You can now run the tests as you did for `sqlite3`. The tasks are respectively
+You can now run the tests as you did for `sqlite3`. The tasks are respectively:
```bash
-test:mysql
test:mysql2
test:postgresql
```
diff --git a/guides/source/debugging_rails_applications.md b/guides/source/debugging_rails_applications.md
index 44434c164b..0046ff7b4e 100644
--- a/guides/source/debugging_rails_applications.md
+++ b/guides/source/debugging_rails_applications.md
@@ -346,23 +346,13 @@ by asking the debugger for help. Type: `help`
```
(byebug) help
-byebug 2.7.0
+ h[elp][ <cmd>[ <subcmd>]]
-Type 'help <command-name>' for help on a specific command
-
-Available commands:
-backtrace delete enable help list pry next restart source up
-break disable eval info method ps save step var
-catch display exit interrupt next putl set thread
-condition down finish irb p quit show trace
-continue edit frame kill pp reload skip undisplay
+ help -- prints this help.
+ help <cmd> -- prints help on command <cmd>.
+ help <cmd> <subcmd> -- prints help on <cmd>'s subcommand <subcmd>.
```
-TIP: To view the help menu for any command use `help <command-name>` at the
-debugger prompt. For example: _`help list`_. You can abbreviate any debugging
-command by supplying just enough letters to distinguish them from other
-commands. For example, you can use `l` for the `list` command.
-
To see the previous ten lines you should type `list-` (or `l-`).
```
@@ -469,12 +459,12 @@ The debugger can list, stop, resume and switch between running threads by using
the `thread` command (or the abbreviated `th`). This command has a handful of
options:
-* `thread` shows the current thread.
-* `thread list` is used to list all threads and their statuses. The plus +
+* `thread`: shows the current thread.
+* `thread list`: is used to list all threads and their statuses. The plus +
character and the number indicates the current thread of execution.
-* `thread stop _n_` stop thread _n_.
-* `thread resume _n_` resumes thread _n_.
-* `thread switch _n_` switches the current thread context to _n_.
+* `thread stop _n_`: stop thread _n_.
+* `thread resume _n_`: resumes thread _n_.
+* `thread switch _n_`: switches the current thread context to _n_.
This command is very helpful when you are debugging concurrent threads and need
to verify that there are no race conditions in your code.
@@ -618,7 +608,7 @@ Started GET "/" for 127.0.0.1 at 2014-04-11 13:39:23 +0200
Processing by ArticlesController#index as HTML
[1, 8] in /home/davidr/Proyectos/test_app/app/models/article.rb
- 1: class Article < ActiveRecord::Base
+ 1: class Article < ApplicationRecord
2:
3: def self.find_recent(limit = 10)
4: byebug
@@ -630,13 +620,16 @@ Processing by ArticlesController#index as HTML
(byebug)
```
-If we use `next`, we want go deep inside method calls. Instead, byebug will go
-to the next line within the same context. In this case, this is the last line of
-the method, so `byebug` will jump to next next line of the previous frame.
+If we use `next`, we won't go deep inside method calls. Instead, `byebug` will
+go to the next line within the same context. In this case, it is the last line
+of the current method, so `byebug` will return to the next line of the caller
+method.
```
(byebug) next
-Next went up a frame because previous frame finished
+
+Next advances to the next line (line 6: `end`), which returns to the next line
+of the caller method:
[4, 13] in /PathTo/project/test_app/app/controllers/articles_controller.rb
4: # GET /articles
@@ -653,8 +646,8 @@ Next went up a frame because previous frame finished
(byebug)
```
-If we use `step` in the same situation, we will literally go to the next Ruby
-instruction to be executed. In this case, Active Support's `week` method.
+If we use `step` in the same situation, `byebug` will literally go to the next
+Ruby instruction to be executed -- in this case, Active Support's `week` method.
```
(byebug) step
@@ -752,12 +745,12 @@ To list all active catchpoints use `catch`.
There are two ways to resume execution of an application that is stopped in the
debugger:
-* `continue` [line-specification] \(or `c`): resume program execution, at the
+* `continue [line-specification]` \(or `c`): resume program execution, at the
address where your script last stopped; any breakpoints set at that address are
bypassed. The optional argument line-specification allows you to specify a line
number to set a one-time breakpoint which is deleted when that breakpoint is
reached.
-* `finish` [frame-number] \(or `fin`): execute until the selected stack frame
+* `finish [frame-number]` \(or `fin`): execute until the selected stack frame
returns. If no frame number is given, the application will run until the
currently selected frame returns. The currently selected frame starts out the
most-recent frame or 0 if no frame positioning (e.g up, down or frame) has been
@@ -773,8 +766,8 @@ environment variable. A specific _line_ can also be given.
### Quitting
-To exit the debugger, use the `quit` command (abbreviated `q`), or its alias
-`exit`.
+To exit the debugger, use the `quit` command (abbreviated to `q`). Or, type `q!`
+to bypass the `Really quit? (y/n)` prompt and exit unconditionally.
A simple quit tries to terminate all threads in effect. Therefore your server
will be stopped and you will have to start it again.
@@ -869,8 +862,8 @@ such as Valgrind.
### Valgrind
-[Valgrind](http://valgrind.org/) is a Linux-only application for detecting
-C-based memory leaks and race conditions.
+[Valgrind](http://valgrind.org/) is an application for detecting C-based memory
+leaks and race conditions.
There are Valgrind tools that can automatically detect many memory management
and threading bugs, and profile your programs in detail. For example, if a C
diff --git a/guides/source/development_dependencies_install.md b/guides/source/development_dependencies_install.md
index 3c670a1221..7beb8f72a9 100644
--- a/guides/source/development_dependencies_install.md
+++ b/guides/source/development_dependencies_install.md
@@ -165,7 +165,7 @@ $ bundle exec ruby -Itest path/to/test.rb -n test_name
### Active Record Setup
-The test suite of Active Record attempts to run four times: once for SQLite3, once for each of the two MySQL gems (`mysql` and `mysql2`), and once for PostgreSQL. We are going to see now how to set up the environment for them.
+Active Record's test suite runs three times: once for SQLite3, once for MySQL, and once for PostgreSQL. We are going to see now how to set up the environment for them.
WARNING: If you're working with Active Record code, you _must_ ensure that the tests pass for at least MySQL, PostgreSQL, and SQLite3. Subtle differences between the various adapters have been behind the rejection of many patches that looked OK when tested only against MySQL.
@@ -190,7 +190,7 @@ Follow the instructions given by Homebrew to start these.
In Ubuntu just run:
```bash
-$ sudo apt-get install mysql-server libmysqlclient15-dev
+$ sudo apt-get install mysql-server libmysqlclient-dev
$ sudo apt-get install postgresql postgresql-client postgresql-contrib libpq-dev
```
diff --git a/guides/source/engines.md b/guides/source/engines.md
index 3b1588b75a..8382bde4d3 100644
--- a/guides/source/engines.md
+++ b/guides/source/engines.md
@@ -150,7 +150,7 @@ When you include the engine into an application later on, you will do so with
this line in the Rails application's `Gemfile`:
```ruby
-gem 'blorgh', path: "vendor/engines/blorgh"
+gem 'blorgh', path: 'engines/blorgh'
```
Don't forget to run `bundle install` as usual. By specifying it as a gem within
@@ -239,6 +239,27 @@ NOTE: The `ApplicationController` class inside an engine is named just like a
Rails application in order to make it easier for you to convert your
applications into engines.
+NOTE: Because of the way that Ruby does constant lookup you may run into a situation
+where your engine controller is inheriting from the main application controller and
+not your engine's application controller. Ruby is able to resolve the `ApplicationController` constant, and therefore the autoloading mechanism is not triggered. See the section [When Constants Aren't Missed](autoloading_and_reloading_constants.html#when-constants-aren-t-missed) of the [Autoloading and Reloading Constants](autoloading_and_reloading_constants.html) guide for further details. The best way to prevent this from
+happening is to use `require_dependency` to ensure that the engine's application
+controller is loaded. For example:
+
+``` ruby
+# app/controllers/blorgh/articles_controller.rb:
+require_dependency "blorgh/application_controller"
+
+module Blorgh
+ class ArticlesController < ApplicationController
+ ...
+ end
+end
+```
+
+WARNING: Don't use `require` because it will break the automatic reloading of classes
+in the development environment - using `require_dependency` ensures that classes are
+loaded and unloaded in the correct manner.
+
Lastly, the `app/views` directory contains a `layouts` folder, which contains a
file at `blorgh/application.html.erb`. This file allows you to specify a layout
for the engine. If this engine is to be used as a stand-alone engine, then you
@@ -487,7 +508,7 @@ Turning the model into this:
```ruby
module Blorgh
- class Article < ActiveRecord::Base
+ class Article < ApplicationRecord
has_many :comments
end
end
@@ -639,7 +660,7 @@ However, because you are developing the `blorgh` engine on your local machine,
you will need to specify the `:path` option in your `Gemfile`:
```ruby
-gem 'blorgh', path: "/path/to/blorgh"
+gem 'blorgh', path: 'engines/blorgh'
```
Then run `bundle` to install the gem.
@@ -670,7 +691,7 @@ pre-defined path which may be customizable.
The engine contains migrations for the `blorgh_articles` and `blorgh_comments`
table which need to be created in the application's database so that the
engine's models can query them correctly. To copy these migrations into the
-application use this command:
+application run the following command from the `test/dummy` directory of your Rails engine:
```bash
$ rake blorgh:install:migrations
@@ -843,28 +864,10 @@ above the "Title" output inside `app/views/blorgh/articles/show.html.erb`:
```html+erb
<p>
<b>Author:</b>
- <%= @article.author %>
+ <%= @article.author.name %>
</p>
```
-By outputting `@article.author` using the `<%=` tag, the `to_s` method will be
-called on the object. By default, this will look quite ugly:
-
-```
-#<User:0x00000100ccb3b0>
-```
-
-This is undesirable. It would be much better to have the user's name there. To
-do this, add a `to_s` method to the `User` class within the application:
-
-```ruby
-def to_s
- name
-end
-```
-
-Now instead of the ugly Ruby object output, the author's name will be displayed.
-
#### Using a Controller Provided by the Application
Because Rails controllers generally share code for things like authentication
@@ -1030,9 +1033,9 @@ typical `GET` to a controller in a controller's functional test like this:
```ruby
module Blorgh
- class FooControllerTest < ActionController::TestCase
+ class FooControllerTest < ActionDispatch::IntegrationTest
def test_index
- get :index
+ get foos_url
...
end
end
@@ -1046,13 +1049,13 @@ in your setup code:
```ruby
module Blorgh
- class FooControllerTest < ActionController::TestCase
+ class FooControllerTest < ActionDispatch::IntegrationTest
setup do
@routes = Engine.routes
end
def test_index
- get :index
+ get foos_url
...
end
end
@@ -1126,7 +1129,7 @@ end
```ruby
# Blorgh/app/models/article.rb
-class Article < ActiveRecord::Base
+class Article < ApplicationRecord
has_many :comments
end
```
@@ -1147,7 +1150,7 @@ end
```ruby
# Blorgh/app/models/article.rb
-class Article < ActiveRecord::Base
+class Article < ApplicationRecord
has_many :comments
def summary
"#{title}"
@@ -1168,7 +1171,7 @@ classes at run time allowing you to significantly modularize your code.
```ruby
# MyApp/app/models/blorgh/article.rb
-class Blorgh::Article < ActiveRecord::Base
+class Blorgh::Article < ApplicationRecord
include Blorgh::Concerns::Models::Article
def time_since_created
@@ -1184,7 +1187,7 @@ end
```ruby
# Blorgh/app/models/article.rb
-class Article < ActiveRecord::Base
+class Article < ApplicationRecord
include Blorgh::Concerns::Models::Article
end
```
diff --git a/guides/source/form_helpers.md b/guides/source/form_helpers.md
index 84a8d695cb..2a289dd33a 100644
--- a/guides/source/form_helpers.md
+++ b/guides/source/form_helpers.md
@@ -40,7 +40,9 @@ When called without arguments like this, it creates a `<form>` tag which, when s
</form>
```
-You'll notice that the HTML contains `input` element with type `hidden`. This `input` is important, because the form cannot be successfully submitted without it. The hidden input element has name attribute of `utf8` enforces browsers to properly respect your form's character encoding and is generated for all forms whether their actions are "GET" or "POST". The second input element with name `authenticity_token` is a security feature of Rails called **cross-site request forgery protection**, and form helpers generate it for every non-GET form (provided that this security feature is enabled). You can read more about this in the [Security Guide](security.html#cross-site-request-forgery-csrf).
+You'll notice that the HTML contains an `input` element with type `hidden`. This `input` is important, because the form cannot be successfully submitted without it. The hidden input element with the name `utf8` enforces browsers to properly respect your form's character encoding and is generated for all forms whether their action is "GET" or "POST".
+
+The second input element with the name `authenticity_token` is a security feature of Rails called **cross-site request forgery protection**, and form helpers generate it for every non-GET form (provided that this security feature is enabled). You can read more about this in the [Security Guide](security.html#cross-site-request-forgery-csrf).
### A Generic Search Form
@@ -103,9 +105,9 @@ checkboxes, text fields, and radio buttons. These basic helpers, with names
ending in `_tag` (such as `text_field_tag` and `check_box_tag`), generate just a
single `<input>` element. The first parameter to these is always the name of the
input. When the form is submitted, the name will be passed along with the form
-data, and will make its way to the `params` hash in the controller with the
-value entered by the user for that field. For example, if the form contains `<%=
-text_field_tag(:query) %>`, then you would be able to get the value of this
+data, and will make its way to the `params` in the controller with the
+value entered by the user for that field. For example, if the form contains
+`<%= text_field_tag(:query) %>`, then you would be able to get the value of this
field in the controller with `params[:query]`.
When naming inputs, Rails uses certain conventions that make it possible to submit parameters with non-scalar values such as arrays or hashes, which will also be accessible in `params`. You can read more about them in [chapter 7 of this guide](#understanding-parameter-naming-conventions). For details on the precise usage of these helpers, please refer to the [API documentation](http://api.rubyonrails.org/classes/ActionView/Helpers/FormTagHelper.html).
@@ -212,7 +214,7 @@ month, week, URL, email, number and range inputs are HTML5 controls.
If you require your app to have a consistent experience in older browsers,
you will need an HTML5 polyfill (provided by CSS and/or JavaScript).
There is definitely [no shortage of solutions for this](https://github.com/Modernizr/Modernizr/wiki/HTML5-Cross-Browser-Polyfills), although a popular tool at the moment is
-[Modernizr](http://www.modernizr.com/), which provides a simple way to add functionality based on the presence of
+[Modernizr](https://modernizr.com/), which provides a simple way to add functionality based on the presence of
detected HTML5 features.
TIP: If you're using password input fields (for any purpose), you might want to configure your application to prevent those parameters from being logged. You can learn about this in the [Security Guide](security.html#logging).
@@ -376,7 +378,7 @@ output:
</form>
```
-When parsing POSTed data, Rails will take into account the special `_method` parameter and acts as if the HTTP method was the one specified inside it ("PATCH" in this example).
+When parsing POSTed data, Rails will take into account the special `_method` parameter and act as if the HTTP method was the one specified inside it ("PATCH" in this example).
Making Select Boxes with Ease
-----------------------------
@@ -655,7 +657,7 @@ NOTE: If the user has not selected a file the corresponding parameter will be an
### Dealing with Ajax
-Unlike other forms making an asynchronous file upload form is not as simple as providing `form_for` with `remote: true`. With an Ajax form the serialization is done by JavaScript running inside the browser and since JavaScript cannot read files from your hard drive the file cannot be uploaded. The most common workaround is to use an invisible iframe that serves as the target for the form submission.
+Unlike other forms, making an asynchronous file upload form is not as simple as providing `form_for` with `remote: true`. With an Ajax form the serialization is done by JavaScript running inside the browser and since JavaScript cannot read files from your hard drive the file cannot be uploaded. The most common workaround is to use an invisible iframe that serves as the target for the form submission.
Customizing Form Builders
-------------------------
@@ -711,13 +713,6 @@ action for a Person model, `params[:person]` would usually be a hash of all the
Fundamentally HTML forms don't know about any sort of structured data, all they generate is name-value pairs, where pairs are just plain strings. The arrays and hashes you see in your application are the result of some parameter naming conventions that Rails uses.
-TIP: You may find you can try out examples in this section faster by using the console to directly invoke Rack's parameter parser. For example,
-
-```ruby
-Rack::Utils.parse_query "name=fred&phone=0123456789"
-# => {"name"=>"fred", "phone"=>"0123456789"}
-```
-
### Basic Structures
The two basic structures are arrays and hashes. Hashes mirror the syntax used for accessing the value in `params`. For example, if a form contains:
@@ -885,12 +880,12 @@ Many apps grow beyond simple forms editing a single object. For example, when cr
Active Record provides model level support via the `accepts_nested_attributes_for` method:
```ruby
-class Person < ActiveRecord::Base
+class Person < ApplicationRecord
has_many :addresses
accepts_nested_attributes_for :addresses
end
-class Address < ActiveRecord::Base
+class Address < ApplicationRecord
belongs_to :person
end
```
@@ -978,7 +973,7 @@ private
You can allow users to delete associated objects by passing `allow_destroy: true` to `accepts_nested_attributes_for`
```ruby
-class Person < ActiveRecord::Base
+class Person < ApplicationRecord
has_many :addresses
accepts_nested_attributes_for :addresses, allow_destroy: true
end
@@ -1019,7 +1014,7 @@ end
It is often useful to ignore sets of fields that the user has not filled in. You can control this by passing a `:reject_if` proc to `accepts_nested_attributes_for`. This proc will be called with each hash of attributes submitted by the form. If the proc returns `false` then Active Record will not build an associated object for that hash. The example below only tries to build an address if the `kind` attribute is set.
```ruby
-class Person < ActiveRecord::Base
+class Person < ApplicationRecord
has_many :addresses
accepts_nested_attributes_for :addresses, reject_if: lambda {|attributes| attributes['kind'].blank?}
end
diff --git a/guides/source/getting_started.md b/guides/source/getting_started.md
index d51a27812a..9f38de6247 100644
--- a/guides/source/getting_started.md
+++ b/guides/source/getting_started.md
@@ -37,7 +37,7 @@ curve diving straight into Rails. There are several curated lists of online reso
for learning Ruby:
* [Official Ruby Programming Language website](https://www.ruby-lang.org/en/documentation/)
-* [reSRC's List of Free Programming Books](http://resrc.io/list/10/list-of-free-programming-books/#ruby)
+* [List of Free Programming Books](https://github.com/vhf/free-programming-books/blob/master/free-programming-books.md#ruby)
Be aware that some resources, while still excellent, cover versions of Ruby as old as
1.6, and commonly 1.8, and will not include some syntax that you will see in day-to-day
@@ -72,10 +72,9 @@ The Rails philosophy includes two major guiding principles:
Creating a New Rails Project
----------------------------
-
-The best way to use this guide is to follow each step as it happens, no code or
-step needed to make this example application has been left out, so you can
-literally follow along step by step.
+The best way to read this guide is to follow it step by step. All steps are
+essential to run this example application and no additional code or steps are
+needed.
By following along with this guide, you'll create a Rails project called
`blog`, a (very) simple weblog. Before you can start building the application,
@@ -92,17 +91,17 @@ Open up a command line prompt. On Mac OS X open Terminal.app, on Windows choose
dollar sign `$` should be run in the command line. Verify that you have a
current version of Ruby installed:
+```bash
+$ ruby -v
+ruby 2.2.2p95
+```
+
TIP: A number of tools exist to help you quickly install Ruby and Ruby
on Rails on your system. Windows users can use [Rails Installer](http://railsinstaller.org),
while Mac OS X users can use [Tokaido](https://github.com/tokaido/tokaidoapp).
For more installation methods for most Operating Systems take a look at
[ruby-lang.org](https://www.ruby-lang.org/en/documentation/installation/).
-```bash
-$ ruby -v
-ruby 2.2.2p95
-```
-
Many popular UNIX-like OSes ship with an acceptable version of SQLite3.
On Windows, if you installed Rails through Rails Installer, you
already have SQLite installed. Others can find installation instructions
@@ -175,7 +174,7 @@ of the files and folders that Rails created by default:
|log/|Application log files.|
|public/|The only folder seen by the world as-is. Contains static files and compiled assets.|
|Rakefile|This file locates and loads tasks that can be run from the command line. The task definitions are defined throughout the components of Rails. Rather than changing Rakefile, you should add your own tasks by adding files to the lib/tasks directory of your application.|
-|README.rdoc|This is a brief instruction manual for your application. You should edit this file to tell others what your application does, how to set it up, and so on.|
+|README.md|This is a brief instruction manual for your application. You should edit this file to tell others what your application does, how to set it up, and so on.|
|test/|Unit tests, fixtures, and other test apparatus. These are covered in [Testing Rails Applications](testing.html).|
|tmp/|Temporary files (like cache and pid files).|
|vendor/|A place for all third-party code. In a typical Rails application this includes vendored gems.|
@@ -681,7 +680,7 @@ If you look in the `db/migrate/YYYYMMDDHHMMSS_create_articles.rb` file
(remember, yours will have a slightly different name), here's what you'll find:
```ruby
-class CreateArticles < ActiveRecord::Migration
+class CreateArticles < ActiveRecord::Migration[5.0]
def change
create_table :articles do |t|
t.string :title
@@ -992,21 +991,22 @@ and restart the web server when a change is made.
The model file, `app/models/article.rb` is about as simple as it can get:
```ruby
-class Article < ActiveRecord::Base
+class Article < ApplicationRecord
end
```
There isn't much to this file - but note that the `Article` class inherits from
-`ActiveRecord::Base`. Active Record supplies a great deal of functionality to
-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.
+`ApplicationRecord`. `ApplicationRecord` inherits from `ActiveRecord::Base`
+which supplies a great deal of functionality to 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 validate the data that you send to models.
Open the `app/models/article.rb` file and edit it:
```ruby
-class Article < ActiveRecord::Base
+class Article < ApplicationRecord
validates :title, presence: true,
length: { minimum: 5 }
end
@@ -1531,7 +1531,7 @@ This command will generate four files:
First, take a look at `app/models/comment.rb`:
```ruby
-class Comment < ActiveRecord::Base
+class Comment < ApplicationRecord
belongs_to :article
end
```
@@ -1544,7 +1544,7 @@ In addition to the model, Rails has also made a migration to create the
corresponding database table:
```ruby
-class CreateComments < ActiveRecord::Migration
+class CreateComments < ActiveRecord::Migration[5.0]
def change
create_table :comments do |t|
t.string :commenter
@@ -1589,7 +1589,7 @@ association. You've already seen the line of code inside the `Comment` model
(app/models/comment.rb) that makes each comment belong to an Article:
```ruby
-class Comment < ActiveRecord::Base
+class Comment < ApplicationRecord
belongs_to :article
end
```
@@ -1598,7 +1598,7 @@ You'll need to edit `app/models/article.rb` to add the other side of the
association:
```ruby
-class Article < ActiveRecord::Base
+class Article < ApplicationRecord
has_many :comments
validates :title, presence: true,
length: { minimum: 5 }
@@ -1964,7 +1964,7 @@ you to use the `dependent` option of an association to achieve this. Modify the
Article model, `app/models/article.rb`, as follows:
```ruby
-class Article < ActiveRecord::Base
+class Article < ApplicationRecord
has_many :comments, dependent: :destroy
validates :title, presence: true,
length: { minimum: 5 }
diff --git a/guides/source/i18n.md b/guides/source/i18n.md
index 272a0e3623..5bbd4048b9 100644
--- a/guides/source/i18n.md
+++ b/guides/source/i18n.md
@@ -51,7 +51,7 @@ Thus, the Ruby I18n gem is split into two parts:
As a user you should always only access the public methods on the I18n module, but it is useful to know about the capabilities of the backend.
-NOTE: It is possible (or even desirable) to swap the shipped Simple backend with a more powerful one, which would store translation data in a relational database, GetText dictionary, or similar. See section [Using different backends](#using-different-backends) below.
+NOTE: It is possible to swap the shipped Simple backend with a more powerful one, which would store translation data in a relational database, GetText dictionary, or similar. See section [Using different backends](#using-different-backends) below.
### The Public I18n API
@@ -109,7 +109,7 @@ The **translations load path** (`I18n.load_path`) is an array of paths to files
NOTE: The backend lazy-loads these translations when a translation is looked up for the first time. This backend can be swapped with something else even after translations have already been announced.
-The default `application.rb` file has instructions on how to add locales from another directory and how to set a different default locale.
+The default `config/application.rb` file has instructions on how to add locales from another directory and how to set a different default locale.
```ruby
# The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
@@ -117,7 +117,7 @@ The default `application.rb` file has instructions on how to add locales from an
# config.i18n.default_locale = :de
```
-The load path must be specified before any translations are looked up. To change the default locale from an initializer instead of `application.rb`:
+The load path must be specified before any translations are looked up. To change the default locale from an initializer instead of `config/application.rb`:
```ruby
# config/initializers/locale.rb
@@ -249,7 +249,7 @@ end
With this approach you will not get a `Routing Error` when accessing your resources such as `http://localhost:3001/books` without a locale. This is useful for when you want to use the default locale when one is not specified.
-Of course, you need to take special care of the root URL (usually "homepage" or "dashboard") of your application. An URL like `http://localhost:3001/nl` will not work automatically, because the `root to: "books#index"` declaration in your `routes.rb` doesn't take locale into account. (And rightly so: there's only one "root" URL.)
+Of course, you need to take special care of the root URL (usually "homepage" or "dashboard") of your application. A URL like `http://localhost:3001/nl` will not work automatically, because the `root to: "books#index"` declaration in your `routes.rb` doesn't take locale into account. (And rightly so: there's only one "root" URL.)
You would probably need to map URLs like these:
@@ -470,7 +470,7 @@ OK! Now let's add a timestamp to the view, so we can demo the **date/time locali
```erb
# app/views/home/index.html.erb
<h1><%=t :hello_world %></h1>
-<p><%= flash[:notice] %></p
+<p><%= flash[:notice] %></p>
<p><%= l Time.now, format: :short %></p>
```
@@ -805,6 +805,8 @@ en:
Then `User.human_attribute_name("gender.female")` will return "Female".
+NOTE: If you are using a class which includes `ActiveModel` and does not inherit from `ActiveRecord::Base`, replace `activerecord` with `activemodel` in the above key paths.
+
#### Error Message Scopes
Active Record validation error messages can also be translated easily. Active Record gives you a couple of namespaces where you can place your message translations in order to provide different messages and translation for certain models, attributes, and/or validations. It also transparently takes single table inheritance into account.
@@ -814,7 +816,7 @@ This gives you quite powerful means to flexibly adjust your messages to your app
Consider a User model with a validation for the name attribute like this:
```ruby
-class User < ActiveRecord::Base
+class User < ApplicationRecord
validates :name, presence: true
end
```
diff --git a/guides/source/initialization.md b/guides/source/initialization.md
index 43083ebb86..6232ef4c57 100644
--- a/guides/source/initialization.md
+++ b/guides/source/initialization.md
@@ -86,10 +86,9 @@ The `APP_PATH` constant will be used later in `rails/commands`. The `config/boot
`config/boot.rb` contains:
```ruby
-# Set up gems listed in the Gemfile.
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
-require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE'])
+require 'bundler/setup' # Set up gems listed in the Gemfile.
```
In a standard Rails application, there's a `Gemfile` which declares all
@@ -140,7 +139,8 @@ aliases = {
"c" => "console",
"s" => "server",
"db" => "dbconsole",
- "r" => "runner"
+ "r" => "runner",
+ "t" => "test"
}
command = ARGV.shift
@@ -159,19 +159,20 @@ defined here to find the matching command.
### `rails/commands/command_tasks.rb`
-When one types an incorrect rails command, the `run_command` is responsible for
-throwing an error message. If the command is valid, a method of the same name
-is called.
+When one types a valid Rails command, `run_command!` a method of the same name
+is called. If Rails doesn't recognize the command, it tries to run a Rake task
+of the same name.
```ruby
COMMAND_WHITELIST = %w(plugin generate destroy console server dbconsole application runner new version help)
def run_command!(command)
command = parse_command(command)
+
if COMMAND_WHITELIST.include?(command)
send(command)
else
- write_error_message(command)
+ run_rake_task(command)
end
end
```
@@ -529,16 +530,17 @@ This file is responsible for requiring all the individual frameworks of Rails:
require "rails"
%w(
- active_record
- action_controller
- action_view
- action_mailer
- active_job
- rails/test_unit
- sprockets
-).each do |framework|
+ active_record/railtie
+ action_controller/railtie
+ action_view/railtie
+ action_mailer/railtie
+ active_job/railtie
+ action_cable/engine
+ rails/test_unit/railtie
+ sprockets/railtie
+).each do |railtie|
begin
- require "#{framework}/railtie"
+ require "#{railtie}"
rescue LoadError
end
end
diff --git a/guides/source/kindle/layout.html.erb b/guides/source/kindle/layout.html.erb
index f0a286210b..fd8746776b 100644
--- a/guides/source/kindle/layout.html.erb
+++ b/guides/source/kindle/layout.html.erb
@@ -14,12 +14,12 @@
<% if content_for? :header_section %>
<%= yield :header_section %>
- <div class="pagebreak">
+ <div class="pagebreak"></div>
<% end %>
<% if content_for? :index_section %>
<%= yield :index_section %>
- <div class="pagebreak">
+ <div class="pagebreak"></div>
<% end %>
<%= yield.html_safe %>
diff --git a/guides/source/kindle/toc.ncx.erb b/guides/source/kindle/toc.ncx.erb
index 2c6d8e3bdf..5094fea4ca 100644
--- a/guides/source/kindle/toc.ncx.erb
+++ b/guides/source/kindle/toc.ncx.erb
@@ -32,12 +32,12 @@
</navPoint>
<navPoint class="article" id="credits" playOrder="3">
<navLabel><text>Credits</text></navLabel>
- <content src="credits.html">
+ <content src="credits.html"/>
</navPoint>
<navPoint class="article" id="copyright" playOrder="4">
<navLabel><text>Copyright &amp; License</text></navLabel>
- <content src="copyright.html">
- </navPoint>
+ <content src="copyright.html"/>
+ </navPoint>
</navPoint>
<% play_order = 4 %>
@@ -47,7 +47,7 @@
<text><%= section['name'] %></text>
</navLabel>
<content src="<%=section['documents'].first['url'] %>"/>
-
+
<% section['documents'].each_with_index do |document, document_no| %>
<navPoint class="article" id="_<%=section_no+1%>.<%=document_no+1%>" playOrder="<%=play_order +=1 %>">
<navLabel>
diff --git a/guides/source/layouts_and_rendering.md b/guides/source/layouts_and_rendering.md
index 94cd7297e2..9b7f916b9e 100644
--- a/guides/source/layouts_and_rendering.md
+++ b/guides/source/layouts_and_rendering.md
@@ -280,7 +280,7 @@ render body: "raw"
```
TIP: This option should be used only if you don't care about the content type of
-the response. Using `:plain` or `:html` might be more appropriate in most of the
+the response. Using `:plain` or `:html` might be more appropriate most of the
time.
NOTE: Unless overridden, your response returned from this render option will be
@@ -360,7 +360,6 @@ Rails understands both numeric status codes and the corresponding symbols shown
| | 303 | :see_other |
| | 304 | :not_modified |
| | 305 | :use_proxy |
-| | 306 | :reserved |
| | 307 | :temporary_redirect |
| | 308 | :permanent_redirect |
| **Client Error** | 400 | :bad_request |
@@ -376,10 +375,10 @@ Rails understands both numeric status codes and the corresponding symbols shown
| | 410 | :gone |
| | 411 | :length_required |
| | 412 | :precondition_failed |
-| | 413 | :request_entity_too_large |
-| | 414 | :request_uri_too_long |
+| | 413 | :payload_too_large |
+| | 414 | :uri_too_long |
| | 415 | :unsupported_media_type |
-| | 416 | :requested_range_not_satisfiable |
+| | 416 | :range_not_satisfiable |
| | 417 | :expectation_failed |
| | 422 | :unprocessable_entity |
| | 423 | :locked |
@@ -623,10 +622,13 @@ Another way to handle returning responses to an HTTP request is with `redirect_t
redirect_to photos_url
```
-You can use `redirect_to` with any arguments that you could use with `link_to` or `url_for`. There's also a special redirect that sends the user back to the page they just came from:
+You can use `redirect_back` to return the user to the page they just came from.
+This location is pulled from the `HTTP_REFERER` header which is not guaranteed
+to be set by the browser, so you must provide the `fallback_location`
+to use in this case.
```ruby
-redirect_to :back
+redirect_back(fallback_location: root_path)
```
#### Getting a Different Redirect Status Code
@@ -782,7 +784,7 @@ The `javascript_include_tag` helper returns an HTML `script` tag for each source
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)
+A JavaScript file within a Rails application or Rails engine goes in one of three locations: `app/assets`, `lib/assets` or `vendor/assets`. These locations are explained in detail in the [Asset Organization section in the Asset Pipeline Guide](asset_pipeline.html#asset-organization).
You can specify a full path relative to the document root, or a URL, if you prefer. For example, to link to a JavaScript file that is inside a directory called `javascripts` inside of one of `app/assets`, `lib/assets` or `vendor/assets`, you would do this:
@@ -1155,14 +1157,12 @@ To pass a local variable to a partial in only specific cases use the `local_assi
* `_articles.html.erb`
```erb
- <%= content_tag_for :article, article do |article| %>
- <h2><%= article.title %></h2>
+ <h2><%= article.title %></h2>
- <% if local_assigns[:full] %>
- <%= simple_format article.body %>
- <% else %>
- <%= truncate article.body %>
- <% end %>
+ <% if local_assigns[:full] %>
+ <%= simple_format article.body %>
+ <% else %>
+ <%= truncate article.body %>
<% end %>
```
diff --git a/guides/source/maintenance_policy.md b/guides/source/maintenance_policy.md
index 50308f505a..f99b6ebd31 100644
--- a/guides/source/maintenance_policy.md
+++ b/guides/source/maintenance_policy.md
@@ -44,7 +44,7 @@ from.
In special situations, where someone from the Core Team agrees to support more series,
they are included in the list of supported series.
-**Currently included series:** `4.2.Z`, `4.1.Z` (Supported by Rafael França).
+**Currently included series:** `5.0.Z`.
Security Issues
---------------
@@ -59,7 +59,7 @@ be built from 1.2.2, and then added to the end of 1-2-stable. This means that
security releases are easy to upgrade to if you're running the latest version
of Rails.
-**Currently included series:** `4.2.Z`, `4.1.Z`.
+**Currently included series:** `5.0.Z`, `4.2.Z`.
Severe Security Issues
----------------------
@@ -68,7 +68,7 @@ For severe security issues we will provide new versions as above, and also the
last major release series will receive patches and new versions. The
classification of the security issue is judged by the core team.
-**Currently included series:** `4.2.Z`, `4.1.Z`, `3.2.Z`.
+**Currently included series:** `5.0.Z`, `4.2.Z`.
Unsupported Release Series
--------------------------
diff --git a/guides/source/nested_model_forms.md b/guides/source/nested_model_forms.md
index 121cf2b185..71efa4b0d0 100644
--- a/guides/source/nested_model_forms.md
+++ b/guides/source/nested_model_forms.md
@@ -32,7 +32,7 @@ For an ActiveRecord::Base model and association this writer method is commonly d
#### has_one
```ruby
-class Person < ActiveRecord::Base
+class Person < ApplicationRecord
has_one :address
accepts_nested_attributes_for :address
end
@@ -41,7 +41,7 @@ end
#### belongs_to
```ruby
-class Person < ActiveRecord::Base
+class Person < ApplicationRecord
belongs_to :firm
accepts_nested_attributes_for :firm
end
@@ -50,7 +50,7 @@ end
#### has_many / has_and_belongs_to_many
```ruby
-class Person < ActiveRecord::Base
+class Person < ApplicationRecord
has_many :projects
accepts_nested_attributes_for :projects
end
diff --git a/guides/source/plugins.md b/guides/source/plugins.md
index 4e630a39f3..68e54f2414 100644
--- a/guides/source/plugins.md
+++ b/guides/source/plugins.md
@@ -17,7 +17,7 @@ After reading this guide, you will know:
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.
+* Add methods to `ApplicationRecord` 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.
@@ -37,7 +37,7 @@ different rails applications using RubyGems and Bundler if desired.
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. Create your
+to run integration tests using a dummy Rails application. Create your
plugin with the command:
```bash
@@ -54,7 +54,7 @@ Testing Your Newly Generated Plugin
-----------------------------------
You can navigate to the directory that contains the plugin, run the `bundle install` command
- and run the one generated test using the `rake` command.
+ and run the one generated test using the `bin/test` command.
You should see:
@@ -83,13 +83,23 @@ class CoreExtTest < ActiveSupport::TestCase
end
```
-Run `rake` to run the test. This test should fail because we haven't implemented the `to_squawk` method:
+Run `bin/test` to run the test. This test should fail because we haven't implemented the `to_squawk` method:
```bash
- 1) Error:
- CoreExtTest#test_to_squawk_prepends_the_word_squawk:
- NoMethodError: undefined method `to_squawk' for "Hello World":String
- /path/to/yaffle/test/core_ext_test.rb:5:in `test_to_squawk_prepends_the_word_squawk'
+E
+
+Error:
+CoreExtTest#test_to_squawk_prepends_the_word_squawk:
+NoMethodError: undefined method `to_squawk' for "Hello World":String
+
+
+bin/test /path/to/yaffle/test/core_ext_test.rb:4
+
+.
+
+Finished in 0.003358s, 595.6483 runs/s, 297.8242 assertions/s.
+
+2 runs, 1 assertions, 0 failures, 1 errors, 0 skips
```
Great - now you are ready to start development.
@@ -117,7 +127,7 @@ String.class_eval do
end
```
-To test that your method does what it says it does, run the unit tests with `rake` from your plugin directory.
+To test that your method does what it says it does, run the unit tests with `bin/test` from your plugin directory.
```bash
2 runs, 2 assertions, 0 failures, 0 errors, 0 skips
@@ -182,7 +192,6 @@ To start out, write a failing test that shows the behavior you'd like:
require 'test_helper'
class ActsAsYaffleTest < ActiveSupport::TestCase
-
def test_a_hickwalls_yaffle_text_field_should_be_last_squawk
assert_equal "last_squawk", Hickwall.yaffle_text_field
end
@@ -190,24 +199,37 @@ class ActsAsYaffleTest < ActiveSupport::TestCase
def test_a_wickwalls_yaffle_text_field_should_be_last_tweet
assert_equal "last_tweet", Wickwall.yaffle_text_field
end
-
end
```
-When you run `rake`, you should see the following:
+When you run `bin/test`, you should see the following:
```
- 1) Error:
- ActsAsYaffleTest#test_a_hickwalls_yaffle_text_field_should_be_last_squawk:
- NameError: uninitialized constant ActsAsYaffleTest::Hickwall
- /path/to/yaffle/test/acts_as_yaffle_test.rb:6:in `test_a_hickwalls_yaffle_text_field_should_be_last_squawk'
+# Running:
+
+..E
+
+Error:
+ActsAsYaffleTest#test_a_wickwalls_yaffle_text_field_should_be_last_tweet:
+NameError: uninitialized constant ActsAsYaffleTest::Wickwall
- 2) Error:
- ActsAsYaffleTest#test_a_wickwalls_yaffle_text_field_should_be_last_tweet:
- NameError: uninitialized constant ActsAsYaffleTest::Wickwall
- /path/to/yaffle/test/acts_as_yaffle_test.rb:10:in `test_a_wickwalls_yaffle_text_field_should_be_last_tweet'
- 4 runs, 2 assertions, 0 failures, 2 errors, 0 skips
+bin/test /path/to/yaffle/test/acts_as_yaffle_test.rb:8
+
+E
+
+Error:
+ActsAsYaffleTest#test_a_hickwalls_yaffle_text_field_should_be_last_squawk:
+NameError: uninitialized constant ActsAsYaffleTest::Hickwall
+
+
+bin/test /path/to/yaffle/test/acts_as_yaffle_test.rb:4
+
+
+
+Finished in 0.004812s, 831.2949 runs/s, 415.6475 assertions/s.
+
+4 runs, 2 assertions, 0 failures, 2 errors, 0 skips
```
This tells us that we don't have the necessary models (Hickwall and Wickwall) that we are trying to test.
@@ -234,22 +256,22 @@ like yaffles.
```ruby
# test/dummy/app/models/hickwall.rb
-class Hickwall < ActiveRecord::Base
+class Hickwall < ApplicationRecord
acts_as_yaffle
end
# test/dummy/app/models/wickwall.rb
-class Wickwall < ActiveRecord::Base
+class Wickwall < ApplicationRecord
acts_as_yaffle yaffle_text_field: :last_tweet
end
-
```
We will also add code to define the `acts_as_yaffle` method.
```ruby
# yaffle/lib/yaffle/acts_as_yaffle.rb
+
module Yaffle
module ActsAsYaffle
extend ActiveSupport::Concern
@@ -265,26 +287,43 @@ module Yaffle
end
end
-ActiveRecord::Base.include(Yaffle::ActsAsYaffle)
+# test/dummy/app/models/application_record.rb
+
+class ApplicationRecord < ActiveRecord::Base
+ include Yaffle::ActsAsYaffle
+
+ self.abstract_class = true
+end
```
-You can then return to the root directory (`cd ../..`) of your plugin and rerun the tests using `rake`.
+You can then return to the root directory (`cd ../..`) of your plugin and rerun the tests using `bin/test`.
```
- 1) Error:
- ActsAsYaffleTest#test_a_hickwalls_yaffle_text_field_should_be_last_squawk:
- NoMethodError: undefined method `yaffle_text_field' for #<Class:0x007fd105e3b218>
- activerecord (4.1.5) lib/active_record/dynamic_matchers.rb:26:in `method_missing'
- /path/to/yaffle/test/acts_as_yaffle_test.rb:6:in `test_a_hickwalls_yaffle_text_field_should_be_last_squawk'
+# Running:
+
+.E
+
+Error:
+ActsAsYaffleTest#test_a_hickwalls_yaffle_text_field_should_be_last_squawk:
+NoMethodError: undefined method `yaffle_text_field' for #<Class:0x0055974ebbe9d8>
+
+
+bin/test /path/to/yaffle/test/acts_as_yaffle_test.rb:4
+
+E
+
+Error:
+ActsAsYaffleTest#test_a_wickwalls_yaffle_text_field_should_be_last_tweet:
+NoMethodError: undefined method `yaffle_text_field' for #<Class:0x0055974eb8cfc8>
+
- 2) Error:
- ActsAsYaffleTest#test_a_wickwalls_yaffle_text_field_should_be_last_tweet:
- NoMethodError: undefined method `yaffle_text_field' for #<Class:0x007fd105e409c0>
- activerecord (4.1.5) lib/active_record/dynamic_matchers.rb:26:in `method_missing'
- /path/to/yaffle/test/acts_as_yaffle_test.rb:10:in `test_a_wickwalls_yaffle_text_field_should_be_last_tweet'
+bin/test /path/to/yaffle/test/acts_as_yaffle_test.rb:8
- 4 runs, 2 assertions, 0 failures, 2 errors, 0 skips
+.
+Finished in 0.008263s, 484.0999 runs/s, 242.0500 assertions/s.
+
+4 runs, 2 assertions, 0 failures, 2 errors, 0 skips
```
Getting closer... Now we will implement the code of the `acts_as_yaffle` method to make the tests pass.
@@ -294,7 +333,7 @@ Getting closer... Now we will implement the code of the `acts_as_yaffle` method
module Yaffle
module ActsAsYaffle
- extend ActiveSupport::Concern
+ extend ActiveSupport::Concern
included do
end
@@ -308,10 +347,16 @@ module Yaffle
end
end
-ActiveRecord::Base.include(Yaffle::ActsAsYaffle)
+# test/dummy/app/models/application_record.rb
+
+class ApplicationRecord < ActiveRecord::Base
+ include Yaffle::ActsAsYaffle
+
+ self.abstract_class = true
+end
```
-When you run `rake`, you should see the tests all pass:
+When you run `bin/test`, you should see the tests all pass:
```bash
4 runs, 4 assertions, 0 failures, 0 errors, 0 skips
@@ -329,7 +374,6 @@ To start out, write a failing test that shows the behavior you'd like:
require 'test_helper'
class ActsAsYaffleTest < ActiveSupport::TestCase
-
def test_a_hickwalls_yaffle_text_field_should_be_last_squawk
assert_equal "last_squawk", Hickwall.yaffle_text_field
end
@@ -382,10 +426,16 @@ module Yaffle
end
end
-ActiveRecord::Base.include(Yaffle::ActsAsYaffle)
+# test/dummy/app/models/application_record.rb
+
+class ApplicationRecord < ActiveRecord::Base
+ include Yaffle::ActsAsYaffle
+
+ self.abstract_class = true
+end
```
-Run `rake` one final time and you should see:
+Run `bin/test` one final time and you should see:
```
6 runs, 6 assertions, 0 failures, 0 errors, 0 skips
@@ -443,4 +493,3 @@ $ bundle exec rake rdoc
* [Developing a RubyGem using Bundler](https://github.com/radar/guides/blob/master/gem-development.md)
* [Using .gemspecs as Intended](http://yehudakatz.com/2010/04/02/using-gemspecs-as-intended/)
* [Gemspec Reference](http://guides.rubygems.org/specification-reference/)
-* [GemPlugins: A Brief Introduction to the Future of Rails Plugins](http://www.intridea.com/blog/2008/6/11/gemplugins-a-brief-introduction-to-the-future-of-rails-plugins)
diff --git a/guides/source/rails_application_templates.md b/guides/source/rails_application_templates.md
index b7364536c3..edd54826cf 100644
--- a/guides/source/rails_application_templates.md
+++ b/guides/source/rails_application_templates.md
@@ -78,7 +78,7 @@ gem_group :development, :test do
end
```
-### add_source(source, options = {})
+### add_source(source, options={}, &block)
Adds the given source to the generated application's `Gemfile`.
@@ -88,6 +88,14 @@ For example, if you need to source a gem from `"http://code.whytheluckystiff.net
add_source "http://code.whytheluckystiff.net"
```
+If block is given, gem entries in block are wrapped into the source group.
+
+```ruby
+add_source "http://gems.github.com/" do
+ gem "rspec-rails"
+end
+```
+
### environment/application(data=nil, options={}, &block)
Adds a line inside the `Application` class for `config/application.rb`.
diff --git a/guides/source/rails_on_rack.md b/guides/source/rails_on_rack.md
index 1e2fe94010..273fbc08e2 100644
--- a/guides/source/rails_on_rack.md
+++ b/guides/source/rails_on_rack.md
@@ -121,7 +121,6 @@ use ActiveRecord::QueryCache
use ActionDispatch::Cookies
use ActionDispatch::Session::CookieStore
use ActionDispatch::Flash
-use ActionDispatch::ParamsParser
use Rack::Head
use Rack::ConditionalGet
use Rack::ETag
@@ -172,7 +171,7 @@ Add the following lines to your application configuration:
```ruby
# config/application.rb
-config.middleware.delete "Rack::Lock"
+config.middleware.delete Rack::Lock
```
And now if you inspect the middleware stack, you'll find that `Rack::Lock` is
@@ -192,16 +191,16 @@ If you want to remove session related middleware, do the following:
```ruby
# config/application.rb
-config.middleware.delete "ActionDispatch::Cookies"
-config.middleware.delete "ActionDispatch::Session::CookieStore"
-config.middleware.delete "ActionDispatch::Flash"
+config.middleware.delete ActionDispatch::Cookies
+config.middleware.delete ActionDispatch::Session::CookieStore
+config.middleware.delete ActionDispatch::Flash
```
And to remove browser related middleware,
```ruby
# config/application.rb
-config.middleware.delete "Rack::MethodOverride"
+config.middleware.delete Rack::MethodOverride
```
### Internal Middleware Stack
@@ -214,7 +213,7 @@ Much of Action Controller's functionality is implemented as Middlewares. The fol
**`ActionDispatch::Static`**
-* Used to serve static files. Disabled if `config.serve_static_files` is `false`.
+* Used to serve static files from the public directory. Disabled if `config.public_file_server.enabled` is `false`.
**`Rack::Lock`**
@@ -284,10 +283,6 @@ Much of Action Controller's functionality is implemented as Middlewares. The fol
* Sets up the flash keys. Only available if `config.action_controller.session_store` is set to a value.
-**`ActionDispatch::ParamsParser`**
-
-* Parses out parameters from the request into `params`.
-
**`Rack::Head`**
* Converts HEAD requests to `GET` requests and serves them as so.
diff --git a/guides/source/routing.md b/guides/source/routing.md
index 732932b26e..9401132500 100644
--- a/guides/source/routing.md
+++ b/guides/source/routing.md
@@ -7,7 +7,7 @@ This guide covers the user-facing features of Rails routing.
After reading this guide, you will know:
-* How to interpret the code in `routes.rb`.
+* How to interpret the code in `config/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.
@@ -79,12 +79,12 @@ it asks the router to map it to a controller action. If the first matching route
resources :photos
```
-Rails would dispatch that request to the `destroy` method on the `photos` controller with `{ id: '17' }` in `params`.
+Rails would dispatch that request to the `destroy` action on the `photos` controller with `{ id: '17' }` in `params`.
### 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 a specific CRUD
+In Rails, a resourceful route provides a mapping between HTTP verbs and URLs to
+controller actions. By convention, each action also maps to a specific CRUD
operation in a database. A single entry in the routing file, such as:
```ruby
@@ -142,10 +142,10 @@ Sometimes, you have a resource that clients always look up without referencing a
get 'profile', to: 'users#show'
```
-Passing a `String` to `get` will expect a `controller#action` format, while passing a `Symbol` will map directly to an action:
+Passing a `String` to `get` will expect a `controller#action` format, while passing a `Symbol` will map directly to an action but you must also specify the `controller:` to use:
```ruby
-get 'profile', to: :show
+get 'profile', to: :show, controller: 'users'
```
This resourceful route:
@@ -252,11 +252,11 @@ TIP: _If you need to use a different controller namespace inside a `namespace` b
It's common to have resources that are logically children of other resources. For example, suppose your application includes these models:
```ruby
-class Magazine < ActiveRecord::Base
+class Magazine < ApplicationRecord
has_many :ads
end
-class Ad < ActiveRecord::Base
+class Ad < ApplicationRecord
belongs_to :magazine
end
```
@@ -392,7 +392,7 @@ The comments resource here will have the following routes generated for it:
### Routing concerns
-Routing Concerns allows you to declare common routes that can be reused inside other resources and routes. To define a concern:
+Routing concerns allow you to declare common routes that can be reused inside other resources and routes. To define a concern:
```ruby
concern :commentable do
@@ -1095,12 +1095,12 @@ edit_videos GET /videos/:identifier/edit(.:format) videos#edit
Video.find_by(identifier: params[:identifier])
```
-You can override `ActiveRecord::Base#to_param` of a related
-model to constructe an URL.
+You can override `ActiveRecord::Base#to_param` of a related model to construct
+a URL:
```ruby
-class Video < ActiveRecord::Base
- def to_param # overridden
+class Video < ApplicationRecord
+ def to_param
identifier
end
end
@@ -1118,7 +1118,7 @@ Rails offers facilities for inspecting and testing your 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.
-Both methods will list all of your routes, in the same order that they appear in `routes.rb`. For each route, you'll see:
+Both methods will list all of your routes, in the same order that they appear in `config/routes.rb`. For each route, you'll see:
* The route name (if any)
* The HTTP verb used (if the route doesn't respond to all verbs)
diff --git a/guides/source/security.md b/guides/source/security.md
index 485b108d12..1d0e87d831 100644
--- a/guides/source/security.md
+++ b/guides/source/security.md
@@ -93,9 +93,16 @@ Rails 2 introduced a new default session storage, CookieStore. CookieStore saves
* Cookies imply a strict size limit of 4kB. This is fine as you should not store large amounts of data in a session anyway, as described before. _Storing the current user's database id in a session is usually ok_.
-* The client can see everything you store in a session, because it is stored in clear-text (actually Base64-encoded, so not encrypted). So, of course, _you don't want to store any secrets here_. To prevent session hash tampering, a digest is calculated from the session with a server-side secret and inserted into the end of the cookie.
+* The client can see everything you store in a session, because it is stored in clear-text (actually Base64-encoded, so not encrypted). So, of course, _you don't want to store any secrets here_. To prevent session hash tampering, a digest is calculated from the session with a server-side secret (`secrets.secret_token`) and inserted into the end of the cookie.
-That means the security of this storage depends on this secret (and on the digest algorithm, which defaults to SHA1, for compatibility). So _don't use a trivial secret, i.e. a word from a dictionary, or one which is shorter than 30 characters_.
+However, since Rails 4, the default store is EncryptedCookieStore. With
+EncryptedCookieStore the session is encrypted before being stored in a cookie.
+This prevents the user from accessing and tampering the content of the cookie.
+Thus the session becomes a more secure place to store data. The encryption is
+done using a server-side secret key `secrets.secret_key_base` stored in
+`config/secrets.yml`.
+
+That means the security of this storage depends on this secret (and on the digest algorithm, which defaults to SHA1, for compatibility). So _don't use a trivial secret, i.e. a word from a dictionary, or one which is shorter than 30 characters, use `rake secret` instead_.
`secrets.secret_key_base` is used for specifying a key which allows sessions for the application to be verified against a known secure key to prevent tampering. Applications get `secrets.secret_key_base` initialized to a random key present in `config/secrets.yml`, e.g.:
@@ -164,7 +171,7 @@ NOTE: _Sessions that never expire extend the time-frame for attacks such as cros
One possibility is to set the expiry time-stamp of the cookie with the session id. However the client can edit cookies that are stored in the web browser so expiring sessions on the server is safer. Here is an example of how to _expire sessions in a database table_. Call `Session.sweep("20 minutes")` to expire sessions that were used longer than 20 minutes ago.
```ruby
-class Session < ActiveRecord::Base
+class Session < ApplicationRecord
def self.sweep(time = 1.hour)
if time.is_a?(String)
time = time.split.inject { |count, unit| count.to_i.send(unit) }
@@ -189,13 +196,12 @@ This attack method works by including malicious code or a link in a page that ac
![](images/csrf.png)
-In the [session chapter](#sessions) you have learned that most Rails applications use cookie-based sessions. Either they store the session id in the cookie and have a server-side session hash, or the entire session hash is on the client-side. In either case the browser will automatically send along the cookie on every request to a domain, if it can find a cookie for that domain. The controversial point is, that it will also send the cookie, if the request comes from a site of a different domain. Let's start with an example:
+In the [session chapter](#sessions) you have learned that most Rails applications use cookie-based sessions. Either they store the session id in the cookie and have a server-side session hash, or the entire session hash is on the client-side. In either case the browser will automatically send along the cookie on every request to a domain, if it can find a cookie for that domain. The controversial point is that if the request comes from a site of a different domain, it will also send the cookie. Let's start with an example:
-* Bob browses a message board and views a post from a hacker where there is a crafted HTML image element. The element references a command in Bob's project management application, rather than an image file.
-* `<img src="http://www.webapp.com/project/1/destroy">`
-* Bob's session at www.webapp.com is still alive, because he didn't log out a few minutes ago.
-* By viewing the post, the browser finds an image tag. It tries to load the suspected image from www.webapp.com. As explained before, it will also send along the cookie with the valid session id.
-* The web application at www.webapp.com verifies the user information in the corresponding session hash and destroys the project with the ID 1. It then returns a result page which is an unexpected result for the browser, so it will not display the image.
+* Bob browses a message board and views a post from a hacker where there is a crafted HTML image element. The element references a command in Bob's project management application, rather than an image file: `<img src="http://www.webapp.com/project/1/destroy">`
+* Bob's session at `www.webapp.com` is still alive, because he didn't log out a few minutes ago.
+* By viewing the post, the browser finds an image tag. It tries to load the suspected image from `www.webapp.com`. As explained before, it will also send along the cookie with the valid session id.
+* The web application at `www.webapp.com` verifies the user information in the corresponding session hash and destroys the project with the ID 1. It then returns a result page which is an unexpected result for the browser, so it will not display the image.
* Bob doesn't notice the attack - but a few days later he finds out that project number one is gone.
It is important to notice that the actual crafted image or link doesn't necessarily have to be situated in the web application's domain, it can be anywhere - in a forum, blog post or email.
@@ -218,9 +224,9 @@ The HTTP protocol basically provides two main types of requests - GET and POST (
* The interaction _changes the state_ of the resource in a way that the user would perceive (e.g., a subscription to a service), or
* The user is _held accountable for the results_ of the interaction.
-If your web application is RESTful, you might be used to additional HTTP verbs, such as PATCH, PUT or DELETE. Most of today's web browsers, however do not support them - only GET and POST. Rails uses a hidden `_method` field to handle this barrier.
+If your web application is RESTful, you might be used to additional HTTP verbs, such as PATCH, PUT or DELETE. Most of today's web browsers, however, do not support them - only GET and POST. Rails uses a hidden `_method` field to handle this barrier.
-_POST requests can be sent automatically, too_. Here is an example for a link which displays www.harmless.com as destination in the browser's status bar. In fact it dynamically creates a new form that sends a POST request.
+_POST requests can be sent automatically, too_. In this example, the link www.harmless.com is shown as the destination in the browser's status bar. But it has actually dynamically created a new form that sends a POST request.
```html
<a href="http://www.harmless.com/" onclick="
@@ -239,7 +245,9 @@ Or the attacker places the code into the onmouseover event handler of an image:
<img src="http://www.harmless.com/img" width="400" height="400" onmouseover="..." />
```
-There are many other possibilities, like using a `<script>` tag to make a cross-site request to a URL with a JSONP or JavaScript response. The response is executable code that the attacker can find a way to run, possibly extracting sensitive data. To protect against this data leakage, we disallow cross-site `<script>` tags. Only Ajax requests may have JavaScript responses since `XMLHttpRequest` is subject to the browser Same-Origin policy - meaning only your site can initiate the request.
+There are many other possibilities, like using a `<script>` tag to make a cross-site request to a URL with a JSONP or JavaScript response. The response is executable code that the attacker can find a way to run, possibly extracting sensitive data. To protect against this data leakage, we must disallow cross-site `<script>` tags. Ajax requests, however, obey the browser's same-origin policy (only your own site is allowed to initiate `XmlHttpRequest`) so we can safely allow them to return JavaScript responses.
+
+Note: We can't distinguish a `<script>` tag's origin—whether it's a tag on your own site or on some other malicious site—so we must block all `<script>` across the board, even if it's actually a safe same-origin script served from your own site. In these cases, explicitly skip CSRF protection on actions that serve JavaScript meant for a `<script>` tag.
To protect against all other forged requests, we introduce a _required security token_ that our site knows but other sites don't know. We include the security token in requests and verify it on the server. This is a one-liner in your application controller, and is the default for newly created rails applications:
@@ -293,7 +301,7 @@ This will redirect the user to the main action if they tried to access a legacy
http://www.example.com/site/legacy?param1=xy&param2=23&host=www.attacker.com
```
-If it is at the end of the URL it will hardly be noticed and redirects the user to the attacker.com host. A simple countermeasure would be to _include only the expected parameters in a legacy action_ (again a whitelist approach, as opposed to removing unexpected parameters). _And if you redirect to an URL, check it with a whitelist or a regular expression_.
+If it is at the end of the URL it will hardly be noticed and redirects the user to the attacker.com host. A simple countermeasure would be to _include only the expected parameters in a legacy action_ (again a whitelist approach, as opposed to removing unexpected parameters). _And if you redirect to a URL, check it with a whitelist or a regular expression_.
#### Self-contained XSS
@@ -373,9 +381,9 @@ Refer to the Injection section for countermeasures against XSS. It is _recommend
**CSRF** Cross-Site Request Forgery (CSRF), also known as Cross-Site Reference Forgery (XSRF), is a gigantic attack method, it allows the attacker to do everything the administrator or Intranet user may do. As you have already seen above how CSRF works, here are a few examples of what attackers can do in the Intranet or admin interface.
-A real-world example is a [router reconfiguration by CSRF](http://www.h-online.com/security/news/item/Symantec-reports-first-active-attack-on-a-DSL-router-735883.html). The attackers sent a malicious e-mail, with CSRF in it, to Mexican users. The e-mail claimed there was an e-card waiting for them, but it also contained an image tag that resulted in a HTTP-GET request to reconfigure the user's router (which is a popular model in Mexico). The request changed the DNS-settings so that requests to a Mexico-based banking site would be mapped to the attacker's site. Everyone who accessed the banking site through that router saw the attacker's fake web site and had their credentials stolen.
+A real-world example is a [router reconfiguration by CSRF](http://www.h-online.com/security/news/item/Symantec-reports-first-active-attack-on-a-DSL-router-735883.html). The attackers sent a malicious e-mail, with CSRF in it, to Mexican users. The e-mail claimed there was an e-card waiting for the user, but it also contained an image tag that resulted in a HTTP-GET request to reconfigure the user's router (which is a popular model in Mexico). The request changed the DNS-settings so that requests to a Mexico-based banking site would be mapped to the attacker's site. Everyone who accessed the banking site through that router saw the attacker's fake web site and had their credentials stolen.
-Another example changed Google Adsense's e-mail address and password by. If the victim was logged into Google Adsense, the administration interface for Google advertisements campaigns, an attacker could change their credentials.

+Another example changed Google Adsense's e-mail address and password. If the victim was logged into Google Adsense, the administration interface for Google advertisement campaigns, an attacker could change the credentials of the victim.

Another popular attack is to spam your web application, your blog or forum to propagate malicious XSS. Of course, the attacker has to know the URL structure, but most Rails URLs are quite straightforward or they will be easy to find out, if it is an open-source application's admin interface. The attacker may even do 1,000 lucky guesses by just including malicious IMG-tags which try every possible combination.
@@ -398,7 +406,7 @@ NOTE: _Almost every web application has to deal with authorization and authentic
There are a number of authentication plug-ins for Rails available. Good ones, such as the popular [devise](https://github.com/plataformatec/devise) and [authlogic](https://github.com/binarylogic/authlogic), store only encrypted passwords, not plain-text passwords. In Rails 3.1 you can use the built-in `has_secure_password` method which has similar features.
-Every new user gets an activation code to activate their account when they get an e-mail with a link in it. After activating the account, the activation_code columns will be set to NULL in the database. If someone requested an URL like these, they would be logged in as the first activated user found in the database (and chances are that this is the administrator):
+Every new user gets an activation code to activate their account when they get an e-mail with a link in it. After activating the account, the activation_code columns will be set to NULL in the database. If someone requested a URL like these, they would be logged in as the first activated user found in the database (and chances are that this is the administrator):
```
http://localhost:3006/user/activate
@@ -754,7 +762,7 @@ s = sanitize(user_input, tags: tags, attributes: %w(href title))
This allows only the given tags and does a good job, even against all kinds of tricks and malformed tags.
-As a second step, _it is good practice to escape all output of the application_, especially when re-displaying user input, which hasn't been input-filtered (as in the search form example earlier on). _Use `escapeHTML()` (or its alias `h()`) method_ to replace the HTML input characters &amp;, &quot;, &lt;, &gt; by their uninterpreted representations in HTML (`&amp;`, `&quot;`, `&lt`;, and `&gt;`). However, it can easily happen that the programmer forgets to use it, so _it is recommended to use the SafeErb gem. SafeErb reminds you to escape strings from external sources.
+As a second step, _it is good practice to escape all output of the application_, especially when re-displaying user input, which hasn't been input-filtered (as in the search form example earlier on). _Use `escapeHTML()` (or its alias `h()`) method_ to replace the HTML input characters &amp;, &quot;, &lt;, and &gt; by their uninterpreted representations in HTML (`&amp;`, `&quot;`, `&lt;`, and `&gt;`). However, it can easily happen that the programmer forgets to use it, so _it is recommended to use the SafeErb gem. SafeErb reminds you to escape strings from external sources.
##### Obfuscation and Encoding Injection
@@ -785,15 +793,13 @@ Another proof-of-concept webmail worm is Nduja, a cross-domain worm for four Ita
In December 2006, 34,000 actual user names and passwords were stolen in a [MySpace phishing attack](http://news.netcraft.com/archives/2006/10/27/myspace_accounts_compromised_by_phishers.html). The idea of the attack was to create a profile page named "login_home_index_html", so the URL looked very convincing. Specially-crafted HTML and CSS was used to hide the genuine MySpace content from the page and instead display its own login form.
-The MySpace Samy worm will be discussed in the CSS Injection section.
-
### CSS Injection
INFO: _CSS Injection is actually JavaScript injection, because some browsers (IE, some versions of Safari and others) allow JavaScript in CSS. Think twice about allowing custom CSS in your web application._
-CSS Injection is explained best by a well-known worm, the [MySpace Samy worm](http://namb.la/popular/tech.html). This worm automatically sent a friend request to Samy (the attacker) simply by visiting his profile. Within several hours he had over 1 million friend requests, but it creates too much traffic on MySpace, so that the site goes offline. The following is a technical explanation of the worm.
+CSS Injection is explained best by the well-known [MySpace Samy worm](http://namb.la/popular/tech.html). This worm automatically sent a friend request to Samy (the attacker) simply by visiting his profile. Within several hours he had over 1 million friend requests, which created so much traffic that MySpace went offline. The following is a technical explanation of that worm.
-MySpace blocks many tags, however it allows CSS. So the worm's author put JavaScript into CSS like this:
+MySpace blocked many tags, but allowed CSS. So the worm's author put JavaScript into CSS like this:
```html
<div style="background:url('javascript:alert(1)')">
@@ -817,7 +823,7 @@ The next problem was MySpace filtering the word "javascript", so the author used
<div id="mycode" expr="alert('hah!')" style="background:url('java↵
script:eval(document.all.mycode.expr)')">
```
-Another problem for the worm's author were CSRF security tokens. Without them he couldn't send a friend request over POST. He got around it by sending a GET to the page right before adding a user and parsing the result for the CSRF token.
+Another problem for the worm's author was the [CSRF security tokens](#cross-site-request-forgery-csrf). Without them he couldn't send a friend request over POST. He got around it by sending a GET to the page right before adding a user and parsing the result for the CSRF token.
In the end, he got a 4 KB worm, which he injected into his profile page.
@@ -1008,18 +1014,12 @@ config.action_dispatch.default_headers.clear
Here is a list of common headers:
-* X-Frame-Options
-_'SAMEORIGIN' in Rails by default_ - allow framing on same domain. Set it to 'DENY' to deny framing at all or 'ALLOWALL' if you want to allow framing for all website.
-* X-XSS-Protection
-_'1; mode=block' in Rails by default_ - use XSS Auditor and block page if XSS attack is detected. Set it to '0;' if you want to switch XSS Auditor off(useful if response contents scripts from request parameters)
-* X-Content-Type-Options
-_'nosniff' in Rails by default_ - stops the browser from guessing the MIME type of a file.
-* X-Content-Security-Policy
-[A powerful mechanism for controlling which sites certain content types can be loaded from](http://w3c.github.io/webappsec/specs/content-security-policy/csp-specification.dev.html)
-* Access-Control-Allow-Origin
-Used to control which sites are allowed to bypass same origin policies and send cross-origin requests.
-* Strict-Transport-Security
-[Used to control if the browser is allowed to only access a site over a secure connection](http://en.wikipedia.org/wiki/HTTP_Strict_Transport_Security)
+* **X-Frame-Options:** _'SAMEORIGIN' in Rails by default_ - allow framing on same domain. Set it to 'DENY' to deny framing at all or 'ALLOWALL' if you want to allow framing for all website.
+* **X-XSS-Protection:** _'1; mode=block' in Rails by default_ - use XSS Auditor and block page if XSS attack is detected. Set it to '0;' if you want to switch XSS Auditor off(useful if response contents scripts from request parameters)
+* **X-Content-Type-Options:** _'nosniff' in Rails by default_ - stops the browser from guessing the MIME type of a file.
+* **X-Content-Security-Policy:** [A powerful mechanism for controlling which sites certain content types can be loaded from](http://w3c.github.io/webappsec/specs/content-security-policy/csp-specification.dev.html)
+* **Access-Control-Allow-Origin:** Used to control which sites are allowed to bypass same origin policies and send cross-origin requests.
+* **Strict-Transport-Security:** [Used to control if the browser is allowed to only access a site over a secure connection](http://en.wikipedia.org/wiki/HTTP_Strict_Transport_Security)
Environmental Security
----------------------
@@ -1046,7 +1046,7 @@ If you want an exception to be raised when some key is blank, use the bang
version:
```ruby
-Rails.application.secrets.some_api_key! # => raises KeyError
+Rails.application.secrets.some_api_key! # => raises KeyError: key not found: :some_api_key
```
Additional Resources
@@ -1057,4 +1057,3 @@ The security landscape shifts and it is important to keep up to date, because mi
* Subscribe to the Rails security [mailing list](http://groups.google.com/group/rubyonrails-security)
* [Keep up to date on the other application layers](http://secunia.com/) (they have a weekly newsletter, too)
* A [good security blog](https://www.owasp.org) including the [Cross-Site scripting Cheat Sheet](https://www.owasp.org/index.php/DOM_based_XSS_Prevention_Cheat_Sheet)
-
diff --git a/guides/source/testing.md b/guides/source/testing.md
index f40e765242..84f80e3c37 100644
--- a/guides/source/testing.md
+++ b/guides/source/testing.md
@@ -25,15 +25,7 @@ Rails tests can also simulate browser requests and thus you can test your applic
Introduction to Testing
-----------------------
-Testing support was woven into the Rails fabric from the beginning. It wasn't an "oh! let's bolt on support for running tests because they're new and cool" epiphany. Just about every Rails application interacts heavily with a database and, as a result, your tests will need a database to interact with as well. To write efficient tests, you'll need to understand how to set up this database and populate it with sample data.
-
-### The Test Environment
-
-By default, every Rails application has three environments: development, test, and production. The database for each one of them is configured in `config/database.yml`.
-
-A dedicated test database allows you to set up and interact with test data in isolation. This way your tests can mangle test data with confidence, without worrying about the data in the development or production databases.
-
-Also, each environment's configuration can be modified similarly. In this case, we can modify our test environment by changing the options found in `config/environments/test.rb`.
+Testing support was woven into the Rails fabric from the beginning. It wasn't an "oh! let's bolt on support for running tests because they're new and cool" epiphany.
### Rails Sets up for Testing from the Word Go
@@ -51,126 +43,23 @@ Fixtures are a way of organizing test data; they reside in the `fixtures` direct
The `test_helper.rb` file holds the default configuration for your tests.
-### The Low-Down on Fixtures
-
-For good tests, you'll need to give some thought to setting up test data.
-In Rails, you can handle this by defining and customizing fixtures.
-You can find comprehensive documentation in the [Fixtures API documentation](http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html).
-
-#### What Are Fixtures?
-
-_Fixtures_ is a fancy word for sample data. Fixtures allow you to populate your testing database with predefined data before your tests run. Fixtures are database independent and written in YAML. There is one file per model.
-
-You'll find fixtures under your `test/fixtures` directory. When you run `rails generate model` to create a new model, Rails automatically creates fixture stubs in this directory.
-
-#### YAML
-
-YAML-formatted fixtures are a human-friendly way to describe your sample data. These types of fixtures have the **.yml** file extension (as in `users.yml`).
-
-Here's a sample YAML fixture file:
-
-```yaml
-# lo & behold! I am a YAML comment!
-david:
- name: David Heinemeier Hansson
- birthday: 1979-10-15
- profession: Systems development
-
-steve:
- name: Steve Ross Kellock
- birthday: 1974-09-27
- profession: guy with keyboard
-```
-
-Each fixture is given a name followed by an indented list of colon-separated key/value pairs. Records are typically separated by a blank line. You can place comments in a fixture file by using the # character in the first column.
-
-If you are working with [associations](/association_basics.html), you can simply
-define a reference node between two different fixtures. Here's an example with
-a `belongs_to`/`has_many` association:
-
-```yaml
-# In fixtures/categories.yml
-about:
- name: About
-
-# In fixtures/articles.yml
-one:
- title: Welcome to Rails!
- body: Hello world!
- category: about
-```
-
-Notice the `category` key of the `one` article found in `fixtures/articles.yml` has a value of `about`. This tells Rails to load the category `about` found in `fixtures/categories.yml`.
-
-NOTE: For associations to reference one another by name, you cannot specify the `id:` attribute on the associated fixtures. Rails will auto assign a primary key to be consistent between runs. For more information on this association behavior please read the [Fixtures API documentation](http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html).
-
-#### ERB'in It Up
-
-ERB allows you to embed Ruby code within templates. The YAML fixture format is pre-processed with ERB when Rails loads fixtures. This allows you to use Ruby to help you generate some sample data. For example, the following code generates a thousand users:
-
-```erb
-<% 1000.times do |n| %>
-user_<%= n %>:
- username: <%= "user#{n}" %>
- email: <%= "user#{n}@example.com" %>
-<% end %>
-```
-#### Fixtures in Action
-
-Rails by default automatically loads all fixtures from the `test/fixtures` directory for your models and controllers test. Loading involves three steps:
-
-1. Remove any existing data from the table corresponding to the fixture
-2. Load the fixture data into the table
-3. Dump the fixture data into a method in case you want to access it directly
-
-TIP: In order to remove existing data from the database, Rails tries to disable referential integrity triggers (like foreign keys and check constraints). If you are getting annoying permission errors on running tests, make sure the database user has privilege to disable these triggers in testing environment. (In PostgreSQL, only superusers can disable all triggers. Read more about PostgreSQL permissions [here](http://blog.endpoint.com/2012/10/postgres-system-triggers-error.html))
-
-#### Fixtures are Active Record objects
-
-Fixtures are instances of Active Record. As mentioned in point #3 above, you can access the object directly because it is automatically available as a method whose scope is local of the test case. For example:
-
-```ruby
-# this will return the User object for the fixture named david
-users(:david)
-
-# this will return the property for david called id
-users(:david).id
-
-# one can also access methods available on the User class
-email(david.partner.email, david.location_tonight)
-```
-
-To get multiple fixtures at once, you can pass in a list of fixture names. For example:
-
-```ruby
-# this will return an array containing the fixtures david and steve
-users(:david, :steve)
-```
-
-### Console Tasks for Running your Tests
-
-Rails comes with a CLI command to run tests.
-Here are some examples of how to use it:
+### The Test Environment
-```bash
-$ bin/rails test # run all tests in the `test` directory
-$ bin/rails test test/controllers # run all tests from specific directory
-$ bin/rails test test/models/post_test.rb # run specific test
-$ bin/rails test test/models/post_test.rb:44 # run specific test and line
-```
+By default, every Rails application has three environments: development, test, and production.
-We will cover each of types Rails tests listed above in this guide.
+Each environment's configuration can be modified similarly. In this case, we can modify our test environment by changing the options found in `config/environments/test.rb`.
-Model Testing
-------------------------
+NOTE: Your tests are run under `RAILS_ENV=test`.
-For this guide we will be using the application we built in the [Getting Started with Rails](getting_started.html) guide.
+### Rails meets Minitest
-If you remember when you used the `rails generate scaffold` command from earlier. We created our first resource among other things it created a test stub in the `test/models` directory:
+If you remember when you used the `rails generate model` command from the
+[Getting Started with Rails](getting_started.html) guide. We created our first
+model among other things it created test stubs in the `test` directory:
```bash
-$ bin/rails generate scaffold article title:string body:text
+$ bin/rails generate model article title:string body:text
...
create app/models/article.rb
create test/models/article_test.rb
@@ -178,14 +67,6 @@ create test/fixtures/articles.yml
...
```
-You can also generate the test stub for a model using the following command:
-
-```bash
-$ bin/rails generate test_unit:model article title:string body:text
-create test/models/article_test.rb
-create test/fixtures/articles.yml
-```
-
The default test stub in `test/models/article_test.rb` looks like this:
```ruby
@@ -250,47 +131,6 @@ An assertion is a line of code that evaluates an object (or expression) for expe
Every test must contain at least one assertion, with no restriction as to how many assertions are allowed. Only when all the assertions are successful will the test pass.
-### Maintaining the test database schema
-
-In order to run your tests, your test database will need to have the current
-structure. The test helper checks whether your test database has any pending
-migrations. If so, it will try to load your `db/schema.rb` or `db/structure.sql`
-into the test database. If migrations are still pending, an error will be
-raised. Usually this indicates that your schema is not fully migrated. Running
-the migrations against the development database (`bin/rake db:migrate`) will
-bring the schema up to date.
-
-NOTE: If existing migrations required modifications, the test database needs to
-be rebuilt. This can be done by executing `bin/rake db:test:prepare`.
-
-### Running Tests
-
-Running a test is as simple as invoking the file containing the test cases through `rails test` command.
-
-```bash
-$ bin/rails test test/models/article_test.rb
-.
-
-Finished tests in 0.009262s, 107.9680 tests/s, 107.9680 assertions/s.
-
-1 tests, 1 assertions, 0 failures, 0 errors, 0 skips
-```
-
-This will run all test methods from the test case.
-
-You can also run a particular test method from the test case by running the test and providing the `test method name`.
-
-```bash
-$ bin/rails test test/models/article_test.rb test_the_truth
-.
-
-Finished tests in 0.009064s, 110.3266 tests/s, 110.3266 assertions/s.
-
-1 tests, 1 assertions, 0 failures, 0 errors, 0 skips
-```
-
-The `.` (dot) above indicates a passing test. When a test fails you see an `F`; when a test throws an error you see an `E` in its place. The last line of the output is the summary.
-
#### Your first failing test
To see how a test failure is reported, you can add a failing test to the `article_test.rb` test case.
@@ -317,7 +157,7 @@ Failed assertion, no message given.
1 tests, 1 assertions, 1 failures, 0 errors, 0 skips
```
-In the output, `F` denotes a failure. You can see the corresponding trace shown under `1)` along with the name of the failing test. The next few lines contain the stack trace followed by a message which mentions the actual value and the expected value by the assertion. The default assertion messages provide just enough information to help pinpoint the error. To make the assertion failure message more readable, every assertion provides an optional message parameter, as shown here:
+In the output, `F` denotes a failure. You can see the corresponding trace shown under `1)` along with the name of the failing test. The next few lines contain the stack trace followed by a message that mentions the actual value and the expected value by the assertion. The default assertion messages provide just enough information to help pinpoint the error. To make the assertion failure message more readable, every assertion provides an optional message parameter, as shown here:
```ruby
test "should not save article without title" do
@@ -337,7 +177,7 @@ Saved the article without a title
Now to get this test to pass we can add a model level validation for the _title_ field.
```ruby
-class Article < ActiveRecord::Base
+class Article < ApplicationRecord
validates :title, presence: true
end
```
@@ -443,8 +283,8 @@ specify to make your test failure messages clearer. It's not required.
| `assert_no_match( regexp, string, [msg] )` | Ensures that a string doesn't match the regular expression.|
| `assert_includes( collection, obj, [msg] )` | Ensures that `obj` is in `collection`.|
| `assert_not_includes( collection, obj, [msg] )` | Ensures that `obj` is not in `collection`.|
-| `assert_in_delta( expecting, actual, [delta], [msg] )` | Ensures that the numbers `expected` and `actual` are within `delta` of each other.|
-| `assert_not_in_delta( expecting, actual, [delta], [msg] )` | Ensures that the numbers `expected` and `actual` are not within `delta` of each other.|
+| `assert_in_delta( expected, actual, [delta], [msg] )` | Ensures that the numbers `expected` and `actual` are within `delta` of each other.|
+| `assert_not_in_delta( expected, actual, [delta], [msg] )` | Ensures that the numbers `expected` and `actual` are not within `delta` of each other.|
| `assert_throws( symbol, [msg] ) { block }` | Ensures that the given block throws the symbol.|
| `assert_raises( exception1, exception2, ... ) { block }` | Ensures that the given block raises one of the given exceptions.|
| `assert_nothing_raised( exception1, exception2, ... ) { block }` | Ensures that the given block doesn't raise one of the given exceptions.|
@@ -464,7 +304,7 @@ specify to make your test failure messages clearer. It's not required.
The above are a subset of assertions that minitest supports. For an exhaustive &
more up-to-date list, please check
[Minitest API documentation](http://docs.seattlerb.org/minitest/), specifically
-[`Minitest::Assertions`](http://docs.seattlerb.org/minitest/Minitest/Assertions.html)
+[`Minitest::Assertions`](http://docs.seattlerb.org/minitest/Minitest/Assertions.html).
Because of the modular nature of the testing framework, it is possible to create your own assertions. In fact, that's exactly what Rails does. It includes some specialized assertions to make your life easier.
@@ -481,16 +321,15 @@ Rails adds some custom assertions of its own to the `minitest` framework:
| `assert_recognizes(expected_options, path, extras={}, message=nil)` | Asserts that the routing of the given path was handled correctly and that the parsed options (given in the expected_options hash) match path. Basically, it asserts that Rails recognizes the route given by expected_options.|
| `assert_generates(expected_path, options, defaults={}, extras = {}, message=nil)` | Asserts that the provided options can be used to generate the provided path. This is the inverse of assert_recognizes. The extras parameter is used to tell the request the names and values of additional request parameters that would be in a query string. The message parameter allows you to specify a custom error message for assertion failures.|
| `assert_response(type, message = nil)` | Asserts that the response comes with a specific status code. You can specify `:success` to indicate 200-299, `:redirect` to indicate 300-399, `:missing` to indicate 404, or `:error` to match the 500-599 range. You can also pass an explicit status number or its symbolic equivalent. For more information, see [full list of status codes](http://rubydoc.info/github/rack/rack/master/Rack/Utils#HTTP_STATUS_CODES-constant) and how their [mapping](http://rubydoc.info/github/rack/rack/master/Rack/Utils#SYMBOL_TO_STATUS_CODE-constant) works.|
-| `assert_redirected_to(options = {}, message=nil)` | Assert that the redirection options passed in match those of the redirect called in the latest action. This match can be partial, such that `assert_redirected_to(controller: "weblog")` will also match the redirection of `redirect_to(controller: "weblog", action: "show")` and so on. You can also pass named routes such as `assert_redirected_to root_path` and Active Record objects such as `assert_redirected_to @article`.|
+| `assert_redirected_to(options = {}, message=nil)` | Asserts that the redirection options passed in match those of the redirect called in the latest action. This match can be partial, such that `assert_redirected_to(controller: "weblog")` will also match the redirection of `redirect_to(controller: "weblog", action: "show")` and so on. You can also pass named routes such as `assert_redirected_to root_path` and Active Record objects such as `assert_redirected_to @article`.|
You'll see the usage of some of these assertions in the next chapter.
-### A Brief Note About Minitest
+### A Brief Note About Test Cases
All the basic assertions such as `assert_equal` defined in `Minitest::Assertions` are also available in the classes we use in our own test cases. In fact, Rails provides the following classes for you to inherit from:
* `ActiveSupport::TestCase`
-* `ActionController::TestCase`
* `ActionMailer::TestCase`
* `ActionView::TestCase`
* `ActionDispatch::IntegrationTest`
@@ -498,7 +337,303 @@ All the basic assertions such as `assert_equal` defined in `Minitest::Assertions
Each of these classes include `Minitest::Assertions`, allowing us to use all of the basic assertions in our tests.
-NOTE: For more information on `Minitest`, refer to [Minitest](http://docs.seattlerb.org/minitest)
+NOTE: For more information on `Minitest`, refer to [its
+documentation](http://docs.seattlerb.org/minitest).
+
+### The Rails Test Runner
+
+We can run all of our tests at once by using the `rails test` command.
+
+Or we can run a single test by passing the `rails test` command the filename containing the test cases.
+
+```bash
+$ bin/rails test test/models/article_test.rb
+.
+
+Finished tests in 0.009262s, 107.9680 tests/s, 107.9680 assertions/s.
+
+1 tests, 1 assertions, 0 failures, 0 errors, 0 skips
+```
+
+This will run all test methods from the test case.
+
+You can also run a particular test method from the test case by providing the
+`-n` or `--name` flag and the test's method name.
+
+```bash
+$ bin/rails test test/models/article_test.rb -n test_the_truth
+.
+
+Finished tests in 0.009064s, 110.3266 tests/s, 110.3266 assertions/s.
+
+1 tests, 1 assertions, 0 failures, 0 errors, 0 skips
+```
+
+You can also run a test at a specific line by providing the line number.
+
+```bash
+$ bin/rails test test/models/post_test.rb:44 # run specific test and line
+```
+
+You can also run an entire directory of tests by providing the path to the directory.
+
+```bash
+$ bin/rails test test/controllers # run all tests from specific directory
+```
+
+
+The Test Database
+-----------------
+
+Just about every Rails application interacts heavily with a database and, as a result, your tests will need a database to interact with as well. To write efficient tests, you'll need to understand how to set up this database and populate it with sample data.
+
+By default, every Rails application has three environments: development, test, and production. The database for each one of them is configured in `config/database.yml`.
+
+A dedicated test database allows you to set up and interact with test data in isolation. This way your tests can mangle test data with confidence, without worrying about the data in the development or production databases.
+
+
+### Maintaining the test database schema
+
+In order to run your tests, your test database will need to have the current
+structure. The test helper checks whether your test database has any pending
+migrations. If so, it will try to load your `db/schema.rb` or `db/structure.sql`
+into the test database. If migrations are still pending, an error will be
+raised. Usually this indicates that your schema is not fully migrated. Running
+the migrations against the development database (`bin/rake db:migrate`) will
+bring the schema up to date.
+
+NOTE: If existing migrations required modifications, the test database needs to
+be rebuilt. This can be done by executing `bin/rake db:test:prepare`.
+
+### The Low-Down on Fixtures
+
+For good tests, you'll need to give some thought to setting up test data.
+In Rails, you can handle this by defining and customizing fixtures.
+You can find comprehensive documentation in the [Fixtures API documentation](http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html).
+
+#### What Are Fixtures?
+
+_Fixtures_ is a fancy word for sample data. Fixtures allow you to populate your testing database with predefined data before your tests run. Fixtures are database independent and written in YAML. There is one file per model.
+
+You'll find fixtures under your `test/fixtures` directory. When you run `rails generate model` to create a new model, Rails automatically creates fixture stubs in this directory.
+
+#### YAML
+
+YAML-formatted fixtures are a human-friendly way to describe your sample data. These types of fixtures have the **.yml** file extension (as in `users.yml`).
+
+Here's a sample YAML fixture file:
+
+```yaml
+# lo & behold! I am a YAML comment!
+david:
+ name: David Heinemeier Hansson
+ birthday: 1979-10-15
+ profession: Systems development
+
+steve:
+ name: Steve Ross Kellock
+ birthday: 1974-09-27
+ profession: guy with keyboard
+```
+
+Each fixture is given a name followed by an indented list of colon-separated key/value pairs. Records are typically separated by a blank line. You can place comments in a fixture file by using the # character in the first column.
+
+If you are working with [associations](/association_basics.html), you can simply
+define a reference node between two different fixtures. Here's an example with
+a `belongs_to`/`has_many` association:
+
+```yaml
+# In fixtures/categories.yml
+about:
+ name: About
+
+# In fixtures/articles.yml
+one:
+ title: Welcome to Rails!
+ body: Hello world!
+ category: about
+```
+
+Notice the `category` key of the `one` article found in `fixtures/articles.yml` has a value of `about`. This tells Rails to load the category `about` found in `fixtures/categories.yml`.
+
+NOTE: For associations to reference one another by name, you cannot specify the `id:` attribute on the associated fixtures. Rails will auto assign a primary key to be consistent between runs. For more information on this association behavior please read the [Fixtures API documentation](http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html).
+
+#### ERB'in It Up
+
+ERB allows you to embed Ruby code within templates. The YAML fixture format is pre-processed with ERB when Rails loads fixtures. This allows you to use Ruby to help you generate some sample data. For example, the following code generates a thousand users:
+
+```erb
+<% 1000.times do |n| %>
+user_<%= n %>:
+ username: <%= "user#{n}" %>
+ email: <%= "user#{n}@example.com" %>
+<% end %>
+```
+
+#### Fixtures in Action
+
+Rails automatically loads all fixtures from the `test/fixtures` directory by
+default. Loading involves three steps:
+
+1. Remove any existing data from the table corresponding to the fixture
+2. Load the fixture data into the table
+3. Dump the fixture data into a method in case you want to access it directly
+
+TIP: In order to remove existing data from the database, Rails tries to disable referential integrity triggers (like foreign keys and check constraints). If you are getting annoying permission errors on running tests, make sure the database user has privilege to disable these triggers in testing environment. (In PostgreSQL, only superusers can disable all triggers. Read more about PostgreSQL permissions [here](http://blog.endpoint.com/2012/10/postgres-system-triggers-error.html)).
+
+#### Fixtures are Active Record objects
+
+Fixtures are instances of Active Record. As mentioned in point #3 above, you can access the object directly because it is automatically available as a method whose scope is local of the test case. For example:
+
+```ruby
+# this will return the User object for the fixture named david
+users(:david)
+
+# this will return the property for david called id
+users(:david).id
+
+# one can also access methods available on the User class
+email(david.partner.email, david.location_tonight)
+```
+
+To get multiple fixtures at once, you can pass in a list of fixture names. For example:
+
+```ruby
+# this will return an array containing the fixtures david and steve
+users(:david, :steve)
+```
+
+
+Model Testing
+-------------
+
+Model tests are used to test the various models of your application.
+
+Rails model tests are stored under the `test/models` directory. Rails provides
+a generator to create a model test skeleton for you.
+
+```bash
+$ bin/rails generate test_unit:model article title:string body:text
+create test/models/article_test.rb
+create test/fixtures/articles.yml
+```
+
+Model tests don't have their own superclass like `ActionMailer::TestCase` instead they inherit from `ActiveSupport::TestCase`.
+
+
+Integration Testing
+-------------------
+
+Integration tests are used to test how various parts of your application interact. They are generally used to test important workflows within your application.
+
+For creating Rails integration tests, we use the 'test/integration' directory for your application. Rails provides a generator to create an integration test skeleton for you.
+
+```bash
+$ bin/rails generate integration_test user_flows
+ exists test/integration/
+ create test/integration/user_flows_test.rb
+```
+
+Here's what a freshly-generated integration test looks like:
+
+```ruby
+require 'test_helper'
+
+class UserFlowsTest < ActionDispatch::IntegrationTest
+ # test "the truth" do
+ # assert true
+ # end
+end
+```
+
+Inheriting from `ActionDispatch::IntegrationTest` comes with some advantages. This makes available some additional helpers to use in your integration tests.
+
+### Helpers Available for Integration Tests
+
+In addition to the standard testing helpers, inheriting `ActionDispatch::IntegrationTest` comes with some additional helpers available when writing integration tests. Let's briefly introduce you to the three categories of helpers you get to choose from.
+
+For dealing with the integration test runner, see [`ActionDispatch::Integration::Runner`](http://api.rubyonrails.org/classes/ActionDispatch/Integration/Runner.html).
+
+When performing requests, you will have [`ActionDispatch::Integration::RequestHelpers`](http://api.rubyonrails.org/classes/ActionDispatch/Integration/RequestHelpers.html) available for your use.
+
+If you'd like to modify the session, or state of your integration test you should look for [`ActionDispatch::Integration::Session`](http://api.rubyonrails.org/classes/ActionDispatch/Integration/Session.html) to help.
+
+### Implementing an integration test
+
+Let's add an integration test to our blog application. We'll start with a basic workflow of creating a new blog article, to verify that everything is working properly.
+
+We'll start by generating our integration test skeleton:
+
+```bash
+$ bin/rails generate integration_test blog_flow
+```
+
+It should have created a test file placeholder for us. With the output of the
+previous command you should see:
+
+```bash
+ invoke test_unit
+ create test/integration/blog_flow_test.rb
+```
+
+Now let's open that file and write our first assertion:
+
+```ruby
+require 'test_helper'
+
+class BlogFlowTest < ActionDispatch::IntegrationTest
+ test "can see the welcome page" do
+ get "/"
+ assert_select "h1", "Welcome#index"
+ end
+end
+```
+
+If you remember from earlier in the "Testing Views" section we covered `assert_select` to query the resulting HTML of a request.
+
+When visit our root path, we should see `welcome/index.html.erb` rendered for the view. So this assertion should pass.
+
+#### Creating articles integration
+
+How about testing our ability to create a new article in our blog and see the resulting article.
+
+```ruby
+test "can create an article" do
+ get "/articles/new"
+ assert_response :success
+
+ post "/articles",
+ params: { article: { title: "can create", body: "article successfully." } }
+ assert_response :redirect
+ follow_redirect!
+ assert_response :success
+ assert_select "p", "Title:\n can create"
+end
+```
+
+Let's break this test down so we can understand it.
+
+We start by calling the `:new` action on our Articles controller. This response should be successful.
+
+After this we make a post request to the `:create` action of our Articles controller:
+
+```ruby
+post "/articles",
+ params: { article: { title: "can create", body: "article successfully." } }
+assert_response :redirect
+follow_redirect!
+```
+
+The two lines following the request are to handle the redirect we setup when creating a new article.
+
+NOTE: Don't forget to call `follow_redirect!` if you plan to make subsequent requests after a redirect is made.
+
+Finally we can assert that our response was successful and our new article is readable on the page.
+
+#### Taking it further
+
+We were able to successfully test a very small workflow for visiting our blog and creating a new article. If we wanted to take this further we could add tests for commenting, removing articles, or editing comments. Integration tests are a great place to experiment with all kinds of use-cases for our applications.
+
Functional Tests for Your Controllers
-------------------------------------
@@ -515,23 +650,40 @@ You should test for things such as:
* was the correct object stored in the response template?
* was the appropriate message displayed to the user in the view?
-Now that we have used Rails scaffold generator for our `Article` resource, it has already created the controller code and tests. You can take look at the file `articles_controller_test.rb` in the `test/controllers` directory.
+The easiest way to see functional tests in action is to generate a controller
+scaffold:
-The following command will generate a controller test case with a filled up
-test for each of the seven default actions.
+```bash
+$ bin/rails generate scaffold_controller article title:string body:text
+...
+create app/controllers/articles_controller.rb
+...
+invoke test_unit
+create test/controllers/articles_controller_test.rb
+...
+```
+
+This will generate the controller code and tests for an `Article` resource.
+You can take look at the file `articles_controller_test.rb` in the `test/controllers` directory.
+
+If you already have a controller and just want to generate the test scaffold code for
+each of the seven default actions, you can use the following command:
```bash
$ bin/rails generate test_unit:scaffold article
+...
+invoke test_unit
create test/controllers/articles_controller_test.rb
+...
```
Let me take you through one such test, `test_should_get_index` from the file `articles_controller_test.rb`.
```ruby
# articles_controller_test.rb
-class ArticlesControllerTest < ActionController::TestCase
+class ArticlesControllerTest < ActionDispatch::IntegrationTest
test "should get index" do
- get :index
+ get '/articles'
assert_response :success
assert_includes @response.body, 'Articles'
end
@@ -544,7 +696,7 @@ and also ensuring that the right response body has been generated.
The `get` method kicks off the web request and populates the results into the response. It accepts 4 arguments:
* The action of the controller you are requesting.
- This can be in the form of a string or a symbol.
+ This can be in the form of a string or a route (i.e. `articles_url`).
* `params`: option with a hash of request parameters to pass into the action
(e.g. query string parameters or article variables).
@@ -564,7 +716,7 @@ get(:show, params: { id: 12 }, session: { user_id: 5 })
Another example: Calling the `:view` action, passing an `id` of 12 as the `params`, this time with no session, but with a flash message.
```ruby
-get(:view, params: { id: 12 }, flash: { message: 'booya!' })
+get(view_url, params: { id: 12 }, flash: { message: 'booya!' })
```
NOTE: If you try running `test_should_create_article` test from `articles_controller_test.rb` it will fail on account of the newly added model level validation and rightly so.
@@ -574,7 +726,7 @@ Let us modify `test_should_create_article` test in `articles_controller_test.rb`
```ruby
test "should create article" do
assert_difference('Article.count') do
- post :create, params: { article: { title: 'Some title' } }
+ post '/article', params: { article: { title: 'Some title' } }
end
assert_redirected_to article_path(Article.last)
@@ -605,20 +757,21 @@ To test AJAX requests, you can specify the `xhr: true` option to `get`, `post`,
```ruby
test "ajax request" do
- get :show, params: { id: articles(:first).id }, xhr: true
+ article = articles(:first)
+ get article_url(article), xhr: true
assert_equal 'hello world', @response.body
assert_equal "text/javascript", @response.content_type
end
```
-### The Four Hashes of the Apocalypse
+### The Three Hashes of the Apocalypse
-After a request has been made and processed, you will have 4 Hash objects ready for use:
+After a request has been made and processed, you will have 3 Hash objects ready for use:
-* `cookies` - Any cookies that are set.
-* `flash` - Any objects living in the flash.
-* `session` - Any object living in session variables.
+* `cookies` - Any cookies that are set
+* `flash` - Any objects living in the flash
+* `session` - Any object living in session variables
As is the case with normal Hash objects, you can access the values by referencing the keys by string. You can also reference them by symbol name. For example:
@@ -646,16 +799,16 @@ can be set directly on the `@request` instance variable:
```ruby
# setting a HTTP Header
@request.headers["Accept"] = "text/plain, text/html"
-get :index # simulate the request with custom header
+get articles_url # simulate the request with custom header
# setting a CGI variable
@request.headers["HTTP_REFERER"] = "http://example.com/home"
-post :create # simulate the request with custom env variable
+post article_url # simulate the request with custom env variable
```
### Testing `flash` notices
-If you remember from earlier one of the Four Hashes of the Apocalypse was `flash`.
+If you remember from earlier one of the Three Hashes of the Apocalypse was `flash`.
We want to add a `flash` message to our blog application whenever someone
successfully creates a new Article.
@@ -665,7 +818,7 @@ Let's start by adding this assertion to our `test_should_create_article` test:
```ruby
test "should create article" do
assert_difference('Article.count') do
- post :create, params: { article: { title: 'Some title' } }
+ post article_url, params: { article: { title: 'Some title' } }
end
assert_redirected_to article_path(Article.last)
@@ -735,7 +888,7 @@ Let's write a test for the `:show` action:
```ruby
test "should show article" do
article = articles(:one)
- get :show, params: { id: article.id }
+ get '/article', params: { id: article.id }
assert_response :success
end
```
@@ -748,7 +901,7 @@ How about deleting an existing Article?
test "should destroy article" do
article = articles(:one)
assert_difference('Article.count', -1) do
- delete :destroy, params: { id: article.id }
+ delete article_url(article)
end
assert_redirected_to articles_path
@@ -760,7 +913,7 @@ We can also add a test for updating an existing Article.
```ruby
test "should update article" do
article = articles(:one)
- patch :update, params: { id: article.id, article: { title: "updated" } }
+ patch '/article', params: { id: article.id, article: { title: "updated" } }
assert_redirected_to article_path(article)
end
```
@@ -772,34 +925,34 @@ Our test should now look something like this, disregard the other tests we're le
```ruby
require 'test_helper'
-class ArticlesControllerTest < ActionController::TestCase
+class ArticlesControllerTest < ActionDispatch::IntegrationTest
# called before every single test
- def setup
+ setup do
@article = articles(:one)
end
# called after every single test
- def teardown
+ teardown do
# when controller is using cache it may be a good idea to reset it afterwards
Rails.cache.clear
end
test "should show article" do
# Reuse the @article instance variable from setup
- get :show, params: { id: @article.id }
+ get article_url(@article)
assert_response :success
end
test "should destroy article" do
assert_difference('Article.count', -1) do
- delete :destroy, params: { id: @article.id }
+ delete article_url(@article)
end
assert_redirected_to articles_path
end
test "should update article" do
- patch :update, params: { id: @article.id, article: { title: "updated" } }
+ patch article_url(@article), params: { article: { title: "updated" } }
assert_redirected_to article_path(@article)
end
end
@@ -821,7 +974,7 @@ module SignInHelper
end
end
-class ActionController::TestCase
+class ActionDispatch::IntegrationTest
include SignInHelper
end
```
@@ -829,13 +982,13 @@ end
```ruby
require 'test_helper'
-class ProfileControllerTest < ActionController::TestCase
+class ProfileControllerTest < ActionDispatch::IntegrationTest
test "should show profile" do
# helper is now reusable from any controller test case
sign_in users(:david)
- get :show
+ get profile_url
assert_response :success
end
end
@@ -844,33 +997,7 @@ end
Testing Routes
--------------
-Like everything else in your Rails application, it is recommended that you test your routes. Below are example tests for the routes of default `show` and `create` action of `Articles` controller above and it should look like:
-
-```ruby
-class ArticleRoutesTest < ActionController::TestCase
- test "should route to article" do
- assert_routing '/articles/1', { controller: "articles", action: "show", id: "1" }
- end
-
- test "should route to create article" do
- assert_routing({ method: 'post', path: '/articles' }, { controller: "articles", action: "create" })
- end
-end
-```
-
-I've added this file here `test/controllers/articles_routes_test.rb` and if we run the test we should see:
-
-```bash
-$ bin/rails test test/controllers/articles_routes_test.rb
-
-# Running:
-
-..
-
-Finished in 0.069381s, 28.8263 runs/s, 86.4790 assertions/s.
-
-2 runs, 6 assertions, 0 failures, 0 errors, 0 skips
-```
+Like everything else in your Rails application, you can test your routes.
For more information on routing assertions available in Rails, see the API documentation for [`ActionDispatch::Assertions::RoutingAssertions`](http://api.rubyonrails.org/classes/ActionDispatch/Assertions/RoutingAssertions.html).
@@ -960,8 +1087,6 @@ have to use a mixin like this:
```ruby
class UserHelperTest < ActionView::TestCase
- include UserHelper
-
test "should return the user name" do
# ...
end
@@ -971,118 +1096,6 @@ end
Moreover, since the test class extends from `ActionView::TestCase`, you have
access to Rails' helper methods such as `link_to` or `pluralize`.
-Integration Testing
--------------------
-
-Integration tests are used to test how various parts of your application interact. They are generally used to test important work flows within your application.
-
-For creating Rails integration tests, we use the 'test/integration' directory for your application. Rails provides a generator to create an integration test skeleton for you.
-
-```bash
-$ bin/rails generate integration_test user_flows
- exists test/integration/
- create test/integration/user_flows_test.rb
-```
-
-Here's what a freshly-generated integration test looks like:
-
-```ruby
-require 'test_helper'
-
-class UserFlowsTest < ActionDispatch::IntegrationTest
- # test "the truth" do
- # assert true
- # end
-end
-```
-
-Inheriting from `ActionDispatch::IntegrationTest` comes with some advantages. This makes available some additional helpers to use in your integration tests.
-
-### Helpers Available for Integration Tests
-
-In addition to the standard testing helpers, inheriting `ActionDispatch::IntegrationTest` comes with some additional helpers available when writing integration tests. Let's briefly introduce you to the three categories of helpers you get to choose from.
-
-For dealing with the integration test runner, see [`ActionDispatch::Integration::Runner`](http://api.rubyonrails.org/classes/ActionDispatch/Integration/Runner.html).
-
-When performing requests, you will have [`ActionDispatch::Integration::RequestHelpers`](http://api.rubyonrails.org/classes/ActionDispatch/Integration/RequestHelpers.html) available for your use.
-
-If you'd like to modify the session, or state of your integration test you should look for [`ActionDispatch::Integration::Session`](http://api.rubyonrails.org/classes/ActionDispatch/Integration/Session.html) to help.
-
-### Implementing an integration test
-
-Let's add an integration test to our blog application. We'll start with a basic workflow of creating a new blog article, to verify that everything is working properly.
-
-We'll start by generating our integration test skeleton:
-
-```bash
-$ bin/rails generate integration_test blog_flow
-```
-
-It should have created a test file placeholder for us, with the output of the previous command you should see:
-
-```bash
- invoke test_unit
- create test/integration/blog_flow_test.rb
-```
-
-Now let's open that file and write our first assertion:
-
-```ruby
-require 'test_helper'
-
-class BlogFlowTest < ActionDispatch::IntegrationTest
- test "can see the welcome page" do
- get "/"
- assert_select "h1", "Welcome#index"
- end
-end
-```
-
-If you remember from earlier in the "Testing Views" section we covered `assert_select` to query the resulting HTML of a request.
-
-When visit our root path, we should see `welcome/index.html.erb` rendered for the view. So this assertion should pass.
-
-#### Creating articles integration
-
-How about testing our ability to create a new article in our blog and see the resulting article.
-
-```ruby
-test "can create an article" do
- get "/articles/new"
- assert_response :success
-
- post "/articles",
- params: { article: { title: "can create", body: "article successfully." } }
- assert_response :redirect
- follow_redirect!
- assert_response :success
- assert_select "p", "Title:\n can create"
-end
-```
-
-Let's break this test down so we can understand it.
-
-We start by calling the `:new` action on our Articles controller. This response should be successful, and we can verify the correct template is rendered including the form partial.
-
-After this we make a post request to the `:create` action of our Articles controller:
-
-```ruby
-post "/articles",
- params: { article: { title: "can create", body: "article successfully." } }
-assert_response :redirect
-follow_redirect!
-```
-
-The two lines following the request are to handle the redirect we setup when creating a new article.
-
-NOTE: Don't forget to call `follow_redirect!` if you plan to make subsequent requests after a redirect is made.
-
-Finally we can assert that our response was successful, template was rendered, and our new article is readable on the page.
-
-#### Taking it further
-
-We were able to successfully test a very small workflow for visiting our blog and creating a new article. If we wanted to take this further we could add tests for commenting, removing articles, or editing comments. Integration tests are a great place to experiment with all kinds of use-cases for our applications.
-
Testing Your Mailers
--------------------
@@ -1121,10 +1134,13 @@ require 'test_helper'
class UserMailerTest < ActionMailer::TestCase
test "invite" do
+ # Create the email and store it for further assertions
+ email = UserMailer.create_invite('me@example.com',
+ 'friend@example.com', Time.now)
+
# Send the email, then test that it got queued
assert_emails 1 do
- email = UserMailer.create_invite('me@example.com',
- 'friend@example.com', Time.now).deliver_now
+ email.deliver_now
end
# Test the body of the sent email contains what we expect it to
@@ -1170,10 +1186,10 @@ Functional testing for mailers involves more than just checking that the email b
```ruby
require 'test_helper'
-class UserControllerTest < ActionController::TestCase
+class UserControllerTest < ActionDispatch::IntegrationTest
test "invite friend" do
assert_difference 'ActionMailer::Base.deliveries.size', +1 do
- post :invite_friend, params: { email: 'friend@example.com' }
+ post invite_friend_url, params: { email: 'friend@example.com' }
end
invite_email = ActionMailer::Base.deliveries.last
@@ -1236,15 +1252,23 @@ class ProductTest < ActiveJob::TestCase
end
```
-Other Testing Approaches
-------------------------
+Testing Time-Dependent Code
+---------------------------
+
+Rails provides inbuilt helper methods that enable you to assert that your time-sensitve code works as expected.
-The built-in `minitest` based testing is not the only way to test Rails applications. Rails developers have come up with a wide variety of other approaches and aids for testing, including:
+Here is an example using the [`travel_to`](http://api.rubyonrails.org/classes/ActiveSupport/Testing/TimeHelpers.html#method-i-travel_to) helper:
+
+```ruby
+# Lets say that a user is eligible for gifting a month after they register.
+user = User.create(name: 'Gaurish', activation_date: Date.new(2004, 10, 24))
+assert_not user.applicable_for_gifting?
+travel_to Date.new(2004, 11, 24) do
+ assert_equal Date.new(2004, 10, 24), user.activation_date # inside the travel_to block `Date.current` is mocked
+ assert user.applicable_for_gifting?
+end
+assert_equal Date.new(2004, 10, 24), user.activation_date # The change was visible only inside the `travel_to` block.
+```
-* [NullDB](http://avdi.org/projects/nulldb/), a way to speed up testing by avoiding database use.
-* [Factory Girl](https://github.com/thoughtbot/factory_girl/tree/master), a replacement for fixtures.
-* [Fixture Builder](https://github.com/rdy/fixture_builder), a tool that compiles Ruby factories into fixtures before a test run.
-* [MiniTest::Spec Rails](https://github.com/metaskills/minitest-spec-rails), use the MiniTest::Spec DSL within your rails tests.
-* [Shoulda](http://www.thoughtbot.com/projects/shoulda), an extension to `test/unit` with additional helpers, macros, and assertions.
-* [RSpec](http://relishapp.com/rspec), a behavior-driven development framework
-* [Capybara](http://jnicklas.github.com/capybara/), Acceptance test framework for web applications
+Please see [`ActiveSupport::TimeHelpers` API Documentation](http://api.rubyonrails.org/classes/ActiveSupport/Testing/TimeHelpers.html)
+for in-depth information about the available time helpers.
diff --git a/guides/source/upgrading_ruby_on_rails.md b/guides/source/upgrading_ruby_on_rails.md
index 743241d7a0..936547a8cc 100644
--- a/guides/source/upgrading_ruby_on_rails.md
+++ b/guides/source/upgrading_ruby_on_rails.md
@@ -53,25 +53,55 @@ Don't forget to review the difference, to see if there were any unexpected chang
Upgrading from Rails 4.2 to Rails 5.0
-------------------------------------
-### Halting callback chains by returning `false`
+### Ruby 2.2.2+
-In Rails 4.2, when a 'before' callback returns `false` in ActiveRecord,
-ActiveModel and ActiveModel::Validations, then the entire callback chain
-is halted. In other words, successive 'before' callbacks are not executed,
-and neither is the action wrapped in callbacks.
+ToDo...
-In Rails 5.0, returning `false` in a callback will not have this side effect
-of halting the callback chain. Instead, callback chains must be explicitly
-halted by calling `throw(:abort)`.
+### Ruby 2.2.2+
-When you upgrade from Rails 4.2 to Rails 5.0, returning `false` in a callback
-will still halt the callback chain, but you will receive a deprecation warning
-about this upcoming change.
+ToDo...
+
+### Active Record models now inherit from ApplicationRecord by default
+
+In Rails 4.2 an Active Record model inherits from `ActiveRecord::Base`. In Rails 5.0,
+all models inherit from `ApplicationRecord`.
+
+`ApplicationRecord` is a new superclass for all app models, analogous to app
+controllers subclassing `ApplicationController` instead of
+`ActionController::Base`. This gives apps a single spot to configure app-wide
+model behavior.
+
+When upgrading from Rails 4.2 to Rails 5.0 you need to create an
+`application_record.rb` file in `app/models/` and add the following content:
+
+```
+class ApplicationRecord < ActiveRecord::Base
+ self.abstract_class = true
+end
+```
+
+### Halting callback chains via `throw(:abort)`
+
+In Rails 4.2, when a 'before' callback returns `false` in Active Record
+and Active Model, then the entire callback chain is halted. In other words,
+successive 'before' callbacks are not executed, and neither is the action wrapped
+in callbacks.
+
+In Rails 5.0, returning `false` in an Active Record or Active Model callback
+will not have this side effect of halting the callback chain. Instead, callback
+chains must be explicitly halted by calling `throw(:abort)`.
+
+When you upgrade from Rails 4.2 to Rails 5.0, returning `false` in those kind of
+callbacks will still halt the callback chain, but you will receive a deprecation
+warning about this upcoming change.
When you are ready, you can opt into the new behavior and remove the deprecation
warning by adding the following configuration to your `config/application.rb`:
- config.active_support.halt_callback_chains_on_return_false = false
+ ActiveSupport.halt_callback_chains_on_return_false = false
+
+Note that this option will not affect Active Support callbacks since they never
+halted the chain when any value was returned.
See [#17227](https://github.com/rails/rails/pull/17227) for more details.
@@ -314,11 +344,11 @@ Upgrading from Rails 4.0 to Rails 4.1
### CSRF protection from remote `<script>` tags
-Or, "whaaat my tests are failing!!!?"
+Or, "whaaat my tests are failing!!!?" or "my `<script>` widget is busted!!"
Cross-site request forgery (CSRF) protection now covers GET requests with
-JavaScript responses, too. This prevents a third-party site from referencing
-your JavaScript URL and attempting to run it to extract sensitive data.
+JavaScript responses, too. This prevents a third-party site from remotely
+referencing your JavaScript with a `<script>` tag to extract sensitive data.
This means that your functional and integration tests that use
@@ -334,8 +364,9 @@ xhr :get, :index, format: :js
to explicitly test an `XmlHttpRequest`.
-If you really mean to load JavaScript from remote `<script>` tags, skip CSRF
-protection on that action.
+Note: Your own `<script>` tags are treated as cross-origin and blocked by
+default, too. If you really mean to load JavaScript from `<script>` tags,
+you must now explicitly skip CSRF protection on those actions.
### Spring
@@ -895,7 +926,7 @@ CatalogProduct < ActiveRecord::Base
end
```
-* Note that the the prefix takes scopes into account as well, so relations between `Catalog::Category` and `Catalog::Product` or `Catalog::Category` and `CatalogProduct` need to be updated similarly.
+* Note that the prefix takes scopes into account as well, so relations between `Catalog::Category` and `Catalog::Product` or `Catalog::Category` and `CatalogProduct` need to be updated similarly.
### Active Resource
@@ -940,7 +971,7 @@ Please read [Pull Request #9978](https://github.com/rails/rails/pull/9978) for d
* Rails 4.0 has removed the XML parameters parser. You will need to add the `actionpack-xml_parser` gem if you require this feature.
-* Rails 4.0 changes the default `layout` lookup set using symbols or procs that return nil. To get the "no layout" behavior, return false instead of nil.
+* Rails 4.0 changes the default `layout` lookup set using symbols or procs that return nil. To get the "no layout" behavior, return false instead of nil.
* Rails 4.0 changes the default memcached client from `memcache-client` to `dalli`. To upgrade, simply add `gem 'dalli'` to your `Gemfile`.
@@ -1086,7 +1117,7 @@ config.active_record.auto_explain_threshold_in_seconds = 0.5
### config/environments/test.rb
-The `mass_assignment_sanitizer` configuration setting should also be be added to `config/environments/test.rb`:
+The `mass_assignment_sanitizer` configuration setting should also be added to `config/environments/test.rb`:
```ruby
# Raise exception on mass assignment protection for Active Record models
@@ -1187,8 +1218,10 @@ You can help test performance with these additions to your test environment:
```ruby
# Configure static asset server for tests with Cache-Control for performance
-config.serve_static_files = true
-config.static_cache_control = 'public, max-age=3600'
+config.public_file_server.enabled = true
+config.public_file_server.headers = {
+ 'Cache-Control' => 'public, max-age=3600'
+}
```
### config/initializers/wrap_parameters.rb
diff --git a/guides/source/working_with_javascript_in_rails.md b/guides/source/working_with_javascript_in_rails.md
index 4c996dd2d0..48fc6bc9c0 100644
--- a/guides/source/working_with_javascript_in_rails.md
+++ b/guides/source/working_with_javascript_in_rails.md
@@ -81,7 +81,7 @@ Awkward, right? We could pull the function definition out of the click handler,
and turn it into CoffeeScript:
```coffeescript
-paintIt = (element, backgroundColor, textColor) ->
+@paintIt = (element, backgroundColor, textColor) ->
element.style.backgroundColor = backgroundColor
if textColor?
element.style.color = textColor
@@ -107,7 +107,7 @@ attribute to our link, and then bind a handler to the click event of every link
that has that attribute:
```coffeescript
-paintIt = (element, backgroundColor, textColor) ->
+@paintIt = (element, backgroundColor, textColor) ->
element.style.backgroundColor = backgroundColor
if textColor?
element.style.color = textColor
@@ -357,7 +357,7 @@ This gem uses Ajax to speed up page rendering in most applications.
Turbolinks attaches a click handler to all `<a>` on the page. If your browser
supports
-[PushState](https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Manipulating_the_browser_history#The_pushState()_method),
+[PushState](https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Manipulating_the_browser_history#The_pushState%28%29_method),
Turbolinks will make an Ajax request for the page, parse the response, and
replace the entire `<body>` of the page with the `<body>` of the response. It
will then use PushState to change the URL to the correct one, preserving