diff options
author | kp <keith.j.payne@gmail.com> | 2016-02-10 17:44:54 +0000 |
---|---|---|
committer | kp <keith.j.payne@gmail.com> | 2016-02-10 17:44:54 +0000 |
commit | ec4ae308a76bd86fb6eaf7fa8ee025af0063ee30 (patch) | |
tree | 741019b3fbf474ff4cdeefdbeb6ff1f598ffcdfc /guides/source | |
parent | 8641de93eb98d4ebdb0db2530c8c79c0c4e2f95e (diff) | |
parent | 688996da7b25080a1a2ef74f5b4789f3e5eb670d (diff) | |
download | rails-ec4ae308a76bd86fb6eaf7fa8ee025af0063ee30.tar.gz rails-ec4ae308a76bd86fb6eaf7fa8ee025af0063ee30.tar.bz2 rails-ec4ae308a76bd86fb6eaf7fa8ee025af0063ee30.zip |
Merge remote-tracking branch 'origin/master' into actioncable_logging
Diffstat (limited to 'guides/source')
-rw-r--r-- | guides/source/5_0_release_notes.md | 6 | ||||
-rw-r--r-- | guides/source/active_job_basics.md | 10 | ||||
-rw-r--r-- | guides/source/active_record_migrations.md | 4 | ||||
-rw-r--r-- | guides/source/active_record_postgresql.md | 2 | ||||
-rw-r--r-- | guides/source/active_record_querying.md | 2 | ||||
-rw-r--r-- | guides/source/api_app.md | 74 | ||||
-rw-r--r-- | guides/source/asset_pipeline.md | 42 | ||||
-rw-r--r-- | guides/source/association_basics.md | 6 | ||||
-rw-r--r-- | guides/source/command_line.md | 6 | ||||
-rw-r--r-- | guides/source/configuring.md | 24 | ||||
-rw-r--r-- | guides/source/contributing_to_ruby_on_rails.md | 10 | ||||
-rw-r--r-- | guides/source/documents.yaml | 4 | ||||
-rw-r--r-- | guides/source/engines.md | 4 | ||||
-rw-r--r-- | guides/source/getting_started.md | 8 | ||||
-rw-r--r-- | guides/source/initialization.md | 2 | ||||
-rw-r--r-- | guides/source/layouts_and_rendering.md | 2 | ||||
-rw-r--r-- | guides/source/rails_on_rack.md | 10 | ||||
-rw-r--r-- | guides/source/routing.md | 17 | ||||
-rw-r--r-- | guides/source/security.md | 8 | ||||
-rw-r--r-- | guides/source/testing.md | 104 | ||||
-rw-r--r-- | guides/source/upgrading_ruby_on_rails.md | 6 | ||||
-rw-r--r-- | guides/source/working_with_javascript_in_rails.md | 8 |
22 files changed, 207 insertions, 152 deletions
diff --git a/guides/source/5_0_release_notes.md b/guides/source/5_0_release_notes.md index 2650384df3..4e8252f85b 100644 --- a/guides/source/5_0_release_notes.md +++ b/guides/source/5_0_release_notes.md @@ -253,6 +253,9 @@ Please refer to the [Changelog][action-pack] for detailed changes. `ActionDispatch::IntegrationTest` instead. ([commit](https://github.com/rails/rails/commit/4414c5d1795e815b102571425974a8b1d46d932d)) +* Rails will only generate "weak", instead of strong ETags. + ([Pull Request](https://github.com/rails/rails/pull/17573)) + Action View ------------- @@ -378,6 +381,9 @@ Please refer to the [Changelog][active-record] for detailed changes. * Removed support for the `protected_attributes` gem. ([commit](https://github.com/rails/rails/commit/f4fbc0301021f13ae05c8e941c8efc4ae351fdf9)) +* Removed support for PostgreSQL versions below 9.1. + ([Pull Request](https://github.com/rails/rails/pull/23434)) + ### Deprecations * Deprecated passing a class as a value in a query. Users should pass strings diff --git a/guides/source/active_job_basics.md b/guides/source/active_job_basics.md index 76c13f0ea9..d8ea1ee079 100644 --- a/guides/source/active_job_basics.md +++ b/guides/source/active_job_basics.md @@ -109,10 +109,12 @@ That's it! Job Execution ------------- -For enqueuing and executing jobs you need to set up a queuing backend, that is to -say you need to decide for a 3rd-party queuing library that Rails should use. -Rails itself does not provide a sophisticated queuing system and just executes the -job immediately if no adapter is set. +For enqueuing and executing jobs in production you need to set up a queuing backend, +that is to say you need to decide for a 3rd-party queuing library that Rails should use. +Rails itself only provides an in-process queuing system, which only keeps the jobs in RAM. +If the process crashes or the machine is reset, then all outstanding jobs are lost with the +default async back-end. This may be fine for smaller apps or non-critical jobs, but most +production apps will need to pick a persistent backend. ### Backends diff --git a/guides/source/active_record_migrations.md b/guides/source/active_record_migrations.md index 83f4b951ee..bd7dbd0f11 100644 --- a/guides/source/active_record_migrations.md +++ b/guides/source/active_record_migrations.md @@ -883,7 +883,7 @@ 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 +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 `rails db:migrate`. You must rollback the migration (for example with `bin/rails db:rollback`), edit your migration and then run @@ -933,7 +933,7 @@ There are two ways to dump the schema. This is set in `config/application.rb` by the `config.active_record.schema_format` setting, which may be either `:sql` or `:ruby`. -If `:ruby` is selected then the schema is stored in `db/schema.rb`. If you look +If `:ruby` is selected, then the schema is stored in `db/schema.rb`. If you look at this file you'll find that it looks an awful lot like one very big migration: diff --git a/guides/source/active_record_postgresql.md b/guides/source/active_record_postgresql.md index 68c6a77882..5eb19f5214 100644 --- a/guides/source/active_record_postgresql.md +++ b/guides/source/active_record_postgresql.md @@ -14,7 +14,7 @@ After reading this guide, you will know: -------------------------------------------------------------------------------- -In order to use the PostgreSQL adapter you need to have at least version 8.2 +In order to use the PostgreSQL adapter you need to have at least version 9.1 installed. Older versions are not supported. To get started with PostgreSQL have a look at the diff --git a/guides/source/active_record_querying.md b/guides/source/active_record_querying.md index 784be91845..63658e7c8b 100644 --- a/guides/source/active_record_querying.md +++ b/guides/source/active_record_querying.md @@ -1085,6 +1085,8 @@ SELECT categories.* FROM categories INNER JOIN tags ON tags.article_id = articles.id ``` +Or, in English: "return all categories that have articles, where those articles have a comment made by a guest, and where those articles also have a tag." + #### 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) provide a special syntax for specifying conditions for the joined tables: diff --git a/guides/source/api_app.md b/guides/source/api_app.md index 86baa9ee84..563214896a 100644 --- a/guides/source/api_app.md +++ b/guides/source/api_app.md @@ -8,7 +8,7 @@ In this guide you will learn: * What Rails provides for API-only applications * How to configure Rails to start without any browser features -* How to decide which middlewares you will want to include +* How to decide which middleware you will want to include * How to decide which modules to use in your controller -------------------------------------------------------------------------------- @@ -44,11 +44,11 @@ using Rails is: "isn't using Rails to spit out some JSON overkill? Shouldn't I just use something like Sinatra?". For very simple APIs, this may be true. However, even in very HTML-heavy -applications, most of an application's logic is actually outside of the view +applications, most of an application's logic lives outside of the view layer. The reason most people use Rails is that it provides a set of defaults that -allows us to get up and running quickly without having to make a lot of trivial +allows developers to get up and running quickly, without having to make a lot of trivial decisions. Let's take a look at some of the things that Rails provides out of the box that are @@ -86,7 +86,7 @@ Handled at the middleware layer: and return just the headers on the way out. This makes `HEAD` work reliably in all Rails APIs. -While you could obviously build these up in terms of existing Rack middlewares, +While you could obviously build these up in terms of existing Rack middleware, this list demonstrates that the default Rails middleware stack provides a lot of value, even if you're "just generating JSON". @@ -97,7 +97,7 @@ Handled at the Action Pack layer: means not having to spend time thinking about how to model your API in terms of HTTP. - URL Generation: The flip side of routing is URL generation. A good API based - on HTTP includes URLs (see [the GitHub gist API](http://developer.github.com/v3/gists/) + on HTTP includes URLs (see [the GitHub Gist API](http://developer.github.com/v3/gists/) for an example). - Header and Redirection Responses: `head :no_content` and `redirect_to user_url(current_user)` come in handy. Sure, you could manually @@ -126,7 +126,7 @@ when configuring Active Record. **The short version is**: you may not have thought about which parts of Rails are still applicable even if you remove the view layer, but the answer turns out -to be "most of it". +to be most of it. The Basic Configuration ----------------------- @@ -135,6 +135,8 @@ If you're building a Rails application that will be an API server first and foremost, you can start with a more limited subset of Rails and add in features as needed. +### Creating a new application + You can generate a new api Rails app: ```bash @@ -143,16 +145,18 @@ $ rails new my_api --api This will do three main things for you: -- Configure your application to start with a more limited set of middlewares +- Configure your application to start with a more limited set of middleware than normal. Specifically, it will not include any middleware primarily useful for browser applications (like cookies support) by default. - Make `ApplicationController` inherit from `ActionController::API` instead of - `ActionController::Base`. As with middlewares, this will leave out any Action + `ActionController::Base`. As with middleware, this will leave out any Action Controller modules that provide functionalities primarily used by browser applications. - Configure the generators to skip generating views, helpers and assets when you generate a new resource. +### Changing an existing application + If you want to take an existing application and make it an API one, read the following steps. @@ -185,18 +189,18 @@ class ApplicationController < ActionController::API end ``` -Choosing Middlewares +Choosing Middleware -------------------- -An API application comes with the following middlewares by default: +An API application comes with the following middleware by default: - `Rack::Sendfile` - `ActionDispatch::Static` -- `Rack::Lock` +- `ActionDispatch::LoadInterlock` - `ActiveSupport::Cache::Strategy::LocalCache::Middleware` +- `Rack::Runtime` - `ActionDispatch::RequestId` - `Rails::Rack::Logger` -- `Rack::Runtime` - `ActionDispatch::ShowExceptions` - `ActionDispatch::DebugExceptions` - `ActionDispatch::RemoteIp` @@ -206,14 +210,14 @@ An API application comes with the following middlewares by default: - `Rack::ConditionalGet` - `Rack::ETag` -See the [internal middlewares](rails_on_rack.html#internal-middleware-stack) +See the [internal middleware](rails_on_rack.html#internal-middleware-stack) section of the Rack guide for further information on them. -Other plugins, including Active Record, may add additional middlewares. In -general, these middlewares are agnostic to the type of application you are +Other plugins, including Active Record, may add additional middleware. In +general, these middleware are agnostic to the type of application you are building, and make sense in an API-only Rails application. -You can get a list of all middlewares in your application via: +You can get a list of all middleware in your application via: ```bash $ rails middleware @@ -262,9 +266,6 @@ subsequent inbound requests for the same URL. Think of it as page caching using HTTP semantics. -NOTE: This middleware is always outside of the `Rack::Lock` mutex, even in -single-threaded applications. - ### Using Rack::Sendfile When you use the `send_file` method inside a Rails controller, it sets the @@ -296,9 +297,6 @@ config.action_dispatch.x_sendfile_header = "X-Accel-Redirect" Make sure to configure your server to support these options following the 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::Request `ActionDispatch::Request#params` will take parameters from the client in the JSON @@ -327,9 +325,9 @@ will be: { :person => { :firstName => "Yehuda", :lastName => "Katz" } } ``` -### Other Middlewares +### Other Middleware -Rails ships with a number of other middlewares that you might want to use in an +Rails ships with a number of other middleware that you might want to use in an API application, especially if one of your API clients is the browser: - `Rack::MethodOverride` @@ -340,13 +338,13 @@ API application, especially if one of your API clients is the browser: * `ActionDispatch::Session::CookieStore` * `ActionDispatch::Session::MemCacheStore` -Any of these middlewares can be added via: +Any of these middleware can be added via: ```ruby config.middleware.use Rack::MethodOverride ``` -### Removing Middlewares +### Removing Middleware If you don't want to use a middleware that is included by default in the API-only middleware set, you can remove it with: @@ -355,7 +353,7 @@ middleware set, you can remove it with: config.middleware.delete ::Rack::Sendfile ``` -Keep in mind that removing these middlewares will remove support for certain +Keep in mind that removing these middleware will remove support for certain features in Action Controller. Choosing Controller Modules @@ -364,22 +362,24 @@ Choosing Controller Modules An API application (using `ActionController::API`) comes with the following controller modules by default: -- `ActionController::UrlFor`: Makes `url_for` and friends available. +- `ActionController::UrlFor`: Makes `url_for` and similar helpers available. - `ActionController::Redirecting`: Support for `redirect_to`. -- `ActionController::Rendering`: Basic support for rendering. +- `AbstractController::Rendering` and `ActionController::ApiRendering`: Basic support for rendering. - `ActionController::Renderers::All`: Support for `render :json` and friends. - `ActionController::ConditionalGet`: Support for `stale?`. -- `ActionController::ForceSSL`: Support for `force_ssl`. -- `ActionController::DataStreaming`: Support for `send_file` and `send_data`. -- `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)). -- `ActionController::Rescue`: Support for `rescue_from`. - `ActionController::BasicImplicitRender`: Makes sure to return an empty response if there's not an explicit one. - `ActionController::StrongParameters`: Support for parameters white-listing in combination with Active Model mass assignment. +- `ActionController::ForceSSL`: Support for `force_ssl`. +- `ActionController::DataStreaming`: Support for `send_file` and `send_data`. +- `AbstractController::Callbacks`: Support for `before_action` and + similar helpers. +- `ActionController::Rescue`: Support for `rescue_from`. +- `ActionController::Instrumentation`: Support for the instrumentation + hooks defined by Action Controller (see [the instrumentation + guide](active_support_instrumentation.html#action-controller) for +more information regarding this). - `ActionController::ParamsWrapper`: Wraps the parameters hash into a nested hash so you don't have to specify root elements sending POST requests for instance. @@ -408,5 +408,5 @@ Some common modules you might want to add: - `ActionController::Cookies`: Support for `cookies`, which includes support for signed and encrypted cookies. This requires the cookies middleware. -The best place to add a module is in your `ApplicationController` but you can +The best place to add a module is in your `ApplicationController`, but you can also add modules to individual controllers. diff --git a/guides/source/asset_pipeline.md b/guides/source/asset_pipeline.md index 60f78d011c..4efffc6605 100644 --- a/guides/source/asset_pipeline.md +++ b/guides/source/asset_pipeline.md @@ -21,8 +21,11 @@ What is the Asset Pipeline? The asset pipeline provides a framework to concatenate and minify or compress JavaScript and CSS assets. It also adds the ability to write these assets in other languages and pre-processors such as CoffeeScript, Sass and ERB. +It allows assets in your application to be automatically combined with assets +from other gems. For example, jquery-rails includes a copy of jquery.js +and enables AJAX features in Rails. -The asset pipeline is technically no longer a core feature of Rails 4, it has +The asset pipeline is technically no longer a core feature from Rails 4 onwards -- it has been extracted out of the framework into the [sprockets-rails](https://github.com/rails/sprockets-rails) gem. @@ -35,7 +38,7 @@ passing the `--skip-sprockets` option. rails new appname --skip-sprockets ``` -Rails 4 automatically adds the `sass-rails`, `coffee-rails` and `uglifier` +Rails automatically adds the `sass-rails`, `coffee-rails` and `uglifier` gems to your Gemfile, which are used by Sprockets for asset compression: ```ruby @@ -44,8 +47,8 @@ gem 'uglifier' gem 'coffee-rails' ``` -Using the `--skip-sprockets` option will prevent Rails 4 from adding -`sass-rails` and `uglifier` to Gemfile, so if you later want to enable +Using the `--skip-sprockets` option will prevent Rails from adding +them to your Gemfile, so if you later want to enable the asset pipeline you will have to add those gems to your Gemfile. Also, creating an application with the `--skip-sprockets` option will generate a slightly different `config/application.rb` file, with a require statement @@ -66,7 +69,7 @@ config.assets.js_compressor = :uglifier ``` NOTE: The `sass-rails` gem is automatically used for CSS compression if included -in Gemfile and no `config.assets.css_compressor` option is set. +in the Gemfile and no `config.assets.css_compressor` option is set. ### Main Features @@ -327,7 +330,7 @@ familiar `javascript_include_tag` and `stylesheet_link_tag`: <%= javascript_include_tag "application" %> ``` -If using the turbolinks gem, which is included by default in Rails 4, then +If using the turbolinks gem, which is included by default in Rails, then include the 'data-turbolinks-track' option which causes turbolinks to check if an asset has been updated and if so loads it into the page: @@ -443,7 +446,7 @@ makes fewer requests. Compression also reduces file size, enabling the browser to download them faster. -For example, a new Rails 4 application includes a default +For example, a new Rails application includes a default `app/assets/javascripts/application.js` file containing the following lines: ```js @@ -484,7 +487,7 @@ which contains these lines: */ ``` -Rails 4 creates both `app/assets/javascripts/application.js` and +Rails creates both `app/assets/javascripts/application.js` and `app/assets/stylesheets/application.css` regardless of whether the --skip-sprockets option is used when creating a new rails application. This is so you can easily add asset pipelining later if you like. @@ -1108,7 +1111,7 @@ supported runtime in order to use `uglifier`. If you are using Mac OS X or Windows you have a JavaScript runtime installed in your operating system. NOTE: The `config.assets.compress` initialization option is no longer used in -Rails 4 to enable either CSS or JavaScript compression. Setting it will have no +Rails to enable either CSS or JavaScript compression. Setting it will have no effect on the application. Instead, setting `config.assets.css_compressor` and `config.assets.js_compressor` will control compression of CSS and JavaScript assets. @@ -1177,19 +1180,14 @@ TIP: For further details have a look at the docs of your production web server: Assets Cache Store ------------------ -The default Rails cache store will be used by Sprockets to cache assets in -development and production. This can be changed by setting -`config.assets.cache_store`: +By default, Sprockets caches assets in `tmp/cache/assets` in development +and production environments. This can be changed as follows: ```ruby -config.assets.cache_store = :memory_store -``` - -The options accepted by the assets cache store are the same as the application's -cache store. - -```ruby -config.assets.cache_store = :memory_store, { size: 32.megabytes } +config.assets.configure do |env| + env.cache = ActiveSupport::Cache.lookup_store(:memory_store, + { size: 32.megabytes }) +end ``` To disable the assets cache store: @@ -1295,12 +1293,12 @@ config.assets.digest = true # config.assets.precompile += %w( search.js ) ``` -Rails 4 no longer sets default config values for Sprockets in `test.rb`, so +Rails 4 and above no longer set default config values for Sprockets in `test.rb`, so `test.rb` now requires Sprockets configuration. The old defaults in the test environment are: `config.assets.compile = true`, `config.assets.compress = false`, `config.assets.debug = false` and `config.assets.digest = false`. -The following should also be added to `Gemfile`: +The following should also be added to your `Gemfile`: ```ruby gem 'sass-rails', "~> 3.2.3" diff --git a/guides/source/association_basics.md b/guides/source/association_basics.md index accce5a904..09ab64837a 100644 --- a/guides/source/association_basics.md +++ b/guides/source/association_basics.md @@ -713,7 +713,7 @@ By default, Active Record doesn't know about the connection between these associ ```ruby a = Author.first -b = c.books.first +b = a.books.first a.first_name == b.author.first_name # => true a.first_name = 'Manny' a.first_name == b.author.first_name # => false @@ -726,7 +726,7 @@ class Author < ApplicationRecord has_many :books, inverse_of: :author end -class book < ApplicationRecord +class Book < ApplicationRecord belongs_to :author, inverse_of: :books end ``` @@ -735,7 +735,7 @@ With these changes, Active Record will only load one copy of the author object, ```ruby a = author.first -b = c.books.first +b = a.books.first a.first_name == b.author.first_name # => true a.first_name = 'Manny' a.first_name == b.author.first_name # => true diff --git a/guides/source/command_line.md b/guides/source/command_line.md index f33e729de0..e865a02cbd 100644 --- a/guides/source/command_line.md +++ b/guides/source/command_line.md @@ -325,7 +325,7 @@ With the `helper` method it is possible to access Rails and your application's h ### `rails dbconsole` -`rails dbconsole` figures out which database you're using and drops you into whichever command line interface you would use with it (and figures out the command line parameters to give to it, too!). It supports MySQL, PostgreSQL, SQLite and SQLite3. +`rails dbconsole` figures out which database you're using and drops you into whichever command line interface you would use with it (and figures out the command line parameters to give to it, too!). It supports MySQL, PostgreSQL and SQLite3. INFO: You can also use the alias "db" to invoke the dbconsole: `rails db`. @@ -432,7 +432,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, Rack::Head, Rack::ConditionalGet, Rack::ETag +Middleware Rack::Sendfile, ActionDispatch::Static, ActionDispatch::LoadInterlock, #<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 @@ -618,7 +618,7 @@ We had to create the **gitapp** directory and initialize an empty git repository ```bash $ cat config/database.yml -# PostgreSQL. Versions 8.2 and up are supported. +# PostgreSQL. Versions 9.1 and up are supported. # # Install the pg driver: # gem install pg diff --git a/guides/source/configuring.md b/guides/source/configuring.md index 8a21d4062a..a5fb396f15 100644 --- a/guides/source/configuring.md +++ b/guides/source/configuring.md @@ -159,8 +159,6 @@ pipeline is enabled. It is set to true by default. * `config.assets.debug` disables the concatenation and compression of assets. Set to `true` by default in `development.rb`. -* `config.assets.cache_store` defines the cache store that Sprockets will use. The default is the Rails file store. - * `config.assets.compile` is a boolean that can be used to turn on live Sprockets compilation in production. * `config.assets.logger` accepts a logger conforming to the interface of Log4r or the default Ruby `Logger` class. Defaults to the same configured at `config.logger`. Setting `config.assets.logger` to false will turn off served assets logging. @@ -200,7 +198,7 @@ Every Rails application comes with a standard set of middleware which it uses in * `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`. +* `ActionDispatch::LoadInterlock` allows thread safe code reloading. Disabled if `config.allow_concurrency` is `false`, which causes `Rack::Lock` to be loaded. `Rack::Lock` wraps the app in mutex so it can only be called by a single thread at a time. * `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. * `Rails::Rack::Logger` notifies the logs that the request has begun. After request is complete, flushes all the logs. @@ -1000,7 +998,7 @@ Below is a comprehensive list of all the initializers found in Rails in the orde * `initialize_cache` If `Rails.cache` isn't set yet, initializes the cache by referencing the value in `config.cache_store` and stores the outcome as `Rails.cache`. If this object responds to the `middleware` method, its middleware is inserted before `Rack::Runtime` in the middleware stack. -* `set_clear_dependencies_hook` Provides a hook for `active_record.set_dispatch_hooks` to use, which will run before this initializer. This initializer - which runs only if `cache_classes` is set to `false` - uses `ActionDispatch::Callbacks.after` to remove the constants which have been referenced during the request from the object space so that they will be reloaded during the following request. +* `set_clear_dependencies_hook` This initializer - which runs only if `cache_classes` is set to `false` - uses `ActionDispatch::Callbacks.after` to remove the constants which have been referenced during the request from the object space so that they will be reloaded during the following request. * `initialize_dependency_mechanism` If `config.cache_classes` is true, configures `ActiveSupport::Dependencies.mechanism` to `require` dependencies rather than `load` them. @@ -1014,13 +1012,17 @@ Below is a comprehensive list of all the initializers found in Rails in the orde * `active_support.initialize_beginning_of_week` Sets the default beginning of week for the application based on `config.beginning_of_week` setting, which defaults to `:monday`. +* `active_support.set_configs` Sets up Active Support by using the settings in `config.active_support` by `send`'ing the method names as setters to `ActiveSupport` and passing the values through. + * `action_dispatch.configure` Configures the `ActionDispatch::Http::URL.tld_length` to be set to the value of `config.action_dispatch.tld_length`. * `action_view.set_configs` Sets up Action View by using the settings in `config.action_view` by `send`'ing the method names as setters to `ActionView::Base` and passing the values through. -* `action_controller.logger` Sets `ActionController::Base.logger` - if it's not already set - to `Rails.logger`. +* `action_controller.assets_config` Initializes the `config.actions_controller.assets_dir` to the app's public directory if not explicitly configured -* `action_controller.initialize_framework_caches` Sets `ActionController::Base.cache_store` - if it's not already set - to `Rails.cache`. +* `action_controller.set_helpers_path` Sets Action Controller's helpers_path to the application's helpers_path + +* `action_controller.parameters_config` Configures strong parameters options for `ActionController::Parameters` * `action_controller.set_configs` Sets up Action Controller by using the settings in `config.action_controller` by `send`'ing the method names as setters to `ActionController::Base` and passing the values through. @@ -1030,13 +1032,21 @@ Below is a comprehensive list of all the initializers found in Rails in the orde * `active_record.logger` Sets `ActiveRecord::Base.logger` - if it's not already set - to `Rails.logger`. +* `active_record.migration_error` Configures middleware to check for pending migrations + +* `active_record.check_schema_cache_dump` Loads the schema cache dump if configured and available + +* `active_record.warn_on_records_fetched_greater_than` Enables warnings when queries return large numbers of records + * `active_record.set_configs` Sets up Active Record by using the settings in `config.active_record` by `send`'ing the method names as setters to `ActiveRecord::Base` and passing the values through. * `active_record.initialize_database` Loads the database configuration (by default) from `config/database.yml` and establishes a connection for the current environment. * `active_record.log_runtime` Includes `ActiveRecord::Railties::ControllerRuntime` which is responsible for reporting the time taken by Active Record calls for the request back to the logger. -* `active_record.set_dispatch_hooks` Resets all reloadable connections to the database if `config.cache_classes` is set to `false`. +* `active_record.set_reloader_hooks` Resets all reloadable connections to the database if `config.cache_classes` is set to `false`. + +* `active_record.add_watchable_files` Adds `schema.rb` and `structure.sql` files to watchable files * `active_job.logger` Sets `ActiveJob::Base.logger` - if it's not already set - to `Rails.logger`. diff --git a/guides/source/contributing_to_ruby_on_rails.md b/guides/source/contributing_to_ruby_on_rails.md index cbc304c87f..0f98d12217 100644 --- a/guides/source/contributing_to_ruby_on_rails.md +++ b/guides/source/contributing_to_ruby_on_rails.md @@ -105,7 +105,7 @@ $ git checkout -b testing_branch Then you can use their remote branch to update your codebase. For example, let's say the GitHub user JohnSmith has forked and pushed to a topic branch "orange" located at https://github.com/JohnSmith/rails. ```bash -$ git remote add JohnSmith git://github.com/JohnSmith/rails.git +$ git remote add JohnSmith https://github.com/JohnSmith/rails.git $ git pull JohnSmith orange ``` @@ -159,7 +159,7 @@ If you want to translate the Rails guides in your own language, follows these st * 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): +To generate the guides in HTML format cd into the *guides* directory then run (eg. for it-IT): ```bash $ bundle install @@ -204,7 +204,7 @@ In case you can't use the Rails development box, see [this other guide](developm To be able to contribute code, you need to clone the Rails repository: ```bash -$ git clone git://github.com/rails/rails.git +$ git clone https://github.com/rails/rails.git ``` and create a dedicated branch: @@ -506,7 +506,7 @@ Navigate to the Rails [GitHub repository](https://github.com/rails/rails) and pr Add the new remote to your local repository on your local machine: ```bash -$ git remote add mine git@github.com:<your user name>/rails.git +$ git remote add mine https://github.com:<your user name>/rails.git ``` Push to your remote: @@ -520,7 +520,7 @@ You might have cloned your forked repository into your machine and might want to In the directory you cloned your fork: ```bash -$ git remote add rails git://github.com/rails/rails.git +$ git remote add rails https://github.com/rails/rails.git ``` Download new commits and branches from the official repository: diff --git a/guides/source/documents.yaml b/guides/source/documents.yaml index 4473eba478..2cf613f47f 100644 --- a/guides/source/documents.yaml +++ b/guides/source/documents.yaml @@ -135,6 +135,10 @@ work_in_progress: true url: profiling.html description: This guide explains how to profile your Rails applications to improve performance. + - + name: Using Rails for API-only Applications + url: api_app.html + description: This guide explains how to effectively use Rails to develop a JSON API application. - name: Extending Rails diff --git a/guides/source/engines.md b/guides/source/engines.md index 697938434c..415def8367 100644 --- a/guides/source/engines.md +++ b/guides/source/engines.md @@ -1034,6 +1034,8 @@ typical `GET` to a controller in a controller's functional test like this: ```ruby module Blorgh class FooControllerTest < ActionDispatch::IntegrationTest + include Engine.routes.url_helpers + def test_index get foos_url ... @@ -1050,6 +1052,8 @@ in your setup code: ```ruby module Blorgh class FooControllerTest < ActionDispatch::IntegrationTest + include Engine.routes.url_helpers + setup do @routes = Engine.routes end diff --git a/guides/source/getting_started.md b/guides/source/getting_started.md index 9677ab1583..8eb3b6190f 100644 --- a/guides/source/getting_started.md +++ b/guides/source/getting_started.md @@ -93,7 +93,7 @@ current version of Ruby installed: ```bash $ ruby -v -ruby 2.2.2p95 +ruby 2.3.0p0 ``` TIP: A number of tools exist to help you quickly install Ruby and Ruby @@ -653,7 +653,7 @@ run this command in your terminal: $ bin/rails generate model Article title:string text:text ``` -With that command we told Rails that we want a `Article` model, together +With that command we told Rails that we want an `Article` model, together with a _title_ attribute of type string, and a _text_ attribute of type text. Those attributes are automatically added to the `articles` table in the database and mapped to the `Article` model. @@ -767,7 +767,7 @@ Why do you have to bother? The ability to grab and automatically assign all controller parameters to your model in one shot makes the programmer's job easier, but this convenience also allows malicious use. What if a request to the server was crafted to look like a new article form submit but also included -extra fields with values that violated your applications integrity? They would +extra fields with values that violated your application's integrity? They would be 'mass assigned' into your model and then into the database along with the good stuff - potentially breaking your application or worse. @@ -1540,7 +1540,7 @@ This is very similar to the `Article` model that you saw earlier. The difference is the line `belongs_to :article`, which sets up an Active Record _association_. You'll learn a little about associations in the next section of this guide. -The (`:references`) keyword used in the bash command is a special data type for models. +The (`:references`) keyword used in the bash command is a special data type for models. It creates a new column on your database table with the provided model name appended with an `_id` that can hold integer values. You can get a better understanding after analyzing the `db/schema.rb` file below. diff --git a/guides/source/initialization.md b/guides/source/initialization.md index 6232ef4c57..156f9c92b4 100644 --- a/guides/source/initialization.md +++ b/guides/source/initialization.md @@ -157,7 +157,7 @@ snippet. If we had used `s` rather than `server`, Rails would have used the `aliases` defined here to find the matching command. -### `rails/commands/command_tasks.rb` +### `rails/commands/commands_tasks.rb` 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 diff --git a/guides/source/layouts_and_rendering.md b/guides/source/layouts_and_rendering.md index d55e1007ee..6946eb81eb 100644 --- a/guides/source/layouts_and_rendering.md +++ b/guides/source/layouts_and_rendering.md @@ -700,7 +700,7 @@ This would detect that there are no books with the specified ID, populate the `@ ### Using `head` To Build Header-Only Responses -The `head` method can be used to send responses with only headers to the browser. It provides a more obvious alternative to calling `render :nothing`. The `head` method accepts a number or symbol (see [reference table](#the-status-option)) representing a HTTP status code. The options argument is interpreted as a hash of header names and values. For example, you can return only an error header: +The `head` method can be used to send responses with only headers to the browser. The `head` method accepts a number or symbol (see [reference table](#the-status-option)) representing a HTTP status code. The options argument is interpreted as a hash of header names and values. For example, you can return only an error header: ```ruby head :bad_request diff --git a/guides/source/rails_on_rack.md b/guides/source/rails_on_rack.md index 934693252e..3b61d65df5 100644 --- a/guides/source/rails_on_rack.md +++ b/guides/source/rails_on_rack.md @@ -104,7 +104,7 @@ For a freshly generated Rails application, this might produce something like: ```ruby use Rack::Sendfile use ActionDispatch::Static -use Rack::Lock +use ActionDispatch::LoadInterlock use #<ActiveSupport::Cache::Strategy::LocalCache::Middleware:0x000000029a0838> use Rack::Runtime use Rack::MethodOverride @@ -171,10 +171,10 @@ Add the following lines to your application configuration: ```ruby # config/application.rb -config.middleware.delete Rack::Lock +config.middleware.delete Rack::Runtime ``` -And now if you inspect the middleware stack, you'll find that `Rack::Lock` is +And now if you inspect the middleware stack, you'll find that `Rack::Runtime` is not a part of it. ```bash @@ -219,6 +219,10 @@ Much of Action Controller's functionality is implemented as Middlewares. The fol * Sets `env["rack.multithread"]` flag to `false` and wraps the application within a Mutex. +**`ActionDispatch::LoadInterlock`** + +* Used for thread safe code reloading during development. + **`ActiveSupport::Cache::Strategy::LocalCache::Middleware`** * Used for memory caching. This cache is not thread safe. diff --git a/guides/source/routing.md b/guides/source/routing.md index 5a745b10cd..777d1d24b6 100644 --- a/guides/source/routing.md +++ b/guides/source/routing.md @@ -1136,10 +1136,21 @@ For example, here's a small section of the `rails routes` output for a RESTful r edit_user GET /users/:id/edit(.:format) users#edit ``` -You may restrict the listing to the routes that map to a particular controller setting the `CONTROLLER` environment variable: +You can search through your routes with the --grep option (-g for short). This outputs any routes that partially match the URL helper method name, the HTTP verb, or the URL path. -```bash -$ CONTROLLER=users bin/rails routes +``` +$ bin/rails routes --grep new_comment +$ bin/rails routes -g POST +$ bin/rails routes -g admin +``` + +If you only want to see the routes that map to a specific controller, there's the --controller option (-c for short). + +``` +$ bin/rails routes --controller users +$ bin/rails routes --controller admin/users +$ bin/rails routes -c Comments +$ bin/rails routes -c Articles::CommentsController ``` TIP: You'll find that the output from `rails routes` is much more readable if you widen your terminal window until the output lines don't wrap. diff --git a/guides/source/security.md b/guides/source/security.md index 1d0e87d831..98324141cc 100644 --- a/guides/source/security.md +++ b/guides/source/security.md @@ -23,7 +23,7 @@ Web application frameworks are made to help developers build web applications. S In general there is no such thing as plug-n-play security. Security depends on the people using the framework, and sometimes on the development method. And it depends on all layers of a web application environment: The back-end storage, the web server and the web application itself (and possibly other layers or applications). -The Gartner Group however estimates that 75% of attacks are at the web application layer, and found out "that out of 300 audited sites, 97% are vulnerable to attack". This is because web applications are relatively easy to attack, as they are simple to understand and manipulate, even by the lay person. +The Gartner Group, however, estimates that 75% of attacks are at the web application layer, and found out "that out of 300 audited sites, 97% are vulnerable to attack". This is because web applications are relatively easy to attack, as they are simple to understand and manipulate, even by the lay person. The threats against web applications include user account hijacking, bypass of access control, reading or modifying sensitive data, or presenting fraudulent content. Or an attacker might be able to install a Trojan horse program or unsolicited e-mail sending software, aim at financial enrichment or cause brand name damage by modifying company resources. In order to prevent attacks, minimize their impact and remove points of attack, first of all, you have to fully understand the attack methods in order to find the correct countermeasures. That is what this guide aims at. @@ -62,7 +62,7 @@ Many web applications have an authentication system: a user provides a user name Hence, the cookie serves as temporary authentication for the web application. Anyone who seizes a cookie from someone else, may use the web application as this user - with possibly severe consequences. Here are some ways to hijack a session, and their countermeasures: -* Sniff the cookie in an insecure network. A wireless LAN can be an example of such a network. In an unencrypted wireless LAN it is especially easy to listen to the traffic of all connected clients. For the web application builder this means to _provide a secure connection over SSL_. In Rails 3.1 and later, this could be accomplished by always forcing SSL connection in your application config file: +* Sniff the cookie in an insecure network. A wireless LAN can be an example of such a network. In an unencrypted wireless LAN, it is especially easy to listen to the traffic of all connected clients. For the web application builder this means to _provide a secure connection over SSL_. In Rails 3.1 and later, this could be accomplished by always forcing SSL connection in your application config file: ```ruby config.force_ssl = true @@ -102,7 +102,7 @@ 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_. +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 `rails 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.: @@ -787,7 +787,7 @@ The following is an excerpt from the [Js.Yamanner@m](http://www.symantec.com/sec var IDList = ''; var CRumb = ''; function makeRequest(url, Func, Method,Param) { ... ``` -The worms exploits a hole in Yahoo's HTML/JavaScript filter, which usually filters all target and onload attributes from tags (because there can be JavaScript). The filter is applied only once, however, so the onload attribute with the worm code stays in place. This is a good example why blacklist filters are never complete and why it is hard to allow HTML/JavaScript in a web application. +The worms exploit a hole in Yahoo's HTML/JavaScript filter, which usually filters all targets and onload attributes from tags (because there can be JavaScript). The filter is applied only once, however, so the onload attribute with the worm code stays in place. This is a good example why blacklist filters are never complete and why it is hard to allow HTML/JavaScript in a web application. Another proof-of-concept webmail worm is Nduja, a cross-domain worm for four Italian webmail services. Find more details on [Rosario Valotta's paper](http://www.xssed.com/news/37/Nduja_Connection_A_cross_webmail_worm_XWW/). Both webmail worms have the goal to harvest email addresses, something a criminal hacker could make money with. diff --git a/guides/source/testing.md b/guides/source/testing.md index b5e49a41f4..1c64b2c0ac 100644 --- a/guides/source/testing.md +++ b/guides/source/testing.md @@ -265,7 +265,7 @@ By now you've caught a glimpse of some of the assertions that are available. Ass Here's an extract of the assertions you can use with [`Minitest`](https://github.com/seattlerb/minitest), the default testing library used by Rails. The `[msg]` parameter is an optional string message you can -specify to make your test failure messages clearer. +specify to make your test failure messages clearer. | Assertion | Purpose | | ---------------------------------------------------------------- | ------- | @@ -316,12 +316,12 @@ Rails adds some custom assertions of its own to the `minitest` framework: | Assertion | Purpose | | --------------------------------------------------------------------------------- | ------- | -| `assert_difference(expressions, difference = 1, message = nil) {...}` | Test numeric difference between the return value of an expression as a result of what is evaluated in the yielded block.| -| `assert_no_difference(expressions, message = nil, &block)` | Asserts that the numeric result of evaluating an expression is not changed before and after invoking the passed in block.| -| `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)` | 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`.| +| [`assert_difference(expressions, difference = 1, message = nil) {...}`](http://api.rubyonrails.org/classes/ActiveSupport/Testing/Assertions.html#method-i-assert_difference) | Test numeric difference between the return value of an expression as a result of what is evaluated in the yielded block.| +| [`assert_no_difference(expressions, message = nil, &block)`](http://api.rubyonrails.org/classes/ActiveSupport/Testing/Assertions.html#method-i-assert_no_difference) | Asserts that the numeric result of evaluating an expression is not changed before and after invoking the passed in block.| +| [`assert_recognizes(expected_options, path, extras={}, message=nil)`](http://api.rubyonrails.org/classes/ActionDispatch/Assertions/RoutingAssertions.html#method-i-assert_recognizes) | 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)`](http://api.rubyonrails.org/classes/ActionDispatch/Assertions/RoutingAssertions.html#method-i-assert_generates) | 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)`](http://api.rubyonrails.org/classes/ActionDispatch/Assertions/ResponseAssertions.html#method-i-assert_response) | 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)`](http://api.rubyonrails.org/classes/ActionDispatch/Assertions/ResponseAssertions.html#method-i-assert_redirected_to) | 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. @@ -329,11 +329,11 @@ You'll see the usage of some of these assertions in the next chapter. 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` -* `ActionMailer::TestCase` -* `ActionView::TestCase` -* `ActionDispatch::IntegrationTest` -* `ActiveJob::TestCase` +* [`ActiveSupport::TestCase`](http://api.rubyonrails.org/classes/ActiveSupport/TestCase.html) +* [`ActionMailer::TestCase`](http://api.rubyonrails.org/classes/ActionMailer/TestCase.html) +* [`ActionView::TestCase`](http://api.rubyonrails.org/classes/ActionView/TestCase.html) +* [`ActionDispatch::IntegrationTest`](http://api.rubyonrails.org/classes/ActionDispatch/IntegrationTest.html) +* [`ActiveJob::TestCase`](http://api.rubyonrails.org/classes/ActiveJob/TestCase.html) Each of these classes include `Minitest::Assertions`, allowing us to use all of the basic assertions in our tests. @@ -415,6 +415,8 @@ You can find comprehensive documentation in the [Fixtures API documentation](htt _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. +NOTE: Fixtures are not designed to create every object that your tests need, and are best managed when only used for default data that can be applied to the common case. + 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 @@ -518,7 +520,7 @@ 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`. +Model tests don't have their own superclass like `ActionMailer::TestCase` instead they inherit from [`ActiveSupport::TestCase`](http://api.rubyonrails.org/classes/ActiveSupport/TestCase.html). Integration Testing @@ -589,7 +591,7 @@ class BlogFlowTest < ActionDispatch::IntegrationTest end ``` -We will take a look at `assert_select` to query the resulting HTML of a request in the "Testing Views" section below. It is used for testing the response of our request by asserting the presence of key HTML elements and their content. +We will take a look at `assert_select` to query the resulting HTML of a request in the "Testing Views" section below. It is used for testing the response of our request by asserting the presence of key HTML elements and their content. When we visit our root path, we should see `welcome/index.html.erb` rendered for the view. So this assertion should pass. @@ -638,9 +640,9 @@ We were able to successfully test a very small workflow for visiting our blog an Functional Tests for Your Controllers ------------------------------------- -In Rails, testing the various actions of a controller is a form of writing functional tests. Remember your controllers handle the incoming web requests to your application and eventually respond with a rendered view. When writing functional tests, you're testing how your actions handle the requests and the expected result, or response in some cases an HTML view. +In Rails, testing the various actions of a controller is a form of writing functional tests. Remember your controllers handle the incoming web requests to your application and eventually respond with a rendered view. When writing functional tests, you are testing how your actions handle the requests and the expected result or response, in some cases an HTML view. -### What to Include in your Functional Tests +### What to include in your Functional Tests You should test for things such as: @@ -650,8 +652,7 @@ 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? -The easiest way to see functional tests in action is to generate a controller -scaffold: +The easiest way to see functional tests in action is to generate a controller using the scaffold generator: ```bash $ bin/rails generate scaffold_controller article title:string body:text @@ -664,7 +665,7 @@ 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. +You can take a 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: @@ -677,7 +678,7 @@ 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`. +Let's take a look at one such test, `test_should_get_index` from the file `articles_controller_test.rb`. ```ruby # articles_controller_test.rb @@ -693,7 +694,7 @@ end In the `test_should_get_index` test, Rails simulates a request on the action called `index`, making sure the request was successful 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 `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 route (i.e. `articles_url`). @@ -705,7 +706,7 @@ The `get` method kicks off the web request and populates the results into the re * `flash`: option with a hash of flash values. -All the keyword arguments are optional. +All of these keyword arguments are optional. Example: Calling the `:show` action, passing an `id` of 12 as the `params` and setting a `user_id` of 5 in the session: @@ -753,7 +754,7 @@ NOTE: Functional tests do not verify whether the specified request type is accep ### Testing XHR (AJAX) requests To test AJAX requests, you can specify the `xhr: true` option to `get`, `post`, -`patch`, `put`, and `delete` methods: +`patch`, `put`, and `delete` methods. For example: ```ruby test "ajax request" do @@ -808,7 +809,7 @@ post article_url # simulate the request with custom env variable ### Testing `flash` notices -If you remember from earlier one of the Three 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. @@ -893,7 +894,7 @@ test "should show article" do end ``` -Remember from our discussion earlier on fixtures the `articles()` method will give us access to our Articles fixtures. +Remember from our discussion earlier on fixtures, the `articles()` method will give us access to our Articles fixtures. How about deleting an existing Article? @@ -913,14 +914,19 @@ We can also add a test for updating an existing Article. ```ruby test "should update article" do article = articles(:one) + patch '/article', params: { id: article.id, article: { title: "updated" } } + assert_redirected_to article_path(article) + # Reload association to fetch updated data and assert that title is updated. + article.reload + assert_equal "updated", article.title end ``` Notice we're starting to see some duplication in these three tests, they both access the same Article fixture data. We can D.R.Y. this up by using the `setup` and `teardown` methods provided by `ActiveSupport::Callbacks`. -Our test should now look something like this, disregard the other tests we're leaving them out for brevity. +Our test should now look something as what follows. Disregard the other tests for now, we're leaving them out for brevity. ```ruby require 'test_helper' @@ -952,8 +958,12 @@ class ArticlesControllerTest < ActionDispatch::IntegrationTest end test "should update article" do - patch article_url(@article), params: { article: { title: "updated" } } + patch '/article', params: { id: @article.id, article: { title: "updated" } } + assert_redirected_to article_path(@article) + # Reload association to fetch updated data and assert that title is updated. + @article.reload + assert_equal "updated", @article.title end end ``` @@ -966,7 +976,7 @@ To avoid code duplication, you can add your own test helpers. Sign in helper can be a good example: ```ruby -test/test_helper.rb +#test/test_helper.rb module SignInHelper def sign_in(user) @@ -999,6 +1009,8 @@ Testing Routes Like everything else in your Rails application, you can test your routes. +NOTE: If your application has complex routes, Rails provides a number of useful helpers to test them. + 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). Testing Views @@ -1045,7 +1057,7 @@ assert_select "ol" do end ``` -This assertion is quite powerful. For more advanced usage, refer to its [documentation](http://www.rubydoc.info/github/rails/rails-dom-testing). +This assertion is quite powerful. For more advanced usage, refer to its [documentation](https://github.com/rails/rails-dom-testing/blob/master/lib/rails/dom/testing/assertions/selector_assertions.rb). #### Additional View-Based Assertions @@ -1068,27 +1080,31 @@ end Testing Helpers --------------- +A helper is just a simple module where you can define methods which are +available into your views. + In order to test helpers, all you need to do is check that the output of the helper method matches what you'd expect. Tests related to the helpers are located under the `test/helpers` directory. -A helper test looks like so: +Given we have the following helper: ```ruby -require 'test_helper' - -class UserHelperTest < ActionView::TestCase +module UserHelper + def link_to_user(user) + link_to "#{user.first_name} #{user.last_name}", user + end end ``` -A helper is just a simple module where you can define methods which are -available into your views. To test the output of the helper's methods, you just -have to use a mixin like this: +We can test the output of this method like this: ```ruby class UserHelperTest < ActionView::TestCase - test "should return the user name" do - # ... + test "should return the user's full name" do + user = users(:david) + + assert_dom_equal %{<a href="/user/#{user.id}">David Heinemeier Hansson</a>}, link_to_user(user) end end ``` @@ -1123,7 +1139,7 @@ In order to test that your mailer is working as expected, you can use unit tests For the purposes of unit testing a mailer, fixtures are used to provide an example of how the output _should_ look. Because these are example emails, and not Active Record data like the other fixtures, they are kept in their own subdirectory apart from the other fixtures. The name of the directory within `test/fixtures` directly corresponds to the name of the mailer. So, for a mailer named `UserMailer`, the fixtures should reside in `test/fixtures/user_mailer` directory. -When you generated your mailer, the generator creates stub fixtures for each of the mailers actions. If you didn't use the generator you'll have to make those files yourself. +When you generated your mailer, the generator creates stub fixtures for each of the mailers actions. If you didn't use the generator, you'll have to create those files yourself. #### The Basic Test Case @@ -1204,7 +1220,7 @@ Testing Jobs ------------ Since your custom jobs can be queued at different levels inside your application, -you'll need to test both jobs themselves (their behavior when they get enqueued) +you'll need to test both, the jobs themselves (their behavior when they get enqueued) and that other entities correctly enqueue them. ### A Basic Test Case @@ -1252,10 +1268,12 @@ class ProductTest < ActiveJob::TestCase end ``` -Testing Time-Dependent Code ---------------------------- +Additional Testing Resources +---------------------------- + +### Testing Time-Dependent Code -Rails provides inbuilt helper methods that enable you to assert that your time-sensitve code works as expected. +Rails provides built-in helper methods that enable you to assert that your time-sensitive code works as expected. Here is an example using the [`travel_to`](http://api.rubyonrails.org/classes/ActiveSupport/Testing/TimeHelpers.html#method-i-travel_to) helper: diff --git a/guides/source/upgrading_ruby_on_rails.md b/guides/source/upgrading_ruby_on_rails.md index 936547a8cc..e631445492 100644 --- a/guides/source/upgrading_ruby_on_rails.md +++ b/guides/source/upgrading_ruby_on_rails.md @@ -57,10 +57,6 @@ Upgrading from Rails 4.2 to Rails 5.0 ToDo... -### Ruby 2.2.2+ - -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, @@ -406,7 +402,7 @@ secrets, you need to: 3. Remove the `secret_token.rb` initializer. -4. Use `rake secret` to generate new keys for the `development` and `test` sections. +4. Use `rails secret` to generate new keys for the `development` and `test` sections. 5. Restart your server. diff --git a/guides/source/working_with_javascript_in_rails.md b/guides/source/working_with_javascript_in_rails.md index 48fc6bc9c0..26ff5da7a3 100644 --- a/guides/source/working_with_javascript_in_rails.md +++ b/guides/source/working_with_javascript_in_rails.md @@ -148,10 +148,10 @@ and Rails has got your back in those cases. Because of Unobtrusive JavaScript, the Rails "Ajax helpers" are actually in two parts: the JavaScript half and the Ruby half. +Unless you have disabled the Asset Pipeline, [rails.js](https://github.com/rails/jquery-ujs/blob/master/src/rails.js) provides the JavaScript half, and the regular Ruby view helpers add appropriate -tags to your DOM. The CoffeeScript in rails.js then listens for these -attributes, and attaches appropriate handlers. +tags to your DOM. ### form_for @@ -350,7 +350,7 @@ $("<%= escape_javascript(render @user) %>").appendTo("#users"); Turbolinks ---------- -Rails 4 ships with the [Turbolinks gem](https://github.com/rails/turbolinks). +Rails 4 ships with the [Turbolinks gem](https://github.com/turbolinks/turbolinks). This gem uses Ajax to speed up page rendering in most applications. ### How Turbolinks Works @@ -395,7 +395,7 @@ $(document).on "page:change", -> For more details, including other events you can bind to, check out [the Turbolinks -README](https://github.com/rails/turbolinks/blob/master/README.md). +README](https://github.com/turbolinks/turbolinks/blob/master/README.md). Other Resources --------------- |