diff options
Diffstat (limited to 'guides')
-rw-r--r-- | guides/assets/stylesheets/main.css | 4 | ||||
-rw-r--r-- | guides/rails_guides/markdown.rb | 4 | ||||
-rw-r--r-- | guides/source/5_1_release_notes.md | 57 | ||||
-rw-r--r-- | guides/source/action_controller_overview.md | 2 | ||||
-rw-r--r-- | guides/source/action_mailer_basics.md | 2 | ||||
-rw-r--r-- | guides/source/active_record_callbacks.md | 10 | ||||
-rw-r--r-- | guides/source/active_record_querying.md | 16 | ||||
-rw-r--r-- | guides/source/api_documentation_guidelines.md | 4 | ||||
-rw-r--r-- | guides/source/contributing_to_ruby_on_rails.md | 26 | ||||
-rw-r--r-- | guides/source/engines.md | 112 | ||||
-rw-r--r-- | guides/source/rails_on_rack.md | 11 | ||||
-rw-r--r-- | guides/source/routing.md | 15 | ||||
-rw-r--r-- | guides/source/security.md | 2 | ||||
-rw-r--r-- | guides/source/working_with_javascript_in_rails.md | 2 |
14 files changed, 215 insertions, 52 deletions
diff --git a/guides/assets/stylesheets/main.css b/guides/assets/stylesheets/main.css index b56699a0d0..b27776745a 100644 --- a/guides/assets/stylesheets/main.css +++ b/guides/assets/stylesheets/main.css @@ -294,6 +294,10 @@ a, a:link, a:visited { #mainCol a, #subCol a, #feature a {color: #980905;} #mainCol a code, #subCol a code, #feature a code {color: #980905;} +#mainCol a.anchorlink, #mainCol a.anchorlink code {color: #333;} +#mainCol a.anchorlink { text-decoration: none; } +#mainCol a.anchorlink:hover { text-decoration: underline; } + /* Navigation --------------------------------------- */ diff --git a/guides/rails_guides/markdown.rb b/guides/rails_guides/markdown.rb index bf2cc82c7c..16aaa7d1eb 100644 --- a/guides/rails_guides/markdown.rb +++ b/guides/rails_guides/markdown.rb @@ -105,6 +105,10 @@ module RailsGuides node.inner_html = "#{node_index(hierarchy)} #{node.inner_html}" end end + + doc.css('h3, h4, h5, h6').each do |node| + node.inner_html = "<a class='anchorlink' href='##{node[:id]}'>#{node.inner_html}</a>" + end end.to_html end end diff --git a/guides/source/5_1_release_notes.md b/guides/source/5_1_release_notes.md index 5d4885d55c..e995c50297 100644 --- a/guides/source/5_1_release_notes.md +++ b/guides/source/5_1_release_notes.md @@ -24,7 +24,14 @@ repository on GitHub. Upgrading to Rails 5.1 ---------------------- -ToDo +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 5.0 in case you +haven't and make sure your application still runs as expected before attempting +an update to Rails 5.1. 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-5-0-to-rails-5-1) +guide. + Major Features -------------- @@ -223,41 +230,89 @@ Railties Please refer to the [Changelog][railties] for detailed changes. +### Removals + +### Deprecations + +### Notable changes + Action Pack ----------- Please refer to the [Changelog][action-pack] for detailed changes. +### Removals + +### Deprecations + +### Notable changes + Action View ------------- Please refer to the [Changelog][action-view] for detailed changes. +### Removals + +### Deprecations + +### Notable changes + Action Mailer ------------- Please refer to the [Changelog][action-mailer] for detailed changes. +### Removals + +### Deprecations + +### Notable changes + Active Record ------------- Please refer to the [Changelog][active-record] for detailed changes. +### Removals + +### Deprecations + +### Notable changes + Active Model ------------ Please refer to the [Changelog][active-model] for detailed changes. +### Removals + +### Deprecations + +### Notable changes + Active Job ----------- Please refer to the [Changelog][active-job] for detailed changes. +### Removals + +### Deprecations + +### Notable changes + Active Support -------------- Please refer to the [Changelog][active-support] for detailed changes. +### Removals + +### Deprecations + +### Notable changes + Credits ------- diff --git a/guides/source/action_controller_overview.md b/guides/source/action_controller_overview.md index 69c4a00c5f..5d987264f5 100644 --- a/guides/source/action_controller_overview.md +++ b/guides/source/action_controller_overview.md @@ -719,7 +719,7 @@ Now, the `LoginsController`'s `new` and `create` actions will work as before wit In addition to "before" filters, you can also run filters after an action has been executed, or both before and after. -"after" filters are similar to "before" filters, but because the action has already been run they have access to the response data that's about to be sent to the client. Obviously, "after" filters cannot stop the action from running. +"after" filters are similar to "before" filters, but because the action has already been run they have access to the response data that's about to be sent to the client. Obviously, "after" filters cannot stop the action from running. Please note that "after" filters are executed only after a successful action, but not when an exception is raised in the request cycle. "around" filters are responsible for running their associated actions by yielding, similar to how Rack middlewares work. diff --git a/guides/source/action_mailer_basics.md b/guides/source/action_mailer_basics.md index 9673571909..65146ee7da 100644 --- a/guides/source/action_mailer_basics.md +++ b/guides/source/action_mailer_basics.md @@ -550,7 +550,7 @@ url helper. <%= user_url(@user, host: 'example.com') %> ``` -NOTE: non-`GET` links require [rails-ujs](https://github.com/rails/rails-ujs) or +NOTE: non-`GET` links require [rails-ujs](https://github.com/rails/rails/blob/master/actionview/app/assets/javascripts) or [jQuery UJS](https://github.com/rails/jquery-ujs), and won't work in mailer templates. They will result in normal `GET` requests. diff --git a/guides/source/active_record_callbacks.md b/guides/source/active_record_callbacks.md index 77bd3c97e8..b1705855d0 100644 --- a/guides/source/active_record_callbacks.md +++ b/guides/source/active_record_callbacks.md @@ -117,6 +117,10 @@ Here is a list with all the available Active Record callbacks, listed in the sam WARNING. `after_save` runs both on create and update, but always _after_ the more specific callbacks `after_create` and `after_update`, no matter the order in which the macro calls were executed. +NOTE: `before_destroy` callbacks should be placed before `dependent: :destroy` +associations (or use the `prepend: true` option), to ensure they execute before +the records are deleted by `dependent: :destroy`. + ### `after_initialize` and `after_find` The `after_initialize` callback will be called whenever an Active Record object is instantiated, either by directly using `new` or when a record is loaded from the database. It can be useful to avoid the need to directly override your Active Record `initialize` method. @@ -254,7 +258,11 @@ Halting Execution As you start registering new callbacks for your models, they will be queued for execution. This queue will include all your model's validations, the registered callbacks, and the database operation to be executed. -The whole callback chain is wrapped in a transaction. If any _before_ callback method returns exactly `false` or raises an exception, the execution chain gets halted and a ROLLBACK is issued; _after_ callbacks can only accomplish that by raising an exception. +The whole callback chain is wrapped in a transaction. If any callback raises an exception, the execution chain gets halted and a ROLLBACK is issued. To intentionally stop a chain use: + +```ruby +throw :abort +``` WARNING. Any exception that is not `ActiveRecord::Rollback` or `ActiveRecord::RecordInvalid` will be re-raised by Rails after the callback chain is halted. Raising an exception other than `ActiveRecord::Rollback` or `ActiveRecord::RecordInvalid` may break code that does not expect methods like `save` and `update_attributes` (which normally try to return `true` or `false`) to raise an exception. diff --git a/guides/source/active_record_querying.md b/guides/source/active_record_querying.md index 2902c5d677..26d01d4ede 100644 --- a/guides/source/active_record_querying.md +++ b/guides/source/active_record_querying.md @@ -1381,8 +1381,9 @@ class Client < ApplicationRecord end ``` -NOTE: The `default_scope` is also applied while creating/building a record. -It is not applied while updating a record. E.g.: +NOTE: The `default_scope` is also applied while creating/building a record +when the scope arguments are given as a `Hash`. It is not applied while +updating a record. E.g.: ```ruby class Client < ApplicationRecord @@ -1393,6 +1394,17 @@ Client.new # => #<Client id: nil, active: true> Client.unscoped.new # => #<Client id: nil, active: nil> ``` +Be aware that, when given in the `Array` format, `default_scope` query arguments +cannot be converted to a `Hash` for default attribute assignment. E.g.: + +```ruby +class Client < ApplicationRecord + default_scope { where("active = ?", true) } +end + +Client.new # => #<Client id: nil, active: nil> +``` + ### Merging of scopes Just like `where` clauses scopes are merged using `AND` conditions. diff --git a/guides/source/api_documentation_guidelines.md b/guides/source/api_documentation_guidelines.md index 34b9c0d2ca..3c61754982 100644 --- a/guides/source/api_documentation_guidelines.md +++ b/guides/source/api_documentation_guidelines.md @@ -333,10 +333,6 @@ As a contributor, it's important to think about whether this API is meant for en A class or module is marked with `:nodoc:` to indicate that all methods are internal API and should never be used directly. -If you come across an existing `:nodoc:` you should tread lightly. Consider asking someone from the core team or author of the code before removing it. This should almost always happen through a pull request instead of the docrails project. - -A `:nodoc:` should never be added simply because a method or class is missing documentation. There may be an instance where an internal public method wasn't given a `:nodoc:` by mistake, for example when switching a method from private to public visibility. When this happens it should be discussed over a PR on a case-by-case basis and never committed directly to docrails. - To summarize, the Rails team uses `:nodoc:` to mark publicly visible methods and classes for internal use; changes to the visibility of API should be considered carefully and discussed over a pull request first. Regarding the Rails Stack diff --git a/guides/source/contributing_to_ruby_on_rails.md b/guides/source/contributing_to_ruby_on_rails.md index 3b19b0dff1..39f4272b3c 100644 --- a/guides/source/contributing_to_ruby_on_rails.md +++ b/guides/source/contributing_to_ruby_on_rails.md @@ -132,24 +132,12 @@ learn about Ruby on Rails, and the API, which serves as a reference. You can help improve the Rails guides by making them more coherent, consistent or readable, adding missing information, correcting factual errors, fixing typos, or bringing them up to date with the latest edge Rails. -You can either open a pull request to [Rails](https://github.com/rails/rails) or -ask the [Rails core team](http://rubyonrails.org/community/#core) for commit access on -docrails if you contribute regularly. -Please do not open pull requests in docrails, if you'd like to get feedback on your -change, ask for it in [Rails](https://github.com/rails/rails) instead. - -Docrails is merged with master regularly, so you are effectively editing the Ruby on Rails documentation. - -If you are unsure of the documentation changes, you can create an issue in the [Rails](https://github.com/rails/rails/issues) issues tracker on GitHub. +To do so, open a pull request to [Rails](https://github.com/rails/rails) on GitHub. When working with documentation, please take into account the [API Documentation Guidelines](api_documentation_guidelines.html) and the [Ruby on Rails Guides Guidelines](ruby_on_rails_guides_guidelines.html). -NOTE: As explained earlier, ordinary code patches should have proper documentation coverage. Docrails is only used for isolated documentation improvements. - NOTE: To help our CI servers you should add [ci skip] to your documentation commit message to skip build on that commit. Please remember to use it for commits containing only documentation changes. -WARNING: Docrails has a very strict policy: no code can be touched whatsoever, no matter how trivial or small the change. Only RDoc and guides can be edited via docrails. Also, CHANGELOGs should never be edited in docrails. - Translating Rails Guides ------------------------ @@ -418,16 +406,6 @@ examples or multiple paragraphs. Otherwise, it's best to make a new paragraph. Some changes require the dependencies to be upgraded. In these cases make sure you run `bundle update` to get the right version of the dependency and commit the `Gemfile.lock` file within your changes. -### Sanity Check - -You should not be the only person who looks at the code before you submit it. -If you know someone else who uses Rails, try asking them if they'll check out -your work. If you don't know anyone else using Rails, try hopping into the IRC -room or posting about your idea to the rails-core mailing list. Doing this in -private before you push a patch out publicly is the "smoke test" for a patch: -if you can't convince one other developer of the beauty of your code, you’re -unlikely to convince the core team either. - ### Commit Your Changes When you're happy with the code on your computer, you need to commit the changes to Git: @@ -685,4 +663,4 @@ And then... think about your next contribution! Rails Contributors ------------------ -All contributions, either via master or docrails, get credit in [Rails Contributors](http://contributors.rubyonrails.org). +All contributions get credit in [Rails Contributors](http://contributors.rubyonrails.org). diff --git a/guides/source/engines.md b/guides/source/engines.md index 180a786237..2276f348a1 100644 --- a/guides/source/engines.md +++ b/guides/source/engines.md @@ -14,6 +14,7 @@ After reading this guide, you will know: * How to build features for the engine. * How to hook the engine into an application. * How to override engine functionality in the application. +* Avoid loading Rails frameworks with Load and Configuration Hooks -------------------------------------------------------------------------------- @@ -1410,3 +1411,114 @@ module MyEngine end end ``` + +Active Support On Load Hooks +---------------------------- + +Active Support is the Ruby on Rails component responsible for providing Ruby language extensions, utilities, and other transversal utilities. + +Rails code can often be referenced on load of an application. Rails is responsible for the load order of these frameworks, so when you load frameworks, such as `ActiveRecord::Base`, prematurely you are violating an implicit contract your application has with Rails. Moreover, by loading code such as `ActiveRecord::Base` on boot of your application you are loading entire frameworks which may slow down your boot time and could cause conflicts with load order and boot of your application. + +On Load hooks are the API that allow you to hook into this initialization process without violating the load contract with Rails. This will also mitigate boot performance degradation and avoid conflicts. + +## What are `on_load` hooks? + +Since Ruby is a dynamic language, some code will cause different Rails frameworks to load. Take this snippet for instance: + +```ruby +ActiveRecord::Base.include(MyActiveRecordHelper) +``` + +This snippet means that when this file is loaded, it will encounter `ActiveRecord::Base`. This encounter causes Ruby to look for the definition of that constant and will require it. This causes the entire Active Record framework to be loaded on boot. + +`ActiveSupport.on_load` is a mechanism that can be used to defer the loading of code until it is actually needed. The snippet above can be changed to: + +```ruby +ActiveSupport.on_load(:active_record) { include MyActiveRecordHelper } +``` + +This new snippet will only include `MyActiveRecordHelper` when `ActiveRecord::Base` is loaded. + +## How does it work? + +In the Rails framework these hooks are called when a specific library is loaded. For example, when `ActionController::Base` is loaded, the `:action_controller_base` hook is called. This means that all `ActiveSupport.on_load` calls with `:action_controller_base` hooks will be called in the context of `ActionController::Base` (that means `self` will be an `ActionController::Base`). + +## Modifying code to use `on_load` hooks + +Modifying code is generally straightforward. If you have a line of code that refers to a Rails framework such as `ActiveRecord::Base` you can wrap that code in an `on_load` hook. + +### Example 1 + +```ruby +ActiveRecord::Base.include(MyActiveRecordHelper) +``` + +becomes + +```ruby +ActiveSupport.on_load(:active_record) { include MyActiveRecordHelper } # self refers to ActiveRecord::Base here, so we can simply #include +``` + +### Example 2 + +```ruby +ActionController::Base.prepend(MyActionControllerHelper) +``` + +becomes + +```ruby +ActiveSupport.on_load(:action_controller_base) { prepend MyActionControllerHelper } # self refers to ActionController::Base here, so we can simply #prepend +``` + +### Example 3 + +```ruby +ActiveRecord::Base.include_root_in_json = true +``` + +becomes + +```ruby +ActiveSupport.on_load(:active_record) { self.include_root_in_json = true } # self refers to ActiveRecord::Base here +``` + +## Available Hooks + +These are the hooks you can use in your own code. + +To hook into the initialization process of one of the following classes use the available hook. + +| Class | Available Hooks | +| --------------------------------- | ------------------------------------ | +| `ActionCable` | `action_cable` | +| `ActionController::API` | `action_controller_api` | +| `ActionController::API` | `action_controller` | +| `ActionController::Base` | `action_controller_base` | +| `ActionController::Base` | `action_controller` | +| `ActionController::TestCase` | `action_controller_test_case` | +| `ActionDispatch::IntegrationTest` | `action_dispatch_integration_test` | +| `ActionMailer::Base` | `action_mailer` | +| `ActionMailer::TestCase` | `action_mailer_test_case` | +| `ActionView::Base` | `action_view` | +| `ActionView::TestCase` | `action_view_test_case` | +| `ActiveJob::Base` | `active_job` | +| `ActiveJob::TestCase` | `active_job_test_case` | +| `ActiveRecord::Base` | `active_record` | +| `ActiveSupport::TestCase` | `active_support_test_case` | +| `i18n` | `i18n` | + +## Configuration hooks + +These are the available configuration hooks. They do not hook into any particular framework, instead they run in context of the entire application. + +| Hook | Use Case | +| ---------------------- | ------------------------------------------------------------------------------------- | +| `before_configuration` | First configurable block to run. Called before any initializers are run. | +| `before_initialize` | Second configurable block to run. Called before frameworks initialize. | +| `before_eager_load` | Third configurable block to run. Does not run if `config.cache_classes` set to false. | +| `after_initialize` | Last configurable block to run. Called after frameworks initialize. | + +### Example + +`config.before_configuration { puts 'I am called before any initializers' }` diff --git a/guides/source/rails_on_rack.md b/guides/source/rails_on_rack.md index 340933c7ee..f25b185fb5 100644 --- a/guides/source/rails_on_rack.md +++ b/guides/source/rails_on_rack.md @@ -20,9 +20,9 @@ Introduction to Rack Rack provides a minimal, modular and adaptable interface for developing web applications in Ruby. By wrapping HTTP requests and responses in the simplest way possible, it unifies and distills the API for web servers, web frameworks, and software in between (the so-called middleware) into a single method call. -* [Rack API Documentation](http://rack.github.io/) - -Explaining Rack is not really in the scope of this guide. In case you are not familiar with Rack's basics, you should check out the [Resources](#resources) section below. +Explaining how Rack works is not really in the scope of this guide. In case you +are not familiar with Rack's basics, you should check out the [Resources](#resources) +section below. Rails on Rack ------------- @@ -74,7 +74,7 @@ And start the server: $ rackup config.ru ``` -To find out more about different `rackup` options: +To find out more about different `rackup` options, you can run: ```bash $ rackup --help @@ -89,7 +89,8 @@ Action Dispatcher Middleware Stack Many of Action Dispatcher's internal components are implemented as Rack middlewares. `Rails::Application` uses `ActionDispatch::MiddlewareStack` to combine various internal and external middlewares to form a complete Rails Rack application. -NOTE: `ActionDispatch::MiddlewareStack` is Rails equivalent of `Rack::Builder`, but built for better flexibility and more features to meet Rails' requirements. +NOTE: `ActionDispatch::MiddlewareStack` is Rails' equivalent of `Rack::Builder`, +but is built for better flexibility and more features to meet Rails' requirements. ### Inspecting Middleware Stack diff --git a/guides/source/routing.md b/guides/source/routing.md index 86492a9332..f7dbbc510e 100644 --- a/guides/source/routing.md +++ b/guides/source/routing.md @@ -142,16 +142,17 @@ Sometimes, you have a resource that clients always look up without referencing a get 'profile', to: 'users#show' ``` -Passing a `String` to `get` will expect a `controller#action` format, while passing a `Symbol` will map directly to an action but you must also specify the `controller:` to use: +Passing a `String` to `to:` will expect a `controller#action` format. When using a `Symbol`, the `to:` option should be replaced with `action:`. When using a `String` without a `#`, the `to:` option should be replaced with `controller:`: ```ruby -get 'profile', to: :show, controller: 'users' +get 'profile', action: :show, controller: 'users' ``` This resourceful route: ```ruby resource :geocoder +resolve('Geocoder') { [:geocoder] } ``` creates six different routes in your application, all mapping to the `Geocoders` controller: @@ -175,14 +176,6 @@ A singular resourceful route generates these helpers: As with plural resources, the same helpers ending in `_url` will also include the host, port and path prefix. -WARNING: A [long-standing bug](https://github.com/rails/rails/issues/1769) prevents `form_for` from working automatically with singular resources. As a workaround, specify the URL for the form directly, like so: - -```ruby -form_for @geocoder, url: geocoder_path do |f| - -# snippet for brevity -``` - ### Controller Namespaces and Routing You may wish to organize groups of controllers under a namespace. Most commonly, you might group a number of administrative controllers under an `Admin::` namespace. You would place these controllers under the `app/controllers/admin` directory, and you can group them together in your router: @@ -545,7 +538,7 @@ TIP: If you find yourself adding many extra actions to a resourceful route, it's Non-Resourceful Routes ---------------------- -In addition to resource routing, Rails has powerful support for routing arbitrary URLs to actions. Here, you don't get groups of routes automatically generated by resourceful routing. Instead, you set up each route within your application separately. +In addition to resource routing, Rails has powerful support for routing arbitrary URLs to actions. Here, you don't get groups of routes automatically generated by resourceful routing. Instead, you set up each route separately within your application. While you should usually use resourceful routing, there are still many places where the simpler routing is more appropriate. There's no need to try to shoehorn every last piece of your application into a resourceful framework if that's not a good fit. diff --git a/guides/source/security.md b/guides/source/security.md index 7e27e6f37d..c305350243 100644 --- a/guides/source/security.md +++ b/guides/source/security.md @@ -257,7 +257,7 @@ protect_from_forgery with: :exception This will automatically include a security token in all forms and Ajax requests generated by Rails. If the security token doesn't match what was expected, an exception will be thrown. -NOTE: By default, Rails includes an [unobtrusive scripting adapter](https://github.com/rails/rails-ujs), +NOTE: By default, Rails includes an [unobtrusive scripting adapter](https://github.com/rails/rails/blob/master/actionview/app/assets/javascripts), which adds a header called `X-CSRF-Token` with the security token on every non-GET Ajax call. Without this header, non-GET Ajax requests won't be accepted by Rails. When using another library to make Ajax calls, it is necessary to add the security diff --git a/guides/source/working_with_javascript_in_rails.md b/guides/source/working_with_javascript_in_rails.md index e04b3e3581..cbaf9100f7 100644 --- a/guides/source/working_with_javascript_in_rails.md +++ b/guides/source/working_with_javascript_in_rails.md @@ -149,7 +149,7 @@ Because of Unobtrusive JavaScript, the Rails "Ajax helpers" are actually in two parts: the JavaScript half and the Ruby half. Unless you have disabled the Asset Pipeline, -[rails-ujs](https://github.com/rails/rails-ujs/blob/master/src/rails-ujs.coffee) +[rails-ujs](https://github.com/rails/rails/blob/master/actionview/app/assets/javascripts/rails-ujs.coffee) provides the JavaScript half, and the regular Ruby view helpers add appropriate tags to your DOM. |