diff options
Diffstat (limited to 'guides/source')
32 files changed, 818 insertions, 205 deletions
diff --git a/guides/source/2_2_release_notes.md b/guides/source/2_2_release_notes.md index 522f628a7e..b11aaa15a8 100644 --- a/guides/source/2_2_release_notes.md +++ b/guides/source/2_2_release_notes.md @@ -1,7 +1,7 @@ Ruby on Rails 2.2 Release Notes =============================== -Rails 2.2 delivers a number of new and improved features. This list covers the major upgrades, but doesn't include every little bug fix and change. If you want to see everything, check out the [list of commits](http://github.com/rails/rails/commits/master) in the main Rails repository on GitHub. +Rails 2.2 delivers a number of new and improved features. This list covers the major upgrades, but doesn't include every little bug fix and change. If you want to see everything, check out the [list of commits](http://github.com/rails/rails/commits/2-2-stable) in the main Rails repository on GitHub. Along with Rails, 2.2 marks the launch of the [Ruby on Rails Guides](http://guides.rubyonrails.org/), the first results of the ongoing [Rails Guides hackfest](http://hackfest.rubyonrails.org/guide). This site will deliver high-quality documentation of the major features of Rails. diff --git a/guides/source/2_3_release_notes.md b/guides/source/2_3_release_notes.md index 52eeb4c2bc..20566c9155 100644 --- a/guides/source/2_3_release_notes.md +++ b/guides/source/2_3_release_notes.md @@ -1,7 +1,7 @@ Ruby on Rails 2.3 Release Notes =============================== -Rails 2.3 delivers a variety of new and improved features, including pervasive Rack integration, refreshed support for Rails Engines, nested transactions for Active Record, dynamic and default scopes, unified rendering, more efficient routing, application templates, and quiet backtraces. This list covers the major upgrades, but doesn't include every little bug fix and change. If you want to see everything, check out the [list of commits](http://github.com/rails/rails/commits/master) in the main Rails repository on GitHub or review the `CHANGELOG` files for the individual Rails components. +Rails 2.3 delivers a variety of new and improved features, including pervasive Rack integration, refreshed support for Rails Engines, nested transactions for Active Record, dynamic and default scopes, unified rendering, more efficient routing, application templates, and quiet backtraces. This list covers the major upgrades, but doesn't include every little bug fix and change. If you want to see everything, check out the [list of commits](http://github.com/rails/rails/commits/2-3-stable) in the main Rails repository on GitHub or review the `CHANGELOG` files for the individual Rails components. -------------------------------------------------------------------------------- diff --git a/guides/source/3_0_release_notes.md b/guides/source/3_0_release_notes.md index aec3a383d6..8122d6c235 100644 --- a/guides/source/3_0_release_notes.md +++ b/guides/source/3_0_release_notes.md @@ -15,7 +15,7 @@ Even if you don't give a hoot about any of our internal cleanups, Rails 3.0 is g On top of all that, we've tried our best to deprecate the old APIs with nice warnings. That means that you can move your existing application to Rails 3 without immediately rewriting all your old code to the latest best practices. -These release notes cover the major upgrades, but don't include every little bug fix and change. Rails 3.0 consists of almost 4,000 commits by more than 250 authors! If you want to see everything, check out the [list of commits](http://github.com/rails/rails/commits/master) in the main Rails repository on GitHub. +These release notes cover the major upgrades, but don't include every little bug fix and change. Rails 3.0 consists of almost 4,000 commits by more than 250 authors! If you want to see everything, check out the [list of commits](http://github.com/rails/rails/commits/3-0-stable) in the main Rails repository on GitHub. -------------------------------------------------------------------------------- diff --git a/guides/source/3_1_release_notes.md b/guides/source/3_1_release_notes.md index 7626296e7d..b7ed285b96 100644 --- a/guides/source/3_1_release_notes.md +++ b/guides/source/3_1_release_notes.md @@ -8,7 +8,10 @@ Highlights in Rails 3.1: * Assets Pipeline * jQuery as the default JavaScript library -This release notes cover the major changes, but don't include every little bug fix and change. If you want to see everything, check out the [list of commits](https://github.com/rails/rails/commits/master) in the main Rails repository on GitHub. +These release notes cover only the major changes. To learn about various bug +fixes and changes, please refer to the change logs or check out the [list of +commits](https://github.com/rails/rails/commits/3-1-stable) in the main Rails +repository on GitHub. -------------------------------------------------------------------------------- diff --git a/guides/source/3_2_release_notes.md b/guides/source/3_2_release_notes.md index 2416e1a228..c5db0262e9 100644 --- a/guides/source/3_2_release_notes.md +++ b/guides/source/3_2_release_notes.md @@ -8,7 +8,10 @@ Highlights in Rails 3.2: * Automatic Query Explains * Tagged Logging -These release notes cover the major changes, but do not include each bug-fix and changes. If you want to see everything, check out the [list of commits](https://github.com/rails/rails/commits/3-2-stable) in the main Rails repository on GitHub. +These release notes cover only the major changes. To learn about various bug +fixes and changes, please refer to the change logs or check out the [list of +commits](https://github.com/rails/rails/commits/3-2-stable) in the main Rails +repository on GitHub. -------------------------------------------------------------------------------- diff --git a/guides/source/4_0_release_notes.md b/guides/source/4_0_release_notes.md index 19c690233c..1aaf5ebc94 100644 --- a/guides/source/4_0_release_notes.md +++ b/guides/source/4_0_release_notes.md @@ -8,7 +8,10 @@ Highlights in Rails 4.0: * Turbolinks * Russian Doll Caching -These release notes cover only the major changes. To know about various bug fixes and changes, please refer to the change logs or check out the [list of commits](https://github.com/rails/rails/commits/master) in the main Rails repository on GitHub. +These release notes cover only the major changes. To learn about various bug +fixes and changes, please refer to the change logs or check out the [list of +commits](https://github.com/rails/rails/commits/4-0-stable) in the main Rails +repository on GitHub. -------------------------------------------------------------------------------- diff --git a/guides/source/4_1_release_notes.md b/guides/source/4_1_release_notes.md index 5f4bdaaa8f..52a5acb75e 100644 --- a/guides/source/4_1_release_notes.md +++ b/guides/source/4_1_release_notes.md @@ -8,10 +8,10 @@ Highlights in Rails 4.1: * Action Pack variants * Action Mailer previews -These release notes cover only the major changes. To know about various bug -fixes and changes, please refer to the change logs or check out the -[list of commits](https://github.com/rails/rails/commits/master) in the main -Rails repository on GitHub. +These release notes cover only the major changes. To learn about various bug +fixes and changes, please refer to the change logs or check out the [list of +commits](https://github.com/rails/rails/commits/4-1-stable) in the main Rails +repository on GitHub. -------------------------------------------------------------------------------- diff --git a/guides/source/4_2_release_notes.md b/guides/source/4_2_release_notes.md index 12db528b91..ce29704a31 100644 --- a/guides/source/4_2_release_notes.md +++ b/guides/source/4_2_release_notes.md @@ -3,20 +3,28 @@ Ruby on Rails 4.2 Release Notes Highlights in Rails 4.2: -These release notes cover only the major changes. To know about various bug -fixes and changes, please refer to the change logs or check out the -[list of commits](https://github.com/rails/rails/commits/master) in the main -Rails repository on GitHub. +* Active Job, Action Mailer #deliver_later +* Adequate Record +* Web Console +* Foreign key support + +These release notes cover only the major changes. To learn about various bug +fixes and changes, please refer to the change logs or check out the [list of +commits](https://github.com/rails/rails/commits/master) in the main Rails +repository on GitHub. -------------------------------------------------------------------------------- +NOTE: This document is a work in progress, please help to improve this by sending +a [pull request](https://github.com/rails/rails/edit/master/guides/source/4_2_release_notes.md). + 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) guide. @@ -25,6 +33,41 @@ guide. Major Features -------------- +### Active Job, Action Mailer #deliver_later + +Active Job is a new framework in Rails 4.2. It is an adapter layer on top of +queuing systems like Resque, Delayed Job, Sidekiq, and more. You can write your +jobs to Active Job, and it'll run on all these queues with no changes. (It comes +pre-configured with an inline runner.) + +Building on top of Active Job, Action Mailer now comes with a #deliver_later +method, which adds your email to be sent as a job to a queue, so it doesn't +bog down the controller or model. + +The new GlobalID library makes it easy to pass Active Record objects to jobs by +serializing them in a generic form. This means you no longer have to manually +pack and unpack your Active Records by passing ids. Just give the job the +straight Active Record object, and it'll serialize it using GlobalID, and +deserialize it at run time. + +### Adequate Record + +Rails 4.2 comes with a performance improvement feature called Adequate Record +for Active Record. A lot of common queries are now up to twice as fast in Rails +4.2! + +TODO: add some technical details + +### Web Console + +New applications generated from Rails 4.2 now comes with the Web Console gem by +default. + +Web Console is an IRB console available in the browser. In development mode, you +can go to /console and do your work right there. It will also be made available +on all exception pages and allows you to jump between the different points in +the backtrace. + ### Foreign key support The migration DSL now supports adding and removing foreign keys. They are dumped @@ -69,11 +112,60 @@ Please refer to the [Changelog][railties] for detailed changes. ### Notable changes -* Introduced `--skip-gems` option in the app generator to skip gems such as - `turbolinks` and `coffee-rails` that does not have their own specific flags. +* Introduced `web-console` in the default application Gemfile. + ([Pull Request](https://github.com/rails/rails/pull/16532)) + +* 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 + ``` + + ([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 do 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. @@ -91,8 +183,23 @@ 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 +214,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 +226,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 +262,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 +281,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 +303,20 @@ 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)) + +* Deprecated `deliver` / `deliver!` in favour of `deliver_now` / `deliver_now!`. + ([Pull Request](https://github.com/rails/rails/pull/16582)) + ### 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)) @@ -220,6 +348,17 @@ for detailed changes. ### Deprecations +* Deprecated swallowing of errors inside `after_commit` and `after_rollback`. + ([Pull Request](https://github.com/rails/rails/pull/16537)) + +* Deprecated calling `DatabaseTasks.load_schema` without a connection. Use + `DatabaseTasks.load_schema_current` instead. + ([Commit](https://github.com/rails/rails/commit/f15cef67f75e4b52fd45655d7c6ab6b35623c608)) + +* Deprecated `Reflection#source_macro` without replacement as it is no longer + needed in Active Record. + ([Pull Request](https://github.com/rails/rails/pull/16373)) + * Deprecated broken support for automatic detection of counter caches on `has_many :through` associations. You should instead manually specify the counter cache on the `has_many` and `belongs_to` associations for the @@ -257,6 +396,13 @@ for detailed changes. ### Notable changes +* The PostgreSQL adapter now supports the `JSONB` datatype in PostgreSQL 9.4+. + ([Pull Request](https://github.com/rails/rails/pull/16220)) + +* The `#references` method in migrations now supports a `type` option for + specifying the type of the foreign key (e.g. `:uuid`). + ([Pull Request](https://github.com/rails/rails/pull/16231)) + * Added a `:required` option to singular associations, which defines a presence validation on the association. ([Pull Request](https://github.com/rails/rails/pull/16056)) @@ -320,13 +466,25 @@ Please refer to the [Changelog][active-model] for detailed changes. ### Removals * Removed deprecated `Validator#setup` without replacement. - ([Pull Request](https://github.com/rails/rails/pull/15617)) + ([Pull Request](https://github.com/rails/rails/pull/10716)) + +### Deprecations + +* Deprecated reset_#{attribute} in favor of restore_#{attribute}. + ([Pull Request](https://github.com/rails/rails/pull/16180)) + +* Deprecated ActiveModel::Dirty#reset_changes in favor of #clear_changes_information. + ([Pull Request](https://github.com/rails/rails/pull/16180)) ### Notable changes -* Introduced `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)) +* Introduced the `restore_attributes` method in `ActiveModel::Dirty` to restore + the changed (dirty) attributes to their previous values. + (Pull Request [1](https://github.com/rails/rails/pull/14861), [2](https://github.com/rails/rails/pull/16180)) + +* `has_secure_password` no longer disallow blank passwords (i.e. passwords + that contains only spaces) by default. + ([Pull Request](https://github.com/rails/rails/pull/16412)) * `has_secure_password` now verifies that the given password is less than 72 characters if validations are enabled. @@ -352,6 +510,10 @@ Please refer to the [Changelog][active-support] for detailed changes. ### Deprecations +* Deprecated `Kernel#silence_stderr`, `Kernel#capture` and `Kernel#quietly` + without replacement. + ([Pull Request](https://github.com/rails/rails/pull/13392)) + * Deprecated `Class#superclass_delegating_accessor`, use `Class#class_attribute` instead. ([Pull Request](https://github.com/rails/rails/pull/14271)) @@ -362,6 +524,23 @@ Please refer to the [Changelog][active-support] for detailed changes. ### Notable changes +* The `travel_to` test helper now truncates the `usec` component to 0. + ([Commit](https://github.com/rails/rails/commit/9f6e82ee4783e491c20f5244a613fdeb4024beb5)) + +* `ActiveSupport::TestCase` now randomizes the order that test cases are ran + by default. + ([Commit](https://github.com/rails/rails/commit/6ffb29d24e05abbd9ffe3ea974140d6c70221807)) + +* Introduced `Object#itself` as an identity function. + (Commit [1](https://github.com/rails/rails/commit/702ad710b57bef45b081ebf42e6fa70820fdd810), + [2](https://github.com/rails/rails/commit/64d91122222c11ad3918cc8e2e3ebc4b0a03448a)) + +* `Object#with_options` can now be used without an explicit receiver. + ([Pull Request](https://github.com/rails/rails/pull/16339)) + +* Introduced `String#truncate_words` to truncate a string by a number of words. + ([Pull Request](https://github.com/rails/rails/pull/16190)) + * Added `Hash#transform_values` and `Hash#transform_values!` to simplify a common pattern where the values of a hash must change, but the keys are left the same. @@ -370,7 +549,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/action_mailer_basics.md b/guides/source/action_mailer_basics.md index cb1c1c653d..f981d0da47 100644 --- a/guides/source/action_mailer_basics.md +++ b/guides/source/action_mailer_basics.md @@ -159,7 +159,10 @@ $ bin/rake db:migrate Now that we have a user model to play with, we will just edit the `app/controllers/users_controller.rb` make it instruct the `UserMailer` to deliver an email to the newly created user by editing the create action and inserting a -call to `UserMailer.welcome_email` right after the user is successfully saved: +call to `UserMailer.welcome_email` right after the user is successfully saved. + +Action Mailer is nicely integrated with Active Job so you can send emails outside +of the request-response cycle, so the user doesn't have to wait on it: ```ruby class UsersController < ApplicationController @@ -171,7 +174,7 @@ class UsersController < ApplicationController respond_to do |format| if @user.save # Tell the UserMailer to send a welcome email after save - UserMailer.welcome_email(@user).deliver + UserMailer.welcome_email(@user).deliver_later format.html { redirect_to(@user, notice: 'User was successfully created.') } format.json { render json: @user, status: :created, location: @user } @@ -184,8 +187,29 @@ class UsersController < ApplicationController end ``` -The method `welcome_email` returns a `Mail::Message` object which can then just -be told `deliver` to send itself out. +NOTE: Active Job's default behavior is to execute jobs ':inline'. So, you can use +`deliver_later` now to send emails, and when you later decide to start sending +them from a background job, you'll only need to set up Active Job to use a queueing +backend (Sidekiq, Resque, etc). + +If you want to send emails right away (from a cronjob for example) just call +`deliver_now`: + +```ruby +class SendWeeklySummary + def run + User.find_each do |user| + UserMailer.weekly_summary(user).deliver_now + end + end +end +``` + +The method `welcome_email` returns a `ActionMailer::MessageDelivery` object which +can then just be told `deliver_now` or `deliver_later` to send itself out. The +`ActionMailer::MessageDelivery` object is just a wrapper around a `Mail::Message`. If +you want to inspect, alter or do anything else with the `Mail::Message` object you can +access it with the `message` method on the `ActionMailer::MessageDelivery` object. ### Auto encoding header values @@ -414,6 +438,22 @@ globally in `config/application.rb`: config.action_mailer.default_url_options = { host: 'example.com' } ``` +Because of this behavior you cannot use any of the `*_path` helpers inside of +an email. Instead you will need to use the associated `*_url` helper. For example +instead of using + +``` +<%= link_to 'welcome', welcome_path %> +``` + +You will need to use: + +``` +<%= link_to 'welcome', welcome_url %> +``` + +By using the full URL, your links will now work in your emails. + #### generating URLs with `url_for` You need to pass the `only_path: false` option when using `url_for`. This will diff --git a/guides/source/action_view_overview.md b/guides/source/action_view_overview.md index ef7ef5a50e..f37bb20750 100644 --- a/guides/source/action_view_overview.md +++ b/guides/source/action_view_overview.md @@ -495,7 +495,7 @@ image_url("edit.png") # => http://www.example.com/assets/edit.png #### image_tag -Returns an html image tag for the source. The source can be a full path or a file that exists in your `app/assets/images` directory. +Returns an HTML image tag for the source. The source can be a full path or a file that exists in your `app/assets/images` directory. ```ruby image_tag("icon.png") # => <img src="/assets/icon.png" alt="Icon" /> @@ -503,7 +503,7 @@ image_tag("icon.png") # => <img src="/assets/icon.png" alt="Icon" /> #### javascript_include_tag -Returns an html script tag for each of the sources provided. You can pass in the filename (`.js` extension is optional) of JavaScript files that exist in your `app/assets/javascripts` directory for inclusion into the current page or you can pass the full path relative to your document root. +Returns an HTML script tag for each of the sources provided. You can pass in the filename (`.js` extension is optional) of JavaScript files that exist in your `app/assets/javascripts` directory for inclusion into the current page or you can pass the full path relative to your document root. ```ruby javascript_include_tag "common" # => <script src="/assets/common.js"></script> @@ -736,7 +736,7 @@ distance_of_time_in_words(Time.now, Time.now + 15.seconds, include_seconds: true #### select_date -Returns a set of html select-tags (one for year, month, and day) pre-selected with the `date` provided. +Returns a set of HTML select-tags (one for year, month, and day) pre-selected with the `date` provided. ```ruby # Generates a date select that defaults to the date provided (six days after today) @@ -748,7 +748,7 @@ select_date() #### select_datetime -Returns a set of html select-tags (one for year, month, day, hour, and minute) pre-selected with the `datetime` provided. +Returns a set of HTML select-tags (one for year, month, day, hour, and minute) pre-selected with the `datetime` provided. ```ruby # Generates a datetime select that defaults to the datetime provided (four days after today) @@ -808,7 +808,7 @@ select_second(Time.now + 16.minutes) #### select_time -Returns a set of html select-tags (one for hour and minute). +Returns a set of HTML select-tags (one for hour and minute). ```ruby # Generates a time select that defaults to the time provided @@ -1526,7 +1526,7 @@ The SanitizeHelper module provides a set of methods for scrubbing text of undesi #### sanitize -This sanitize helper will html encode all tags and strip all attributes that aren't specifically allowed. +This sanitize helper will HTML encode all tags and strip all attributes that aren't specifically allowed. ```ruby sanitize @article.body diff --git a/guides/source/active_job_basics.md b/guides/source/active_job_basics.md new file mode 100644 index 0000000000..a8e1f22b4d --- /dev/null +++ b/guides/source/active_job_basics.md @@ -0,0 +1,259 @@ +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, to billing charges, to 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 enqueuing 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 what 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 no 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 easily 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 support 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 allow 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 asynchronously: + +```ruby +# If you want to send the email now use #deliver_now +UserMailer.welcome(@user).deliver_now + +# If you want to send the email through ActiveJob use #deliver_later +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_basics.md b/guides/source/active_record_basics.md index 21022f1abb..eff93ce41d 100644 --- a/guides/source/active_record_basics.md +++ b/guides/source/active_record_basics.md @@ -310,10 +310,10 @@ models and validate that an attribute value is not empty, is unique and not already in the database, follows a specific format and many more. Validation is a very important issue to consider when persisting to the database, so -the methods `create`, `save` and `update` take it into account when +the methods `save` and `update` take it into account when running: they return `false` when validation fails and they didn't actually perform any operation on the database. All of these have a bang counterpart (that -is, `create!`, `save!` and `update!`), which are stricter in that +is, `save!` and `update!`), which are stricter in that they raise the exception `ActiveRecord::RecordInvalid` if validation fails. A quick example to illustrate: @@ -322,8 +322,9 @@ class User < ActiveRecord::Base validates :name, presence: true end -User.create # => false -User.create! # => ActiveRecord::RecordInvalid: Validation failed: Name can't be blank +user = User.new +user.save # => false +user.save! # => ActiveRecord::RecordInvalid: Validation failed: Name can't be blank ``` You can learn more about validations in the [Active Record Validations diff --git a/guides/source/active_record_querying.md b/guides/source/active_record_querying.md index c9e265de08..cb243c95f5 100644 --- a/guides/source/active_record_querying.md +++ b/guides/source/active_record_querying.md @@ -267,23 +267,6 @@ This is equivalent to writing: Client.where(first_name: 'does not exist').take! ``` -#### `last!` - -`Model.last!` finds the last record ordered by the primary key. For example: - -```ruby -client = Client.last! -# => #<Client id: 221, first_name: "Russel"> -``` - -The SQL equivalent of the above is: - -```sql -SELECT * FROM clients ORDER BY clients.id DESC LIMIT 1 -``` - -`Model.last!` raises `ActiveRecord::RecordNotFound` if no matching record is found. - ### Retrieving Multiple Objects in Batches We often need to iterate over a large set of records, as when we send a newsletter to a large set of users, or when we export data. @@ -293,7 +276,7 @@ This may appear straightforward: ```ruby # This is very inefficient when the users table has thousands of rows. User.all.each do |user| - NewsLetter.weekly_deliver(user) + NewsMailer.weekly(user).deliver_now end ``` @@ -309,7 +292,7 @@ The `find_each` method retrieves a batch of records and then yields _each_ recor ```ruby User.find_each do |user| - NewsMailer.weekly(user).deliver + NewsMailer.weekly(user).deliver_now end ``` @@ -317,7 +300,7 @@ To add conditions to a `find_each` operation you can chain other Active Record m ```ruby User.where(weekly_subscriber: true).find_each do |user| - NewsMailer.weekly(user).deliver + NewsMailer.weekly(user).deliver_now end ``` @@ -333,7 +316,7 @@ The `:batch_size` option allows you to specify the number of records to be retri ```ruby User.find_each(batch_size: 5000) do |user| - NewsLetter.weekly_deliver(user) + NewsMailer.weekly(user).deliver_now end ``` @@ -345,7 +328,7 @@ For example, to send newsletters only to users with the primary key starting fro ```ruby User.find_each(start: 2000, batch_size: 5000) do |user| - NewsLetter.weekly_deliver(user) + NewsMailer.weekly(user).deliver_now end ``` @@ -1481,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/asset_pipeline.md b/guides/source/asset_pipeline.md index 84cda9222e..e31cefa5bb 100644 --- a/guides/source/asset_pipeline.md +++ b/guides/source/asset_pipeline.md @@ -124,19 +124,22 @@ with a built-in helper. In the source the generated code looked like this: The query string strategy has several disadvantages: 1. **Not all caches will reliably cache content where the filename only differs by -query parameters** +query parameters** + [Steve Souders recommends](http://www.stevesouders.com/blog/2008/08/23/revving-filenames-dont-use-querystring/), "...avoiding a querystring for cacheable resources". He found that in this case 5-20% of requests will not be cached. Query strings in particular do not work at all with some CDNs for cache invalidation. -2. **The file name can change between nodes in multi-server environments.** +2. **The file name can change between nodes in multi-server environments.** + The default query string in Rails 2.x is based on the modification time of the files. When assets are deployed to a cluster, there is no guarantee that the timestamps will be the same, resulting in different values being used depending on which server handles the request. -3. **Too much cache invalidation** +3. **Too much cache invalidation** + When static assets are deployed with each new release of code, the mtime (time of last modification) of _all_ these files changes, forcing all remote clients to fetch them again, even when the content of those assets has not changed. @@ -490,8 +493,7 @@ The directives that work in JavaScript files also work in stylesheets one, requiring all stylesheets from the current directory. In this example, `require_self` is used. This puts the CSS contained within the -file (if any) at the precise location of the `require_self` call. If -`require_self` is called more than once, only the last call is respected. +file (if any) at the precise location of the `require_self` call. NOTE. If you want to use multiple Sass files, you should generally use the [Sass `@import` rule](http://sass-lang.com/docs/yardoc/file.SASS_REFERENCE.html#import) instead of these Sprockets directives. When using Sprockets directives, Sass files exist within diff --git a/guides/source/association_basics.md b/guides/source/association_basics.md index 7e99da3f6d..daf4113b66 100644 --- a/guides/source/association_basics.md +++ b/guides/source/association_basics.md @@ -105,7 +105,7 @@ class CreateOrders < ActiveRecord::Migration end create_table :orders do |t| - t.belongs_to :customer + t.belongs_to :customer, index: true t.datetime :order_date t.timestamps end @@ -136,7 +136,7 @@ class CreateSuppliers < ActiveRecord::Migration end create_table :accounts do |t| - t.belongs_to :supplier + t.belongs_to :supplier, index: true t.string :account_number t.timestamps end @@ -169,7 +169,7 @@ class CreateCustomers < ActiveRecord::Migration end create_table :orders do |t| - t.belongs_to :customer + t.belongs_to :customer, index:true t.datetime :order_date t.timestamps end @@ -216,8 +216,8 @@ class CreateAppointments < ActiveRecord::Migration end create_table :appointments do |t| - t.belongs_to :physician - t.belongs_to :patient + t.belongs_to :physician, index: true + t.belongs_to :patient, index: true t.datetime :appointment_date t.timestamps end @@ -295,13 +295,13 @@ class CreateAccountHistories < ActiveRecord::Migration end create_table :accounts do |t| - t.belongs_to :supplier + t.belongs_to :supplier, index: true t.string :account_number t.timestamps end create_table :account_histories do |t| - t.belongs_to :account + t.belongs_to :account, index: true t.integer :credit_rating t.timestamps end @@ -341,8 +341,8 @@ class CreateAssembliesAndParts < ActiveRecord::Migration end create_table :assemblies_parts, id: false do |t| - t.belongs_to :assembly - t.belongs_to :part + t.belongs_to :assembly, index: true + t.belongs_to :part, index: true end end end @@ -379,6 +379,8 @@ class CreateSuppliers < ActiveRecord::Migration t.string :account_number t.timestamps end + + add_index :accounts, :supplier_id end end ``` @@ -455,6 +457,8 @@ class CreatePictures < ActiveRecord::Migration t.string :imageable_type t.timestamps end + + add_index :pictures, :imageable_id end end ``` @@ -466,7 +470,7 @@ class CreatePictures < ActiveRecord::Migration def change create_table :pictures do |t| t.string :name - t.references :imageable, polymorphic: true + t.references :imageable, polymorphic: true, index: true t.timestamps end end @@ -496,7 +500,7 @@ In your migrations/schema, you will add a references column to the model itself. class CreateEmployees < ActiveRecord::Migration def change create_table :employees do |t| - t.references :manager + t.references :manager, index: true t.timestamps end end @@ -561,6 +565,8 @@ class CreateOrders < ActiveRecord::Migration t.string :order_number t.integer :customer_id end + + add_index :orders, :customer_id end end ``` @@ -594,6 +600,9 @@ class CreateAssembliesPartsJoinTable < ActiveRecord::Migration t.integer :assembly_id t.integer :part_id end + + add_index :assemblies_parts, :assembly_id + add_index :assemblies_parts, :part_id end end ``` 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 cb0228fa75..a074b849c6 100644 --- a/guides/source/command_line.md +++ b/guides/source/command_line.md @@ -7,7 +7,6 @@ After reading this guide, you will know: * How to generate models, controllers, database migrations, and unit tests. * How to start a development server. * How to experiment with objects through an interactive shell. -* How to profile and benchmark your new creation. -------------------------------------------------------------------------------- @@ -150,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 @@ -237,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..38f9609287 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`. @@ -288,8 +290,6 @@ All these configuration options are delegated to the `I18n` library. * `config.active_record.partial_writes` is a boolean value and controls whether or not partial writes are used (i.e. whether updates only set attributes that are dirty). Note that when using partial writes, you should also use optimistic locking `config.active_record.lock_optimistically` since concurrent updates may write attributes based on a possibly stale read state. The default value is `true`. -* `config.active_record.attribute_types_cached_by_default` sets the attribute types that `ActiveRecord::AttributeMethods` will cache by default on reads. The default is `[:datetime, :timestamp, :time, :date]`. - * `config.active_record.maintain_test_schema` is a boolean value which controls whether Active Record should try to keep your test database schema up-to-date with `db/schema.rb` (or `db/structure.sql`) when you run your tests. The default is true. * `config.active_record.dump_schema_after_migration` is a flag which @@ -996,3 +996,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 a8b959c725..8bc4b10591 100644 --- a/guides/source/contributing_to_ruby_on_rails.md +++ b/guides/source/contributing_to_ruby_on_rails.md @@ -318,6 +318,12 @@ You can also run any single test separately: $ ARCONN=sqlite3 ruby -Itest test/cases/associations/has_many_associations_test.rb ``` +To run a single test against all adapters, use: + +```bash +$ bundle exec rake TEST=test/cases/associations/has_many_associations_test.rb +``` + You can invoke `test_jdbcmysql`, `test_jdbcsqlite3` or `test_jdbcpostgresql` also. See the file `activerecord/RUNNING_UNIT_TESTS.rdoc` for information on running more targeted database tests, or the file `ci/travis.rb` for the test suite run by the continuous integration server. ### Warnings @@ -391,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..5c37837a1c 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 @@ -159,6 +163,11 @@ url: upgrading_ruby_on_rails.html description: This guide helps in upgrading applications to latest Ruby on Rails versions. - + name: Ruby on Rails 4.2 Release Notes + url: 4_2_release_notes.html + description: Release notes for Rails 4.2. + work_in_progress: true + - name: Ruby on Rails 4.1 Release Notes url: 4_1_release_notes.html description: Release notes for Rails 4.1. 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 93fb5eece8..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. @@ -35,7 +36,7 @@ $ bin/rails generate helper --help Creating Your First Generator ----------------------------- -Since Rails 3.0, generators are built on top of [Thor](https://github.com/erikhuda/thor). Thor provides powerful options parsing and a great API for manipulating files. For instance, let's build a generator that creates an initializer file named `initializer.rb` inside `config/initializers`. +Since Rails 3.0, generators are built on top of [Thor](https://github.com/erikhuda/thor). Thor provides powerful options for parsing and a great API for manipulating files. For instance, let's build a generator that creates an initializer file named `initializer.rb` inside `config/initializers`. The first step is to create a file at `lib/generators/initializer_generator.rb` with the following content: @@ -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 ef97cda3bc..964bb30856 100644 --- a/guides/source/getting_started.md +++ b/guides/source/getting_started.md @@ -21,10 +21,10 @@ application from scratch. It does not assume that you have any prior experience with Rails. However, to get the most out of it, you need to have some prerequisites installed: -* The [Ruby](http://www.ruby-lang.org/en/downloads) language version 1.9.3 or newer. -* The [RubyGems](http://rubygems.org) packaging system, which is installed with Ruby +* The [Ruby](https://www.ruby-lang.org/en/downloads) language version 1.9.3 or newer. +* The [RubyGems](https://rubygems.org) packaging system, which is installed with Ruby versions 1.9 and later. To learn more about RubyGems, please read the [RubyGems Guides](http://guides.rubygems.org). -* A working installation of the [SQLite3 Database](http://www.sqlite.org). +* A working installation of the [SQLite3 Database](https://www.sqlite.org). Rails is a web application framework running on the Ruby programming language. If you have no prior experience with Ruby, you will find a very steep learning @@ -101,7 +101,7 @@ If you don't have Ruby installed have a look at install Ruby on your platform. Many popular UNIX-like OSes ship with an acceptable version of SQLite3. Windows -users and others can find installation instructions at [the SQLite3 website](http://www.sqlite.org). +users and others can find installation instructions at [the SQLite3 website](https://www.sqlite.org). Verify that it is correctly installed and in your PATH: ```bash @@ -120,7 +120,7 @@ To verify that you have everything installed correctly, you should be able to run the following: ```bash -$ bin/rails --version +$ rails --version ``` If it says something like "Rails 4.2.0", you are ready to continue. @@ -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 @@ -749,7 +748,7 @@ to create an article. Try it! You should get an error that looks like this: (images/getting_started/forbidden_attributes_for_new_article.png) Rails has several security features that help you write secure applications, -and you're running into one of them now. This one is called [strong parameters](http://guides.rubyonrails.org/action_controller_overview.html#strong-parameters), +and you're running into one of them now. This one is called [strong parameters](action_controller_overview.html#strong-parameters), which requires us to tell Rails exactly which parameters are allowed into our controller actions. @@ -909,7 +908,7 @@ And then finally, add the view for this action, located at </table> ``` -Now if you go to `http://localhost:3000/articles` you will see a list of all the +Now if you go to <http://localhost:3000/articles> you will see a list of all the articles that you have created. ### Adding links @@ -1105,7 +1104,7 @@ standout. Now you'll get a nice error message when saving an article without title when you attempt to do just that on the new article form -[(http://localhost:3000/articles/new)](http://localhost:3000/articles/new). +<http://localhost:3000/articles/new>:  @@ -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 f00f7bca1b..60571750a1 100644 --- a/guides/source/layouts_and_rendering.md +++ b/guides/source/layouts_and_rendering.md @@ -263,7 +263,7 @@ TIP: This is useful when you're rendering a small snippet of HTML code. However, you might want to consider moving it to a template file if the markup is complex. -NOTE: This option will escape HTML entities if the string is not html safe. +NOTE: This option will escape HTML entities if the string is not HTML safe. #### Rendering JSON @@ -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/routing.md b/guides/source/routing.md index c8f8ba3044..af8c1bbcc4 100644 --- a/guides/source/routing.md +++ b/guides/source/routing.md @@ -645,6 +645,8 @@ match 'photos', to: 'photos#show', via: :all NOTE: Routing both `GET` and `POST` requests to a single action has security implications. In general, you should avoid routing all verbs to an action unless you have a good reason to. +NOTE: 'GET' in Rails won't check for CSRF token. You should never write to the database from 'GET' requests, for more information see the [security guide](security.html#csrf-countermeasures) on CSRF countermeasures. + ### Segment Constraints You can use the `:constraints` option to enforce a format for a dynamic segment: @@ -681,7 +683,7 @@ You can also constrain a route based on any method on the [Request object](actio You specify a request-based constraint the same way that you specify a segment constraint: ```ruby -get 'photos', constraints: { subdomain: 'admin' } +get 'photos', to: 'photos#index', constraints: { subdomain: 'admin' } ``` You can also specify constraints in a block form: 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 b2da25b19f..29724ae011 100644 --- a/guides/source/testing.md +++ b/guides/source/testing.md @@ -99,7 +99,7 @@ one: Note: For associations to reference one another by name, you cannot specify the `id:` attribute on the fixtures. Rails will auto assign a primary key to be consistent between runs. If you manually specify an `id:` attribute, this behavior will not work. For more - information on this assocation behavior please read the + information on this association behavior please read the [fixture api documentation](http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html). #### ERB'in It Up @@ -364,13 +364,8 @@ Ideally, you would like to include a test for everything which could possibly br By now you've caught a glimpse of some of the assertions that are available. Assertions are the worker bees of testing. They are the ones that actually perform the checks to ensure that things are going as planned. -There are a bunch of different types of assertions you can use. Here's an -extract of the -[assertions](http://docs.seattlerb.org/minitest/Minitest/Assertions.html) 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. It's not -required. +There are a bunch of different types of assertions you can use. +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. It's not required. | Assertion | Purpose | | ---------------------------------------------------------------- | ------- | @@ -406,6 +401,8 @@ required. | `assert_send( array, [msg] )` | Ensures that executing the method listed in `array[1]` on the object in `array[0]` with the parameters of `array[2 and up]` is true. This one is weird eh?| | `flunk( [msg] )` | Ensures failure. This is useful to explicitly mark a test that isn't finished yet.| +The above are subset of assertions that minitest supports. For an exhaustive & more up-to-date list, please check [Minitest API documentation](http://docs.seattlerb.org/minitest/), specifically [`Minitest::Assertions`](http://docs.seattlerb.org/minitest/Minitest/Assertions.html) + Because of the modular nature of the testing framework, it is possible to create your own assertions. In fact, that's exactly what Rails does. It includes some specialized assertions to make your life easier. NOTE: Creating your own assertions is an advanced topic that we won't cover in this tutorial. @@ -608,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: @@ -644,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 @@ -952,7 +949,7 @@ class UserMailerTest < ActionMailer::TestCase test "invite" do # Send the email, then test that it got queued email = UserMailer.create_invite('me@example.com', - 'friend@example.com', Time.now).deliver + 'friend@example.com', Time.now).deliver_now assert_not ActionMailer::Base.deliveries.empty? # Test the body of the sent email contains what we expect it to @@ -1017,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: - -```bash -$ bin/rails generate helper User - create app/helpers/user_helper.rb - invoke test_unit - create test/helpers/user_helper_test.rb -``` +located under the `test/helpers` directory. -The generated test file contains the following code: +A helper test looks like so: ```ruby require 'test_helper' @@ -1060,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..407445f449 100644 --- a/guides/source/upgrading_ruby_on_rails.md +++ b/guides/source/upgrading_ruby_on_rails.md @@ -50,14 +50,96 @@ Don't forget to review the difference, to see if there were any unexpected chang Upgrading from Rails 4.1 to Rails 4.2 ------------------------------------- -NOTE: This section is a work in progress. +NOTE: This section is a work in progress, please help to improve this by sending +a [pull request](https://github.com/rails/rails/edit/master/guides/source/upgrading_ruby_on_rails.md). + +### Web Console + +TODO: setup instructions for web console on existing apps. + +### Responders + +TODO: mention https://github.com/rails/rails/pull/16526 + +### Error handling in transaction callbacks + +TODO: mention https://github.com/rails/rails/pull/16537 ### 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. + +### Rails DOM Testing + +TODO: Mention https://github.com/rails/rails/commit/4e97d7585a2f4788b9eed98c6cdaf4bb6f2cf5ce + Upgrading from Rails 4.0 to Rails 4.1 ------------------------------------- @@ -66,7 +148,7 @@ Upgrading from Rails 4.0 to Rails 4.1 Or, "whaaat my tests are failing!!!?" Cross-site request forgery (CSRF) protection now covers GET requests with -JavaScript responses, too. That prevents a third-party site from referencing +JavaScript responses, too. This prevents a third-party site from referencing your JavaScript URL and attempting to run it to extract sensitive data. This means that your functional and integration tests that use @@ -117,8 +199,8 @@ secrets, you need to: ``` 2. Use your existing `secret_key_base` from the `secret_token.rb` initializer to - set the SECRET_KEY_BASE environment variable for whichever users run the Rails - app in production mode. Alternately, you can simply copy the existing + set the SECRET_KEY_BASE environment variable for whichever users running the + Rails application in production mode. Alternatively, you can simply copy the existing `secret_key_base` from the `secret_token.rb` initializer to `secrets.yml` under the `production` section, replacing '<%= ENV["SECRET_KEY_BASE"] %>'. @@ -132,7 +214,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 @@ -321,8 +403,8 @@ ActiveRecord::FixtureSet.context_class.send :include, FixtureFileHelpers ### I18n enforcing available locales -Rails 4.1 now defaults the I18n option `enforce_available_locales` to `true`, -meaning that it will make sure that all locales passed to it must be declared in +Rails 4.1 now defaults the I18n option `enforce_available_locales` to `true`. This +means that it will make sure that all locales passed to it must be declared in the `available_locales` list. To disable it (and allow I18n to accept *any* locale option) add the following @@ -332,9 +414,10 @@ configuration to your application: config.i18n.enforce_available_locales = false ``` -Note that this option was added as a security measure, to ensure user input could -not be used as locale information unless previously known, so it's recommended not -to disable this option unless you have a strong reason for doing so. +Note that this option was added as a security measure, to ensure user input +cannot be used as locale information unless it is previously known. Therefore, +it's recommended not to disable this option unless you have a strong reason for +doing so. ### Mutator methods called on Relation @@ -442,7 +525,7 @@ Using `render :text` may pose a security risk, as the content is sent as ### PostgreSQL json and hstore datatypes Rails 4.1 will map `json` and `hstore` columns to a string-keyed Ruby `Hash`. -In earlier versions a `HashWithIndifferentAccess` was used. This means that +In earlier versions, a `HashWithIndifferentAccess` was used. This means that symbol access is no longer supported. This is also the case for `store_accessors` based on top of `json` or `hstore` columns. Make sure to use string keys consistently. @@ -532,7 +615,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 +675,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 |