diff options
Diffstat (limited to 'guides')
-rw-r--r-- | guides/source/4_2_release_notes.md | 107 | ||||
-rw-r--r-- | guides/source/active_job_basics.md | 253 | ||||
-rw-r--r-- | guides/source/active_record_querying.md | 2 | ||||
-rw-r--r-- | guides/source/caching_with_rails.md | 7 | ||||
-rw-r--r-- | guides/source/command_line.md | 4 | ||||
-rw-r--r-- | guides/source/configuring.md | 25 | ||||
-rw-r--r-- | guides/source/contributing_to_ruby_on_rails.md | 2 | ||||
-rw-r--r-- | guides/source/development_dependencies_install.md | 2 | ||||
-rw-r--r-- | guides/source/documents.yaml | 4 | ||||
-rw-r--r-- | guides/source/engines.md | 8 | ||||
-rw-r--r-- | guides/source/generators.md | 17 | ||||
-rw-r--r-- | guides/source/getting_started.md | 20 | ||||
-rw-r--r-- | guides/source/layouts_and_rendering.md | 2 | ||||
-rw-r--r-- | guides/source/plugins.md | 46 | ||||
-rw-r--r-- | guides/source/rails_application_templates.md | 24 | ||||
-rw-r--r-- | guides/source/ruby_on_rails_guides_guidelines.md | 22 | ||||
-rw-r--r-- | guides/source/security.md | 8 | ||||
-rw-r--r-- | guides/source/testing.md | 21 | ||||
-rw-r--r-- | guides/source/upgrading_ruby_on_rails.md | 74 |
19 files changed, 545 insertions, 103 deletions
diff --git a/guides/source/4_2_release_notes.md b/guides/source/4_2_release_notes.md index 12db528b91..1c14519506 100644 --- a/guides/source/4_2_release_notes.md +++ b/guides/source/4_2_release_notes.md @@ -16,9 +16,9 @@ Upgrading to Rails 4.2 If you're upgrading an existing application, it's a great idea to have good test coverage before going in. You should also first upgrade to Rails 4.1 in case you haven't and make sure your application still runs as expected before attempting -an update to Rails 4.2. A list of things to watch out for when upgrading is +to upgrade to Rails 4.2. 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-1-to-rails-4-2) +[Upgrading Ruby on Rails](upgrading_ruby_on_rails.html#upgrading-from-rails-4.1-to-rails-4.2) guide. @@ -69,11 +69,58 @@ Please refer to the [Changelog][railties] for detailed changes. ### Notable changes -* Introduced `--skip-gems` option in the app generator to skip gems such as +* Added a `required` option to the model generator for associations. + ([Pull Request](https://github.com/rails/rails/pull/16062)) + +* Introduced an `after_bundle` callback for use in Rails templates. + ([Pull Request](https://github.com/rails/rails/pull/16359)) + +* Introduced the `x` namespace for defining custom configuration options: + + ```ruby + # config/environments/production.rb + config.x.payment_processing.schedule = :daily + config.x.payment_processing.retries = 3 + config.x.super_debugger = true + ``` + + These options 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 + ``` + + ([Commit](https://github.com/rails/rails/commit/611849772dd66c2e4d005dcfe153f7ce79a8a7db)) + +* Introduced `Rails::Application.config_for` to load a configuration for the + current environment. + + ```ruby + # config/exception_notification.yml: + production: + url: http://127.0.0.1:8080 + namespace: my_app_production + development: + url: http://localhost:3001 + namespace: my_app_development + + # config/production.rb + MyApp::Application.configure do + config.middleware.use ExceptionNotifier, config_for(:exception_notification) + end + ``` + + ([Pull Request](https://github.com/rails/rails/pull/16129)) + +* Introduced a `--skip-gems` option in the app generator to skip gems such as `turbolinks` and `coffee-rails` that does not have their own specific flags. ([Commit](https://github.com/rails/rails/commit/10565895805887d4faf004a6f71219da177f78b7)) -* Introduced `bin/setup` script to bootstrap an application. +* Introduced a `bin/setup` script to enable automated setup code when + bootstrapping an application. ([Pull Request](https://github.com/rails/rails/pull/15189)) * Changed default value for `config.assets.digest` to `true` in development. @@ -85,14 +132,32 @@ Please refer to the [Changelog][railties] for detailed changes. * Introduced `Rails.gem_version` as a convenience method to return `Gem::Version.new(Rails.version)`. ([Pull Request](https://github.com/rails/rails/pull/14101)) +* Introduced an `after_bundle` callback in the Rails templates. + ([Pull Request](https://github.com/rails/rails/pull/16359)) + Action Pack ----------- Please refer to the [Changelog][action-pack] for detailed changes. +### Removals + +* `respond_with` and the class-level `respond_to` were removed from Rails and + moved to the `responders` gem (version 2.0). Add `gem 'responders', '~> 2.0'` + to your `Gemfile` to continue using these features. + ([Pull Request](https://github.com/rails/rails/pull/16526)) + +* Removed deprecated `AbstractController::Helpers::ClassMethods::MissingHelperError` + in favor of `AbstractController::Helpers::MissingHelperError`. + ([Commit](https://github.com/rails/rails/commit/a1ddde15ae0d612ff2973de9cf768ed701b594e8)) + ### Deprecations +* Deprecated `assert_tag`, `assert_no_tag`, `find_tag` and `find_all_tag` in + favor of `assert_select`. + ([Commit](https://github.com/rails/rails-dom-testing/commit/b12850bc5ff23ba4b599bf2770874dd4f11bf750)) + * Deprecated support for setting the `:to` option of a router to a symbol or a string that does not contain a `#` character: @@ -107,6 +172,9 @@ Please refer to the [Changelog][action-pack] for detailed changes. ### Notable changes +* Rails will now automatically include the template's digest in ETags. + ([Pull Request](https://github.com/rails/rails/pull/16527)) + * `render nothing: true` or rendering a `nil` body no longer add a single space padding to the response body. ([Pull Request](https://github.com/rails/rails/pull/14883)) @@ -116,8 +184,8 @@ Please refer to the [Changelog][action-pack] for detailed changes. is `['controller', 'action']`. ([Pull Request](https://github.com/rails/rails/pull/15933)) -* The `*_filter` family methods has been removed from the documentation. Their - usage are discouraged in favor of the `*_action` family methods: +* The `*_filter` family methods have been removed from the documentation. Their + usage is discouraged in favor of the `*_action` family methods: ``` after_filter => after_action @@ -152,10 +220,10 @@ Please refer to the [Changelog][action-pack] for detailed changes. * Segments that are passed into URL helpers are now automatically escaped. ([Commit](https://github.com/rails/rails/commit/5460591f0226a9d248b7b4f89186bd5553e7768f)) -* Improved Routing Error page with fuzzy matching for route search. +* Improved the Routing Error page with fuzzy matching for route search. ([Pull Request](https://github.com/rails/rails/pull/14619)) -* Added option to disable logging of CSRF failures. +* Added an option to disable logging of CSRF failures. ([Pull Request](https://github.com/rails/rails/pull/14280)) @@ -171,12 +239,18 @@ Please refer to the [Changelog][action-view] for detailed changes. where to find views. ([Pull Request](https://github.com/rails/rails/pull/15026)) -* Deprecated `ActionView::Digestor#digest(name, format, finder, options = {})`, - arguments should be passed as a hash instead. +* Deprecated `ActionView::Digestor#digest(name, format, finder, options = {})`. + Arguments should be passed as a hash instead. ([Pull Request](https://github.com/rails/rails/pull/14243)) ### Notable changes +* Introduced a `#{partial_name}_iteration` special local variable for use with + partials that are rendered with a collection. It provides access to the + current state of the iteration via the `#index`, `#size`, `#first?` and + `#last?` methods. + ([Pull Request](https://github.com/rails/rails/pull/7698)) + * The form helpers no longer generate a `<div>` element with inline CSS around the hidden fields. ([Pull Request](https://github.com/rails/rails/pull/14738)) @@ -187,8 +261,17 @@ Action Mailer Please refer to the [Changelog][action-mailer] for detailed changes. +### Deprecations + +* Deprecated `*_path` helpers in mailers. Always use `*_url` helpers instead. + ([Pull Request](https://github.com/rails/rails/pull/15840)) + ### Notable changes +* Introduced `deliver_later` which enqueues a job on the application's queue + to deliver the mailer asynchronously. + ([Pull Request](https://github.com/rails/rails/pull/16485)) + * Added the `show_previews` configuration option for enabling mailer previews outside of the development environment. ([Pull Request](https://github.com/rails/rails/pull/15970)) @@ -324,7 +407,7 @@ Please refer to the [Changelog][active-model] for detailed changes. ### Notable changes -* Introduced `undo_changes` method in `ActiveModel::Dirty` to restore the +* Introduced the `undo_changes` method in `ActiveModel::Dirty` to restore the changed (dirty) attributes to their previous values. ([Pull Request](https://github.com/rails/rails/pull/14861)) @@ -370,7 +453,7 @@ Please refer to the [Changelog][active-support] for detailed changes. * The `humanize` inflector helper now strips any leading underscores. ([Commit](https://github.com/rails/rails/commit/daaa21bc7d20f2e4ff451637423a25ff2d5e75c7)) -* Introduce `Concern#class_methods` as an alternative to +* Introduced `Concern#class_methods` as an alternative to `module ClassMethods`, as well as `Kernel#concern` to avoid the `module Foo; extend ActiveSupport::Concern; end` boilerplate. ([Commit](https://github.com/rails/rails/commit/b16c36e688970df2f96f793a759365b248b582ad)) diff --git a/guides/source/active_job_basics.md b/guides/source/active_job_basics.md new file mode 100644 index 0000000000..ae5d21d546 --- /dev/null +++ b/guides/source/active_job_basics.md @@ -0,0 +1,253 @@ +Active Job Basics +================= + +This guide provides you with all you need to get started in creating, +enqueueing and executing background jobs. + +After reading this guide, you will know: + +* How to create jobs. +* How to enqueue jobs. +* How to run jobs in the background. +* How to send emails from your application async. + +-------------------------------------------------------------------------------- + +Introduction +------------ + +Active Job is a framework for declaring jobs and making them run on a variety +of queueing backends. These jobs can be everything from regularly scheduled +clean-ups, billing charges, or mailings. Anything that can be chopped up +into small units of work and run in parallel, really. + + +The Purpose of the Active Job +----------------------------- +The main point is to ensure that all Rails apps will have a job infrastructure +in place, even if it's in the form of an "immediate runner". We can then have +framework features and other gems build on top of that, without having to +worry about API differences between various job runners such as Delayed Job +and Resque. Picking your queuing backend becomes more of an operational concern, +then. And you'll be able to switch between them without having to rewrite your jobs. + + +Creating a Job +-------------- + +This section will provide a step-by-step guide to creating a job and enqueue it. + +### Create the Job + +Active Job provides a Rails generator to create jobs. The following will create a +job in app/jobs: + +```bash +$ bin/rails generate job guests_cleanup +create app/jobs/guests_cleanup_job.rb +``` + +You can also create a job that will run on a specific queue: + +```bash +$ bin/rails generate job guests_cleanup --queue urgent +create app/jobs/guests_cleanup_job.rb +``` + +As you can see, you can generate jobs just like you use other generators with +Rails. + +If you don't want to use a generator, you could create your own file inside of +app/jobs, just make sure that it inherits from `ActiveJob::Base`. + +Here's how a job looks like: + +```ruby +class GuestsCleanupJob < ActiveJob::Base + queue_as :default + + def perform + # Do something later + end +end +``` + +### Enqueue the Job + +Enqueue a job like so: + +```ruby +MyJob.enqueue record # Enqueue a job to be performed as soon the queueing system is free. +``` + +```ruby +MyJob.enqueue_at Date.tomorrow.noon, record # Enqueue a job to be performed tomorrow at noon. +``` + +```ruby +MyJob.enqueue_in 1.week, record # Enqueue a job to be performed 1 week from now. +``` + +That's it! + + +Job Execution +------------- + +If not adapter is set, the job is immediately executed. + +### Backends + +Active Job has adapters for the following queueing backends: + +* [Backburner](https://github.com/nesquena/backburner) +* [Delayed Job](https://github.com/collectiveidea/delayed_job) +* [Qu](https://github.com/bkeepers/qu) +* [Que](https://github.com/chanks/que) +* [QueueClassic](https://github.com/ryandotsmith/queue_classic) +* [Resque 1.x](https://github.com/resque/resque) +* [Sidekiq](https://github.com/mperham/sidekiq) +* [Sneakers](https://github.com/jondot/sneakers) +* [Sucker Punch](https://github.com/brandonhilkert/sucker_punch) + +#### Backends Features + +| | Async | Queues | Delayed | Priorities | Timeout | Retries | +|-----------------------|-------|---------|---------|-------------|---------|---------| +| **Backburner** | Yes | Yes | Yes | Yes | Job | Global | +| **Delayed Job** | Yes | Yes | Yes | Job | Global | Global | +| **Que** | Yes | Yes | Yes | Job | No | Job | +| **Queue Classic** | Yes | Yes | Gem | No | No | No | +| **Resque** | Yes | Yes | Gem | Queue | Global | ? | +| **Sidekiq** | Yes | Yes | Yes | Queue | No | Job | +| **Sneakers** | Yes | Yes | No | Queue | Queue | No | +| **Sucker Punch** | Yes | Yes | Yes | No | No | No | +| **Active Job** | Yes | Yes | WIP | No | No | No | +| **Active Job Inline** | No | Yes | N/A | N/A | N/A | N/A | + +### Change Backends + +You can easy change your adapter: + +```ruby +# be sure to have the adapter gem in your Gemfile and follow the adapter specific +# installation and deployment instructions +YourApp::Application.config.active_job.queue_adapter = :sidekiq +``` + +Queues +------ + +Most of the adapters supports multiple queues. With Active Job you can schedule the job +to run on a specific queue: + +```ruby +class GuestsCleanupJob < ActiveJob::Base + queue_as :low_priority + #.... +end +``` + +NOTE: Make sure your queueing backend "listens" on your queue name. For some backends +you need to specify the queues to listen to. + + +Callbacks +--------- + +Active Job provides hooks during the lifecycle of a job. Callbacks allows you to trigger +logic during the lifecycle of a job. + +### Available callbacks + +* before_enqueue +* around_enqueue +* after_enqueue +* before_perform +* around_perform +* after_perform + +### Usage + +```ruby +class GuestsCleanupJob < ActiveJob::Base + queue_as :default + + before_enqueue do |job| + # do somthing with the job instance + end + + around_perform do |job, block| + # do something before perform + block.call + # do something after perform + end + + def perform + # Do something later + end +end +``` + +ActionMailer +------------ +One of the most common jobs in a modern web application is sending emails outside +of the request-response cycle, so the user doesn't have to wait on it. Active Job +is integrated with Action Mailer so you can easily send emails async: + +```ruby +# Instead of the classic +UserMailer.welcome(@user).deliver + +# use #deliver later to send the email async +UserMailer.welcome(@user).deliver_later +``` + +GlobalID +-------- +Active Job supports GlobalID for parameters. This makes it possible +to pass live Active Record objects to your job instead of class/id pairs, which +you then have to manually deserialize. Before, jobs would look like this: + +```ruby +class TrashableCleanupJob + def perform(trashable_class, trashable_id, depth) + trashable = trashable_class.constantize.find(trashable_id) + trashable.cleanup(depth) + end +end +``` + +Now you can simply do: + +```ruby +class TrashableCleanupJob + def perform(trashable, depth) + trashable.cleanup(depth) + end +end +``` + +This works with any class that mixes in ActiveModel::GlobalIdentification, which +by default has been mixed into Active Model classes. + + +Exceptions +---------- +Active Job provides a way to catch exceptions raised during the execution of the +job: + +```ruby + +class GuestsCleanupJob < ActiveJob::Base + queue_as :default + + rescue_from(ActiveRecord:NotFound) do |exception| + # do something with the exception + end + + def perform + # Do something later + end +end +``` diff --git a/guides/source/active_record_querying.md b/guides/source/active_record_querying.md index 35467fe95b..f9b46286c1 100644 --- a/guides/source/active_record_querying.md +++ b/guides/source/active_record_querying.md @@ -1464,7 +1464,7 @@ Client.connection.select_all("SELECT first_name, created_at FROM clients WHERE i ### `pluck` -`pluck` can be used to query a single or multiple columns from the underlying table of a model. It accepts a list of column names as argument and returns an array of values of the specified columns with the corresponding data type. +`pluck` can be used to query single or multiple columns from the underlying table of a model. It accepts a list of column names as argument and returns an array of values of the specified columns with the corresponding data type. ```ruby Client.where(active: true).pluck(:id) diff --git a/guides/source/caching_with_rails.md b/guides/source/caching_with_rails.md index 0902e347e2..d0f3a596fe 100644 --- a/guides/source/caching_with_rails.md +++ b/guides/source/caching_with_rails.md @@ -353,7 +353,12 @@ Instead of an options hash, you can also simply pass in a model, Rails will use class ProductsController < ApplicationController def show @product = Product.find(params[:id]) - respond_with(@product) if stale?(@product) + + if stale?(@product) + respond_to do |wants| + # ... normal response processing + end + end end end ``` diff --git a/guides/source/command_line.md b/guides/source/command_line.md index 3a78c3bb3f..a074b849c6 100644 --- a/guides/source/command_line.md +++ b/guides/source/command_line.md @@ -149,8 +149,6 @@ $ bin/rails generate controller Greetings hello create test/controllers/greetings_controller_test.rb invoke helper create app/helpers/greetings_helper.rb - invoke test_unit - create test/helpers/greetings_helper_test.rb invoke assets invoke coffee create app/assets/javascripts/greetings.js.coffee @@ -236,8 +234,6 @@ $ bin/rails generate scaffold HighScore game:string score:integer create test/controllers/high_scores_controller_test.rb invoke helper create app/helpers/high_scores_helper.rb - invoke test_unit - create test/helpers/high_scores_helper_test.rb invoke jbuilder create app/views/high_scores/index.json.jbuilder create app/views/high_scores/show.json.jbuilder diff --git a/guides/source/configuring.md b/guides/source/configuring.md index 13020fb286..801cef5ca6 100644 --- a/guides/source/configuring.md +++ b/guides/source/configuring.md @@ -137,7 +137,7 @@ numbers. New applications filter out passwords by adding the following `config.f * `config.assets.enabled` a flag that controls whether the asset pipeline is enabled. It is set to true by default. -*`config.assets.raise_runtime_errors`* Set this flag to `true` to enable additional runtime error checking. Recommended in `config/environments/development.rb` to minimize unexpected behavior when deploying to `production`. +* `config.assets.raise_runtime_errors`* Set this flag to `true` to enable additional runtime error checking. Recommended in `config/environments/development.rb` to minimize unexpected behavior when deploying to `production`. * `config.assets.compress` a flag that enables the compression of compiled assets. It is explicitly set to true in `config/environments/production.rb`. @@ -151,6 +151,8 @@ pipeline is enabled. It is set to true by default. * `config.assets.prefix` defines the prefix where assets are served from. Defaults to `/assets`. +* `config.assets.manifest` defines the full path to be used for the asset precompiler's manifest file. Defaults to a file named `manifest-<random>.json` in the `config.assets.prefix` directory within the public folder. + * `config.assets.digest` enables the use of MD5 fingerprints in asset names. Set to `true` by default in `production.rb`. * `config.assets.debug` disables the concatenation and compression of assets. Set to `true` by default in `development.rb`. @@ -996,3 +998,24 @@ If you get the above error, you might want to increase the size of connection pool by incrementing the `pool` option in `database.yml` NOTE. If you are running in a multi-threaded environment, there could be a chance that several threads may be accessing multiple connections simultaneously. So depending on your current request load, you could very well have multiple threads contending for a limited amount of connections. + + +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 + ``` + +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 + ``` diff --git a/guides/source/contributing_to_ruby_on_rails.md b/guides/source/contributing_to_ruby_on_rails.md index 0b05725623..8bc4b10591 100644 --- a/guides/source/contributing_to_ruby_on_rails.md +++ b/guides/source/contributing_to_ruby_on_rails.md @@ -397,7 +397,7 @@ inside, just indent it with 4 spaces: class ArticlesController def index - respond_with Article.limit(10) + render json: Article.limit(10) end end diff --git a/guides/source/development_dependencies_install.md b/guides/source/development_dependencies_install.md index b134c9d2d0..54b4230e16 100644 --- a/guides/source/development_dependencies_install.md +++ b/guides/source/development_dependencies_install.md @@ -100,7 +100,7 @@ For FreeBSD users, you're done with: Or compile the `databases/sqlite3` port. -Get a recent version of [Bundler](http://gembundler.com/) +Get a recent version of [Bundler](http://bundler.io/) ```bash $ gem install bundler diff --git a/guides/source/documents.yaml b/guides/source/documents.yaml index 82e248ee38..562c65dc0e 100644 --- a/guides/source/documents.yaml +++ b/guides/source/documents.yaml @@ -75,6 +75,10 @@ url: action_mailer_basics.html description: This guide describes how to use Action Mailer to send and receive emails. - + name: Active Job Basics + url: active_job_basics.html + description: This guide provides you with all you need to get started in creating, enqueueing and executing background jobs. + - name: Testing Rails Applications url: testing.html work_in_progress: true diff --git a/guides/source/engines.md b/guides/source/engines.md index a5f8ee27b8..24548a5b01 100644 --- a/guides/source/engines.md +++ b/guides/source/engines.md @@ -136,7 +136,7 @@ following to the dummy application's routes file at `test/dummy/config/routes.rb`: ```ruby -mount Blorgh::Engine, at: "blorgh" +mount Blorgh::Engine => "/blorgh" ``` ### Inside an Engine @@ -173,7 +173,7 @@ Within `lib/blorgh/engine.rb` is the base class for the engine: ```ruby module Blorgh - class Engine < Rails::Engine + class Engine < ::Rails::Engine isolate_namespace Blorgh end end @@ -322,8 +322,6 @@ invoke test_unit create test/controllers/blorgh/articles_controller_test.rb invoke helper create app/helpers/blorgh/articles_helper.rb -invoke test_unit -create test/helpers/blorgh/articles_helper_test.rb invoke assets invoke js create app/assets/javascripts/blorgh/articles.js @@ -560,8 +558,6 @@ invoke test_unit create test/controllers/blorgh/comments_controller_test.rb invoke helper create app/helpers/blorgh/comments_helper.rb -invoke test_unit -create test/helpers/blorgh/comments_helper_test.rb invoke assets invoke js create app/assets/javascripts/blorgh/comments.js diff --git a/guides/source/generators.md b/guides/source/generators.md index be64f1638d..2b39ea66d8 100644 --- a/guides/source/generators.md +++ b/guides/source/generators.md @@ -8,6 +8,7 @@ After reading this guide, you will know: * How to see which generators are available in your application. * How to create a generator using templates. * How Rails searches for generators before invoking them. +* How Rails internally generates Rails code from the templates. * How to customize your scaffold by creating new generators. * How to customize your scaffold by changing generator templates. * How to use fallbacks to avoid overwriting a huge set of generators. @@ -191,8 +192,6 @@ $ bin/rails generate scaffold User name:string create test/controllers/users_controller_test.rb invoke helper create app/helpers/users_helper.rb - invoke test_unit - create test/helpers/users_helper_test.rb invoke jbuilder create app/views/users/index.json.jbuilder create app/views/users/show.json.jbuilder @@ -342,6 +341,18 @@ end If you generate another resource, you can see that we get exactly the same result! This is useful if you want to customize your scaffold templates and/or layout by just creating `edit.html.erb`, `index.html.erb` and so on inside `lib/templates/erb/scaffold`. +Many scaffold templates in Rails are written in ERB tags which need to be escaped, so that the output is valid ERB code. For example, + +```ruby +<%%= stylesheet_include_tag :application %> +``` + +when passed through the generator, would generate the following output. + +```ruby +<%= stylesheet_include_tag :application %> +``` + Adding Generators Fallbacks --------------------------- @@ -387,8 +398,6 @@ $ bin/rails generate scaffold Comment body:text create test/controllers/comments_controller_test.rb invoke my_helper create app/helpers/comments_helper.rb - invoke shoulda - create test/helpers/comments_helper_test.rb invoke jbuilder create app/views/comments/index.json.jbuilder create app/views/comments/show.json.jbuilder diff --git a/guides/source/getting_started.md b/guides/source/getting_started.md index 2ea415bbfe..964bb30856 100644 --- a/guides/source/getting_started.md +++ b/guides/source/getting_started.md @@ -191,14 +191,15 @@ following in the `blog` directory: $ bin/rails server ``` -TIP: Compiling CoffeeScript to JavaScript requires a JavaScript runtime and the -absence of a runtime will give you an `execjs` error. Usually Mac OS X and -Windows come with a JavaScript runtime installed. Rails adds the `therubyracer` -gem to the generated `Gemfile` in a commented line for new apps and you can -uncomment if you need it. `therubyrhino` is the recommended runtime for JRuby -users and is added by default to the `Gemfile` in apps generated under JRuby. -You can investigate about all the supported runtimes at -[ExecJS](https://github.com/sstephenson/execjs#readme). +TIP: Compiling CoffeeScript and JavaScript asset compression requires you +have a JavaScript runtime available on your system, in the absence +of a runtime you will see an `execjs` error during asset compilation. +Usually Mac OS X and Windows come with a JavaScript runtime installed. +Rails adds the `therubyracer` gem to the generated `Gemfile` in a +commented line for new apps and you can uncomment if you need it. +`therubyrhino` is the recommended runtime for JRuby users and is added by +default to the `Gemfile` in apps generated under JRuby. You can investigate +all the supported runtimes at [ExecJS](https://github.com/sstephenson/execjs#readme). This will fire up WEBrick, a web server distributed with Ruby by default. To see your application in action, open a browser window and navigate to @@ -256,8 +257,6 @@ invoke test_unit create test/controllers/welcome_controller_test.rb invoke helper create app/helpers/welcome_helper.rb -invoke test_unit -create test/helpers/welcome_helper_test.rb invoke assets invoke coffee create app/assets/javascripts/welcome.js.coffee @@ -1636,7 +1635,6 @@ This creates six files and one empty directory: | app/views/comments/ | Views of the controller are stored here | | test/controllers/comments_controller_test.rb | The test for the controller | | app/helpers/comments_helper.rb | A view helper file | -| test/helpers/comments_helper_test.rb | The test for the helper | | app/assets/javascripts/comment.js.coffee | CoffeeScript for the controller | | app/assets/stylesheets/comment.css.scss | Cascading style sheet for the controller | diff --git a/guides/source/layouts_and_rendering.md b/guides/source/layouts_and_rendering.md index 4bc07222a8..60571750a1 100644 --- a/guides/source/layouts_and_rendering.md +++ b/guides/source/layouts_and_rendering.md @@ -903,7 +903,7 @@ You can also specify multiple videos to play by passing an array of videos to th This will produce: ```erb -<video><source src="trailer.ogg" /><source src="movie.ogg" /></video> +<video><source src="/videos/trailer.ogg" /><source src="/videos/trailer.flv" /></video> ``` #### Linking to Audio Files with the `audio_tag` diff --git a/guides/source/plugins.md b/guides/source/plugins.md index a35648d341..dbccfd4021 100644 --- a/guides/source/plugins.md +++ b/guides/source/plugins.md @@ -45,7 +45,7 @@ $ bin/rails plugin new yaffle See usage and options by asking for help: ```bash -$ bin/rails plugin --help +$ bin/rails plugin new --help ``` Testing Your Newly Generated Plugin @@ -57,7 +57,7 @@ You can navigate to the directory that contains the plugin, run the `bundle inst You should see: ```bash - 2 tests, 2 assertions, 0 failures, 0 errors, 0 skips + 1 runs, 1 assertions, 0 failures, 0 errors, 0 skips ``` This will tell you that everything got generated properly and you are ready to start adding functionality. @@ -85,9 +85,9 @@ Run `rake` to run the test. This test should fail because we haven't implemented ```bash 1) Error: - test_to_squawk_prepends_the_word_squawk(CoreExtTest): - NoMethodError: undefined method `to_squawk' for [Hello World](String) - test/core_ext_test.rb:5:in `test_to_squawk_prepends_the_word_squawk' + 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' ``` Great - now you are ready to start development. @@ -118,7 +118,7 @@ end To test that your method does what it says it does, run the unit tests with `rake` from your plugin directory. ```bash - 3 tests, 3 assertions, 0 failures, 0 errors, 0 skips + 2 runs, 2 assertions, 0 failures, 0 errors, 0 skips ``` To see this in action, change to the test/dummy directory, fire up a console and start squawking: @@ -196,16 +196,16 @@ When you run `rake`, you should see the following: ``` 1) Error: - test_a_hickwalls_yaffle_text_field_should_be_last_squawk(ActsAsYaffleTest): + ActsAsYaffleTest#test_a_hickwalls_yaffle_text_field_should_be_last_squawk: NameError: uninitialized constant ActsAsYaffleTest::Hickwall - test/acts_as_yaffle_test.rb:6:in `test_a_hickwalls_yaffle_text_field_should_be_last_squawk' + /path/to/yaffle/test/acts_as_yaffle_test.rb:6:in `test_a_hickwalls_yaffle_text_field_should_be_last_squawk' 2) Error: - test_a_wickwalls_yaffle_text_field_should_be_last_tweet(ActsAsYaffleTest): + ActsAsYaffleTest#test_a_wickwalls_yaffle_text_field_should_be_last_tweet: NameError: uninitialized constant ActsAsYaffleTest::Wickwall - test/acts_as_yaffle_test.rb:10:in `test_a_wickwalls_yaffle_text_field_should_be_last_tweet' + /path/to/yaffle/test/acts_as_yaffle_test.rb:10:in `test_a_wickwalls_yaffle_text_field_should_be_last_tweet' - 5 tests, 3 assertions, 0 failures, 2 errors, 0 skips + 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. @@ -270,18 +270,18 @@ You can then return to the root directory (`cd ../..`) of your plugin and rerun ``` 1) Error: - test_a_hickwalls_yaffle_text_field_should_be_last_squawk(ActsAsYaffleTest): - NoMethodError: undefined method `yaffle_text_field' for #<Class:0x000001016661b8> - /Users/xxx/.rvm/gems/ruby-1.9.2-p136@xxx/gems/activerecord-3.0.3/lib/active_record/base.rb:1008:in `method_missing' - test/acts_as_yaffle_test.rb:5:in `test_a_hickwalls_yaffle_text_field_should_be_last_squawk' + 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' 2) Error: - test_a_wickwalls_yaffle_text_field_should_be_last_tweet(ActsAsYaffleTest): - NoMethodError: undefined method `yaffle_text_field' for #<Class:0x00000101653748> - Users/xxx/.rvm/gems/ruby-1.9.2-p136@xxx/gems/activerecord-3.0.3/lib/active_record/base.rb:1008:in `method_missing' - test/acts_as_yaffle_test.rb:9:in `test_a_wickwalls_yaffle_text_field_should_be_last_tweet' + 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' - 5 tests, 3 assertions, 0 failures, 2 errors, 0 skips + 4 runs, 2 assertions, 0 failures, 2 errors, 0 skips ``` @@ -312,7 +312,7 @@ ActiveRecord::Base.send :include, Yaffle::ActsAsYaffle When you run `rake`, you should see the tests all pass: ```bash - 5 tests, 5 assertions, 0 failures, 0 errors, 0 skips + 4 runs, 4 assertions, 0 failures, 0 errors, 0 skips ``` ### Add an Instance Method @@ -386,7 +386,7 @@ ActiveRecord::Base.send :include, Yaffle::ActsAsYaffle Run `rake` one final time and you should see: ``` - 7 tests, 7 assertions, 0 failures, 0 errors, 0 skips + 6 runs, 6 assertions, 0 failures, 0 errors, 0 skips ``` NOTE: The use of `write_attribute` to write to the field in model is just one example of how a plugin can interact with the model, and will not always be the right method to use. For example, you could also use: @@ -440,5 +440,5 @@ $ bin/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://docs.rubygems.org/read/chapter/20) +* [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 0bd608c007..6512b14e60 100644 --- a/guides/source/rails_application_templates.md +++ b/guides/source/rails_application_templates.md @@ -38,9 +38,11 @@ generate(:scaffold, "person name:string") route "root to: 'people#index'" rake("db:migrate") -git :init -git add: "." -git commit: %Q{ -m 'Initial commit' } +after_bundle do + git :init + git add: "." + git commit: %Q{ -m 'Initial commit' } +end ``` The following sections outline the primary methods provided by the API: @@ -228,6 +230,22 @@ git add: "." git commit: "-a -m 'Initial commit'" ``` +### after_bundle(&block) + +Registers a callback to be executed after the gems are bundled and binstubs +are generated. Useful for all generated files to version control: + +```ruby +after_bundle do + git :init + git add: '.' + git commit: "-a -m 'Initial commit'" +end +``` + +The callbacks gets executed even if `--skip-bundle` and/or `--skip-spring` has +been passed. + Advanced Usage -------------- diff --git a/guides/source/ruby_on_rails_guides_guidelines.md b/guides/source/ruby_on_rails_guides_guidelines.md index f0230b428b..6206b3c715 100644 --- a/guides/source/ruby_on_rails_guides_guidelines.md +++ b/guides/source/ruby_on_rails_guides_guidelines.md @@ -13,17 +13,17 @@ After reading this guide, you will know: Markdown ------- -Guides are written in [GitHub Flavored Markdown](https://help.github.com/articles/github-flavored-markdown). There is comprehensive [documentation for Markdown](http://daringfireball.net/projects/markdown/syntax), a [cheatsheet](http://daringfireball.net/projects/markdown/basics). +Guides are written in [GitHub Flavored Markdown](https://help.github.com/articles/github-flavored-markdown). There is comprehensive [documentation for Markdown](http://daringfireball.net/projects/markdown/syntax), as well as a [cheatsheet](http://daringfireball.net/projects/markdown/basics). Prologue -------- -Each guide should start with motivational text at the top (that's the little introduction in the blue area). The prologue should tell the reader what the guide is about, and what they will learn. See for example the [Routing Guide](routing.html). +Each guide should start with motivational text at the top (that's the little introduction in the blue area). The prologue should tell the reader what the guide is about, and what they will learn. As an example, see the [Routing Guide](routing.html). -Titles +Headings ------ -The title of every guide uses `h1`; guide sections use `h2`; subsections `h3`; etc. However, the generated HTML output will have the heading tag starting from `<h2>`. +The title of every guide uses an `h1` heading; guide sections use `h2` headings; subsections use `h3` headings; etc. Note that the generated HTML output will use heading tags starting with `<h2>`. ``` Guide Title @@ -35,14 +35,14 @@ Section ### Sub Section ``` -Capitalize all words except for internal articles, prepositions, conjunctions, and forms of the verb to be: +When writing headings, capitalize all words except for prepositions, conjunctions, internal articles, and forms of the verb "to be": ``` #### Middleware Stack is an Array #### When are Objects Saved? ``` -Use the same typography as in regular text: +Use the same inline formatting as regular text: ``` ##### The `:content_type` Option @@ -51,25 +51,23 @@ Use the same typography as in regular text: API Documentation Guidelines ---------------------------- -The guides and the API should be coherent and consistent where appropriate. Please have a look at these particular sections of the [API Documentation Guidelines](api_documentation_guidelines.html): +The guides and the API should be coherent and consistent where appropriate. In particular, these sections of the [API Documentation Guidelines](api_documentation_guidelines.html) also apply to the guides: * [Wording](api_documentation_guidelines.html#wording) * [Example Code](api_documentation_guidelines.html#example-code) -* [Filenames](api_documentation_guidelines.html#filenames) +* [Filenames](api_documentation_guidelines.html#file-names) * [Fonts](api_documentation_guidelines.html#fonts) -Those guidelines apply also to guides. - HTML Guides ----------- Before generating the guides, make sure that you have the latest version of Bundler installed on your system. As of this writing, you must install Bundler 1.3.5 on your device. -To install the latest version of Bundler, simply run the `gem install bundler` command +To install the latest version of Bundler, run `gem install bundler`. ### Generation -To generate all the guides, just `cd` into the `guides` directory, run `bundle install` and execute: +To generate all the guides, just `cd` into the `guides` directory, run `bundle install`, and execute: ``` bundle exec rake guides:generate diff --git a/guides/source/security.md b/guides/source/security.md index ebfcc5bdd0..125dd82666 100644 --- a/guides/source/security.md +++ b/guides/source/security.md @@ -118,9 +118,9 @@ It works like this: * A user receives credits, the amount is stored in a session (which is a bad idea anyway, but we'll do this for demonstration purposes). * The user buys something. -* Their new, lower credit will be stored in the session. -* The dark side of the user forces them to take the cookie from the first step (which they copied) and replace the current cookie in the browser. -* The user has their credit back. +* The new adjusted credit value is stored in the session. +* The user takes the cookie from the first step (which they previously copied) and replaces the current cookie in the browser. +* The user has their original credit back. Including a nonce (a random value) in the session solves replay attacks. A nonce is valid only once, and the server has to keep track of all the valid nonces. It gets even more complicated if you have several application servers (mongrels). Storing nonces in a database table would defeat the entire purpose of CookieStore (avoiding accessing the database). @@ -847,7 +847,7 @@ It is recommended to _use RedCloth in combination with a whitelist input filter_ NOTE: _The same security precautions have to be taken for Ajax actions as for "normal" ones. There is at least one exception, however: The output has to be escaped in the controller already, if the action doesn't render a view._ -If you use the [in_place_editor plugin](http://dev.rubyonrails.org/browser/plugins/in_place_editing), or actions that return a string, rather than rendering a view, _you have to escape the return value in the action_. Otherwise, if the return value contains a XSS string, the malicious code will be executed upon return to the browser. Escape any input value using the h() method. +If you use the [in_place_editor plugin](https://rubygems.org/gems/in_place_editing), or actions that return a string, rather than rendering a view, _you have to escape the return value in the action_. Otherwise, if the return value contains a XSS string, the malicious code will be executed upon return to the browser. Escape any input value using the h() method. ### Command Line Injection diff --git a/guides/source/testing.md b/guides/source/testing.md index 4ded7818b5..2ecd560a87 100644 --- a/guides/source/testing.md +++ b/guides/source/testing.md @@ -605,13 +605,13 @@ end Testing the response to your request by asserting the presence of key HTML elements and their content is a useful way to test the views of your application. The `assert_select` assertion allows you to do this by using a simple yet powerful syntax. -NOTE: You may find references to `assert_tag` in other documentation, but this is now deprecated in favor of `assert_select`. +NOTE: You may find references to `assert_tag` in other documentation. This has been removed in 4.2. Use `assert_select` instead. There are two forms of `assert_select`: -`assert_select(selector, [equality], [message])` ensures that the equality condition is met on the selected elements through the selector. The selector may be a CSS selector expression (String), an expression with substitution values, or an `HTML::Selector` object. +`assert_select(selector, [equality], [message])` ensures that the equality condition is met on the selected elements through the selector. The selector may be a CSS selector expression (String) or an expression with substitution values. -`assert_select(element, selector, [equality], [message])` ensures that the equality condition is met on all the selected elements through the selector starting from the _element_ (instance of `HTML::Node`) and its descendants. +`assert_select(element, selector, [equality], [message])` ensures that the equality condition is met on all the selected elements through the selector starting from the _element_ (instance of `Nokogiri::XML::Node` or `Nokogiri::XML::NodeSet`) and its descendants. For example, you could verify the contents on the title element in your response with: @@ -641,7 +641,7 @@ assert_select "ol" do end ``` -The `assert_select` assertion is quite powerful. For more advanced usage, refer to its [documentation](http://api.rubyonrails.org/classes/ActionDispatch/Assertions/SelectorAssertions.html). +The `assert_select` 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 @@ -1014,17 +1014,9 @@ Testing helpers 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. Rails provides a generator which -generates both the helper and the test file: +located under the `test/helpers` directory. -```bash -$ bin/rails generate helper User - create app/helpers/user_helper.rb - invoke test_unit - create test/helpers/user_helper_test.rb -``` - -The generated test file contains the following code: +A helper test looks like so: ```ruby require 'test_helper' @@ -1057,7 +1049,6 @@ The built-in `minitest` based testing is not the only way to test Rails applicat * [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. -* [Machinist](https://github.com/notahat/machinist/tree/master), another 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. diff --git a/guides/source/upgrading_ruby_on_rails.md b/guides/source/upgrading_ruby_on_rails.md index b3e4505fc0..4b421633e2 100644 --- a/guides/source/upgrading_ruby_on_rails.md +++ b/guides/source/upgrading_ruby_on_rails.md @@ -54,10 +54,75 @@ NOTE: This section is a work in progress. ### Serialized attributes -When assigning `nil` to a serialized attribute, it will be saved to the database +When using a custom coder (e.g. `serialize :metadata, JSON`), +assigning `nil` to a serialized attribute will save it to the database as `NULL` instead of passing the `nil` value through the coder (e.g. `"null"` when using the `JSON` coder). +### `after_bundle` in Rails templates + +If you have a Rails template that adds all the files in version control, it +fails to add the generated binstubs because it gets executed before Bundler: + +```ruby +# template.rb +generate(:scaffold, "person name:string") +route "root to: 'people#index'" +rake("db:migrate") + +git :init +git add: "." +git commit: %Q{ -m 'Initial commit' } +``` + +You can now wrap the `git` calls in an `after_bundle` block. It will be run +after the binstubs have been generated. + +```ruby +# template.rb +generate(:scaffold, "person name:string") +route "root to: 'people#index'" +rake("db:migrate") + +after_bundle do + git :init + git add: "." + git commit: %Q{ -m 'Initial commit' } +end +``` + +### Rails Html Sanitizer + +There's a new choice for sanitizing HTML fragments in your applications. The +venerable html-scanner approach is now officially being deprecated in favor of +[`Rails Html Sanitizer`](https://github.com/rails/rails-html-sanitizer). + +This means the methods `sanitize`, `sanitize_css`, `strip_tags` and +`strip_links` are backed by a new implementation. + +In the next major Rails version `Rails Html Sanitizer` will be the default +sanitizer. It already is for new applications. + +Include this in your Gemfile to try it out today: + +```ruby +gem 'rails-html-sanitizer' +``` + +This new sanitizer uses [Loofah](https://github.com/flavorjones/loofah) internally. Loofah in turn uses Nokogiri, which +wraps XML parsers written in both C and Java, so sanitization should be faster +no matter which Ruby version you run. + +The new version updates `sanitize`, so it can take a `Loofah::Scrubber` for +powerful scrubbing. +[See some examples of scrubbers here](https://github.com/flavorjones/loofah#loofahscrubber). + +Two new scrubbers have also been added: `PermitScrubber` and `TargetScrubber`. +Read the [gem's readme](https://github.com/rails/rails-html-sanitizer) for more information. + +The documentation for `PermitScrubber` and `TargetScrubber` explains how you +can gain complete control over when and how elements should be stripped. + Upgrading from Rails 4.0 to Rails 4.1 ------------------------------------- @@ -132,7 +197,7 @@ secrets, you need to: If your test helper contains a call to `ActiveRecord::Migration.check_pending!` this can be removed. The check -is now done automatically when you `require 'test_help'`, although +is now done automatically when you `require 'rails/test_help'`, although leaving this line in your helper is not harmful in any way. ### Cookies serializer @@ -532,7 +597,7 @@ being used, you can update your form to use the `PUT` method instead: <%= form_for [ :update_name, @user ], method: :put do |f| %> ``` -For more on PATCH and why this change was made, see [this post](http://weblog.rubyonrails.org/2012/2/25/edge-rails-patch-is-the-new-primary-http-method-for-updates/) +For more on PATCH and why this change was made, see [this post](http://weblog.rubyonrails.org/2012/2/26/edge-rails-patch-is-the-new-primary-http-method-for-updates/) on the Rails blog. #### A note about media types @@ -592,6 +657,9 @@ Rails 4.0 no longer supports loading plugins from `vendor/plugins`. You must rep * Rails 4.0 has changed `serialized_attributes` and `attr_readonly` to class methods only. You shouldn't use instance methods since it's now deprecated. You should change them to use class methods, e.g. `self.serialized_attributes` to `self.class.serialized_attributes`. +* When using the default coder, assigning `nil` to a serialized attribute will save it +to the database as `NULL` instead of passing the `nil` value through YAML (`"--- \n...\n"`). + * Rails 4.0 has removed `attr_accessible` and `attr_protected` feature in favor of Strong Parameters. You can use the [Protected Attributes gem](https://github.com/rails/protected_attributes) for a smooth upgrade path. * If you are not using Protected Attributes, you can remove any options related to |