aboutsummaryrefslogtreecommitdiffstats
path: root/guides
diff options
context:
space:
mode:
Diffstat (limited to 'guides')
-rw-r--r--guides/CHANGELOG.md2
-rw-r--r--guides/code/getting_started/config/application.rb3
-rw-r--r--guides/source/4_0_release_notes.md31
-rw-r--r--guides/source/active_record_callbacks.md361
-rw-r--r--guides/source/active_record_validations.md (renamed from guides/source/active_record_validations_callbacks.md)420
-rw-r--r--guides/source/active_support_core_extensions.md27
-rw-r--r--guides/source/caching_with_rails.md98
-rw-r--r--guides/source/configuring.md4
-rw-r--r--guides/source/documents.yaml10
9 files changed, 421 insertions, 535 deletions
diff --git a/guides/CHANGELOG.md b/guides/CHANGELOG.md
index 11fe1c5efa..e9f7ff9d68 100644
--- a/guides/CHANGELOG.md
+++ b/guides/CHANGELOG.md
@@ -1,5 +1,7 @@
## Rails 4.0.0 (unreleased) ##
+* Split Validations and Callbacks guide into two. *Steve Klabnik*
+
* New guide _Working with JavaScript in Rails_. *Steve Klabnik*
* Guides updated to reflect new test locations. *Mike Moore*
diff --git a/guides/code/getting_started/config/application.rb b/guides/code/getting_started/config/application.rb
index d2cd5c028b..d53c9fd8bc 100644
--- a/guides/code/getting_started/config/application.rb
+++ b/guides/code/getting_started/config/application.rb
@@ -18,9 +18,6 @@ module Blog
# Custom directories with classes and modules you want to be autoloadable.
# config.autoload_paths += %W(#{config.root}/extras)
- # Activate observers that should always be running.
- # config.active_record.observers = :cacher, :garbage_collector, :forum_observer
-
# Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
# Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
# config.time_zone = 'Central Time (US & Canada)'
diff --git a/guides/source/4_0_release_notes.md b/guides/source/4_0_release_notes.md
index ecb8dd04f5..b4442130ac 100644
--- a/guides/source/4_0_release_notes.md
+++ b/guides/source/4_0_release_notes.md
@@ -7,6 +7,7 @@ Highlights in Rails 4.0: (WIP)
* Strong Parameters
* Queue API
* Caching Improvements
+* ActionController::Live
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/master) in the main Rails repository on GitHub.
@@ -69,6 +70,20 @@ $ ruby /path/to/rails/railties/bin/rails new myapp --dev
Major Features
--------------
+Moved to a Plugin
+-----------------
+
+With Rails 4 several pieces have been extracted. While Rails won't ship with these features anymore,
+you can simply add the extracted plugin to your `Gemfile` to bring the functionality back.
+
+* Hash-based & Dynamic finder methods ([Github](https://github.com/rails/activerecord-deprecated_finders))
+* Mass assignment protection in Active Record models ([Github](https://github.com/rails/protected_attributes), [Pull Request](https://github.com/rails/rails/pull/7251))
+* ActiveRecord::SessionStore ([Github](https://github.com/rails/activerecord-session_store), [Pull Request](https://github.com/rails/rails/pull/7436))
+* Active Record Observers ([Github](https://github.com/rails/rails-observers), [Commit](https://github.com/rails/rails/commit/39e85b3b90c58449164673909a6f1893cba290b2))
+* Active Resource ([Github](https://github.com/rails/activeresource), [Pull Request](https://github.com/rails/rails/pull/572), [Blog](http://yetimedia.tumblr.com/post/35233051627/activeresource-is-dead-long-live-activeresource))
+* Action Caching ([Github](https://github.com/rails/actionpack-action_caching), [Pull Request](https://github.com/rails/rails/pull/7833))
+* Page Caching ([Github](https://github.com/rails/actionpack-page_caching), [Pull Request](https://github.com/rails/rails/pull/7833))
+
Documentation
-------------
@@ -85,7 +100,7 @@ Railties
* Add `.rake` to list of file extensions included by `rake notes` and `rake notes:custom`.
-* New test locations `test/models`, `test/helpers`, `test/controllers`, and `test/mailers`. Corresponding rake tasks added as well.
+* New test locations `test/models`, `test/helpers`, `test/controllers`, and `test/mailers`. Corresponding rake tasks added as well. ([Pull Request](https://github.com/rails/rails/pull/7878))
* Set a different cache per environment for assets pipeline through `config.assets.cache`.
@@ -167,7 +182,7 @@ Action Mailer
* Raise an `ActionView::MissingTemplate` exception when no implicit template could be found.
-* Asynchronously send messages via the Rails Queue.
+* Asynchronously send messages via the Rails Queue. ([Pull Request](https://github.com/rails/rails/pull/6839))
* Delivery Options (such as SMTP Settings) can now be set dynamically per mailer action.
@@ -197,6 +212,8 @@ Action Pack
If you add the above code, you can use `<%= error %>` in an erb, and `redirect_to /foo, :error => 'message'` in a controller.
+* Encrypted Cookies + Sign using Derived Keys. ([Pull Request](https://github.com/rails/rails/pull/8112))
+
* Remove Active Model dependency from Action Pack.
* Support unicode characters in routes. Route will be automatically escaped, so instead of manually escaping:
@@ -294,6 +311,8 @@ Action Pack
* Show routes in exception page while debugging a `RoutingError` in development.
+* Helper methods for HTML5 inputs. ([Pull Request](https://github.com/rails/rails/pull/6359))
+
* Include `mounted_helpers` (helpers for accessing mounted engines) in `ActionDispatch::IntegrationTest` by default.
* Added `ActionDispatch::SSL` middleware that when included force all the requests to be under HTTPS protocol.
@@ -577,7 +596,7 @@ Active Record
store :settings, accessors: [ :color, :homepage ], coder: JSON
```
-* `mysql` and `mysql2` connections will set `SQL_MODE=STRICT_ALL_TABLES` by default to avoid silent data loss. This can be disabled by specifying `strict: false` in `config/database.yml`.
+* `mysql` and `mysql2` connections will set `SQL_MODE=STRICT_ALL_TABLES` by default to avoid silent data loss. This can be disabled by specifying `strict: false` in `config/database.yml`. ([Pull Request](https://github.com/rails/rails/pull/6069))
* Added default order to `ActiveRecord::Base#first` to assure consistent results among different database engines. Introduced `ActiveRecord::Base#take` as a replacement to the old behavior.
@@ -614,7 +633,7 @@ Active Record
* Remove IdentityMap - IdentityMap has never graduated to be an "enabled-by-default" feature, due to some inconsistencies with associations, as described in this [commit](https://github.com/rails/rails/commit/302c912bf6bcd0fa200d964ec2dc4a44abe328a6). Hence the removal from the codebase, until such issues are fixed.
-* Added a feature to dump/load internal state of `SchemaCache` instance because we want to boot more quickly when we have many models.
+* Added a feature to dump/load internal state of `SchemaCache` instance because we want to boot more quickly when we have many models. ([Pull Request](https://github.com/rails/rails/pull/5162))
```ruby
# execute rake task.
@@ -685,6 +704,8 @@ Active Record
* PostgreSQL hstore types are automatically deserialized from the database.
+* Support for array datatype in PostgreSQL. ([Pull Request](https://github.com/rails/rails/pull/7547))
+
* Added `#update_columns` method which updates the attributes from the passed-in hash without calling save, hence skipping validations and callbacks. `ActiveRecordError` will be raised when called on new objects or when at least one of the attributes is marked as read only.
```ruby
@@ -819,7 +840,7 @@ Active Model
* `ConfirmationValidator` error messages will attach to `:#{attribute}_confirmation` instead of `attribute`.
-* Added `ActiveModel::Model`, a mixin to make Ruby objects work with Action Pack out of the box.
+* Added `ActiveModel::Model`, a mixin to make Ruby objects work with Action Pack out of the box. ([Pull Request](https://github.com/rails/rails/pull/5253))
* `ActiveModel::Errors#to_json` supports a new parameter `:full_messages`.
diff --git a/guides/source/active_record_callbacks.md b/guides/source/active_record_callbacks.md
new file mode 100644
index 0000000000..c45f3f2e6a
--- /dev/null
+++ b/guides/source/active_record_callbacks.md
@@ -0,0 +1,361 @@
+Active Record Callbacks
+=======================
+
+This guide teaches you how to hook into the life cycle of your Active Record
+objects.
+
+After reading this guide and trying out the presented concepts, we hope that you'll be able to:
+
+* Understand the life cycle of Active Record objects
+* Create callback methods that respond to events in the object life cycle
+* Create special classes that encapsulate common behavior for your callbacks
+
+--------------------------------------------------------------------------------
+
+The Object Life Cycle
+---------------------
+
+During the normal operation of a Rails application, objects may be created, updated, and destroyed. Active Record provides hooks into this <em>object life cycle</em> so that you can control your application and its data.
+
+Callbacks allow you to trigger logic before or after an alteration of an object's state.
+
+Callbacks Overview
+------------------
+
+Callbacks are methods that get called at certain moments of an object's life cycle. With callbacks it is possible to write code that will run whenever an Active Record object is created, saved, updated, deleted, validated, or loaded from the database.
+
+### Callback Registration
+
+In order to use the available callbacks, you need to register them. You can implement the callbacks as ordinary methods and use a macro-style class method to register them as callbacks:
+
+```ruby
+class User < ActiveRecord::Base
+ validates :login, :email, presence: true
+
+ before_validation :ensure_login_has_a_value
+
+ protected
+ def ensure_login_has_a_value
+ if login.nil?
+ self.login = email unless email.blank?
+ end
+ end
+end
+```
+
+The macro-style class methods can also receive a block. Consider using this style if the code inside your block is so short that it fits in a single line:
+
+```ruby
+class User < ActiveRecord::Base
+ validates :login, :email, presence: true
+
+ before_create do |user|
+ user.name = user.login.capitalize if user.name.blank?
+ end
+end
+```
+
+Callbacks can also be registered to only fire on certain lifecycle events:
+
+```ruby
+class User < ActiveRecord::Base
+ before_validation :normalize_name, on: :create
+
+ # :on takes an array as well
+ after_validation :set_location, on: [ :create, :update ]
+
+ protected
+ def normalize_name
+ self.name = self.name.downcase.titleize
+ end
+
+ def set_location
+ self.location = LocationService.query(self)
+ end
+end
+```
+
+It is considered good practice to declare callback methods as protected or private. If left public, they can be called from outside of the model and violate the principle of object encapsulation.
+
+Available Callbacks
+-------------------
+
+Here is a list with all the available Active Record callbacks, listed in the same order in which they will get called during the respective operations:
+
+### Creating an Object
+
+* `before_validation`
+* `after_validation`
+* `before_save`
+* `around_save`
+* `before_create`
+* `around_create`
+* `after_create`
+* `after_save`
+
+### Updating an Object
+
+* `before_validation`
+* `after_validation`
+* `before_save`
+* `around_save`
+* `before_update`
+* `around_update`
+* `after_update`
+* `after_save`
+
+### Destroying an Object
+
+* `before_destroy`
+* `around_destroy`
+* `after_destroy`
+
+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.
+
+### `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.
+
+The `after_find` callback will be called whenever Active Record loads a record from the database. `after_find` is called before `after_initialize` if both are defined.
+
+The `after_initialize` and `after_find` callbacks have no `before_*` counterparts, but they can be registered just like the other Active Record callbacks.
+
+```ruby
+class User < ActiveRecord::Base
+ after_initialize do |user|
+ puts "You have initialized an object!"
+ end
+
+ after_find do |user|
+ puts "You have found an object!"
+ end
+end
+
+>> User.new
+You have initialized an object!
+=> #<User id: nil>
+
+>> User.first
+You have found an object!
+You have initialized an object!
+=> #<User id: 1>
+```
+
+Running Callbacks
+-----------------
+
+The following methods trigger callbacks:
+
+* `create`
+* `create!`
+* `decrement!`
+* `destroy`
+* `destroy_all`
+* `increment!`
+* `save`
+* `save!`
+* `save(validate: false)`
+* `toggle!`
+* `update`
+* `update_attribute`
+* `update_attributes`
+* `update_attributes!`
+* `valid?`
+
+Additionally, the `after_find` callback is triggered by the following finder methods:
+
+* `all`
+* `first`
+* `find`
+* `find_all_by_*`
+* `find_by_*`
+* `find_by_*!`
+* `find_by_sql`
+* `last`
+
+The `after_initialize` callback is triggered every time a new object of the class is initialized.
+
+NOTE: The `find_all_by_*`, `find_by_*` and `find_by_*!` methods are dynamic finders generated automatically for every attribute. Learn more about them at the [Dynamic finders section](active_record_querying.html#dynamic-finders)
+
+Skipping Callbacks
+------------------
+
+Just as with validations, it is also possible to skip callbacks. These methods should be used with caution, however, because important business rules and application logic may be kept in callbacks. Bypassing them without understanding the potential implications may lead to invalid data.
+
+* `decrement`
+* `decrement_counter`
+* `delete`
+* `delete_all`
+* `increment`
+* `increment_counter`
+* `toggle`
+* `touch`
+* `update_column`
+* `update_columns`
+* `update_all`
+* `update_counters`
+
+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 <em>before</em> callback method returns exactly `false` or raises an exception, the execution chain gets halted and a ROLLBACK is issued; <em>after</em> callbacks can only accomplish that by raising an exception.
+
+WARNING. Raising an arbitrary exception may break code that expects `save` and its friends not to fail like that. The `ActiveRecord::Rollback` exception is thought precisely to tell Active Record a rollback is going on. That one is internally captured but not reraised.
+
+Relational Callbacks
+--------------------
+
+Callbacks work through model relationships, and can even be defined by them. Suppose an example where a user has many posts. A user's posts should be destroyed if the user is destroyed. Let's add an `after_destroy` callback to the `User` model by way of its relationship to the `Post` model:
+
+```ruby
+class User < ActiveRecord::Base
+ has_many :posts, dependent: :destroy
+end
+
+class Post < ActiveRecord::Base
+ after_destroy :log_destroy_action
+
+ def log_destroy_action
+ puts 'Post destroyed'
+ end
+end
+
+>> user = User.first
+=> #<User id: 1>
+>> user.posts.create!
+=> #<Post id: 1, user_id: 1>
+>> user.destroy
+Post destroyed
+=> #<User id: 1>
+```
+
+Conditional Callbacks
+---------------------
+
+As with validations, we can also make the calling of a callback method conditional on the satisfaction of a given predicate. We can do this using the `:if` and `:unless` options, which can take a symbol, a string, a `Proc` or an `Array`. You may use the `:if` option when you want to specify under which conditions the callback **should** be called. If you want to specify the conditions under which the callback **should not** be called, then you may use the `:unless` option.
+
+### Using `:if` and `:unless` with a `Symbol`
+
+You can associate the `:if` and `:unless` options with a symbol corresponding to the name of a predicate method that will get called right before the callback. When using the `:if` option, the callback won't be executed if the predicate method returns false; when using the `:unless` option, the callback won't be executed if the predicate method returns true. This is the most common option. Using this form of registration it is also possible to register several different predicates that should be called to check if the callback should be executed.
+
+```ruby
+class Order < ActiveRecord::Base
+ before_save :normalize_card_number, if: :paid_with_card?
+end
+```
+
+### Using `:if` and `:unless` with a String
+
+You can also use a string that will be evaluated using `eval` and hence needs to contain valid Ruby code. You should use this option only when the string represents a really short condition:
+
+```ruby
+class Order < ActiveRecord::Base
+ before_save :normalize_card_number, if: "paid_with_card?"
+end
+```
+
+### Using `:if` and `:unless` with a `Proc`
+
+Finally, it is possible to associate `:if` and `:unless` with a `Proc` object. This option is best suited when writing short validation methods, usually one-liners:
+
+```ruby
+class Order < ActiveRecord::Base
+ before_save :normalize_card_number,
+ if: Proc.new { |order| order.paid_with_card? }
+end
+```
+
+### Multiple Conditions for Callbacks
+
+When writing conditional callbacks, it is possible to mix both `:if` and `:unless` in the same callback declaration:
+
+```ruby
+class Comment < ActiveRecord::Base
+ after_create :send_email_to_author, if: :author_wants_emails?,
+ unless: Proc.new { |comment| comment.post.ignore_comments? }
+end
+```
+
+Callback Classes
+----------------
+
+Sometimes the callback methods that you'll write will be useful enough to be reused by other models. Active Record makes it possible to create classes that encapsulate the callback methods, so it becomes very easy to reuse them.
+
+Here's an example where we create a class with an `after_destroy` callback for a `PictureFile` model:
+
+```ruby
+class PictureFileCallbacks
+ def after_destroy(picture_file)
+ if File.exists?(picture_file.filepath)
+ File.delete(picture_file.filepath)
+ end
+ end
+end
+```
+
+When declared inside a class, as above, the callback methods will receive the model object as a parameter. We can now use the callback class in the model:
+
+```ruby
+class PictureFile < ActiveRecord::Base
+ after_destroy PictureFileCallbacks.new
+end
+```
+
+Note that we needed to instantiate a new `PictureFileCallbacks` object, since we declared our callback as an instance method. This is particularly useful if the callbacks make use of the state of the instantiated object. Often, however, it will make more sense to declare the callbacks as class methods:
+
+```ruby
+class PictureFileCallbacks
+ def self.after_destroy(picture_file)
+ if File.exists?(picture_file.filepath)
+ File.delete(picture_file.filepath)
+ end
+ end
+end
+```
+
+If the callback method is declared this way, it won't be necessary to instantiate a `PictureFileCallbacks` object.
+
+```ruby
+class PictureFile < ActiveRecord::Base
+ after_destroy PictureFileCallbacks
+end
+```
+
+You can declare as many callbacks as you want inside your callback classes.
+
+Transaction Callbacks
+---------------------
+
+There are two additional callbacks that are triggered by the completion of a database transaction: `after_commit` and `after_rollback`. These callbacks are very similar to the `after_save` callback except that they don't execute until after database changes have either been committed or rolled back. They are most useful when your active record models need to interact with external systems which are not part of the database transaction.
+
+Consider, for example, the previous example where the `PictureFile` model needs to delete a file after the corresponding record is destroyed. If anything raises an exception after the `after_destroy` callback is called and the transaction rolls back, the file will have been deleted and the model will be left in an inconsistent state. For example, suppose that `picture_file_2` in the code below is not valid and the `save!` method raises an error.
+
+```ruby
+PictureFile.transaction do
+ picture_file_1.destroy
+ picture_file_2.save!
+end
+```
+
+By using the `after_commit` callback we can account for this case.
+
+```ruby
+class PictureFile < ActiveRecord::Base
+ attr_accessor :delete_file
+
+ after_destroy do |picture_file|
+ picture_file.delete_file = picture_file.filepath
+ end
+
+ after_commit do |picture_file|
+ if picture_file.delete_file && File.exist?(picture_file.delete_file)
+ File.delete(picture_file.delete_file)
+ picture_file.delete_file = nil
+ end
+ end
+end
+```
+
+The `after_commit` and `after_rollback` callbacks are guaranteed to be called for all models created, updated, or destroyed within a transaction block. If any exceptions are raised within one of these callbacks, they will be ignored so that they don't interfere with the other callbacks. As such, if your callback code could raise an exception, you'll need to rescue it and handle it appropriately within the callback.
diff --git a/guides/source/active_record_validations_callbacks.md b/guides/source/active_record_validations.md
index 18b73d8805..541b1a1e84 100644
--- a/guides/source/active_record_validations_callbacks.md
+++ b/guides/source/active_record_validations.md
@@ -1,7 +1,8 @@
-Active Record Validations and Callbacks
-=======================================
+Active Record Validations
+=========================
-This guide teaches you how to hook into the life cycle of your Active Record objects. You will learn how to validate the state of objects before they go into the database, and how to perform custom operations at certain points in the object life cycle.
+This guide teaches you how to validate the state of objects before they go into
+the database using Active Record's validations feature.
After reading this guide, you will know:
@@ -11,17 +12,9 @@ After reading this guide, you will know:
* Work with the error messages generated by the validation process.
* Create callback methods that respond to events in the object life cycle.
* Create special classes that encapsulate common behavior for your callbacks.
-* Create Observers that respond to life cycle events outside of the original class.
--------------------------------------------------------------------------------
-The Object Life Cycle
----------------------
-
-During the normal operation of a Rails application, objects may be created, updated, and destroyed. Active Record provides hooks into this <em>object life cycle</em> so that you can control your application and its data.
-
-Validations allow you to ensure that only valid data is stored in your database. Callbacks and observers allow you to trigger logic before or after an alteration of an object's state.
-
Validations Overview
--------------------
@@ -973,408 +966,3 @@ end
The result looks like the following:
![Validation error messages](images/validation_error_messages.png)
-
-Callbacks Overview
-------------------
-
-Callbacks are methods that get called at certain moments of an object's life cycle. With callbacks it is possible to write code that will run whenever an Active Record object is created, saved, updated, deleted, validated, or loaded from the database.
-
-### Callback Registration
-
-In order to use the available callbacks, you need to register them. You can implement the callbacks as ordinary methods and use a macro-style class method to register them as callbacks:
-
-```ruby
-class User < ActiveRecord::Base
- validates :login, :email, presence: true
-
- before_validation :ensure_login_has_a_value
-
- protected
- def ensure_login_has_a_value
- if login.nil?
- self.login = email unless email.blank?
- end
- end
-end
-```
-
-The macro-style class methods can also receive a block. Consider using this style if the code inside your block is so short that it fits in a single line:
-
-```ruby
-class User < ActiveRecord::Base
- validates :login, :email, presence: true
-
- before_create do |user|
- user.name = user.login.capitalize if user.name.blank?
- end
-end
-```
-
-Callbacks can also be registered to only fire on certain lifecycle events:
-
-```ruby
-class User < ActiveRecord::Base
- before_validation :normalize_name, on: :create
-
- # :on takes an array as well
- after_validation :set_location, on: [ :create, :update ]
-
- protected
- def normalize_name
- self.name = self.name.downcase.titleize
- end
-
- def set_location
- self.location = LocationService.query(self)
- end
-end
-```
-
-It is considered good practice to declare callback methods as protected or private. If left public, they can be called from outside of the model and violate the principle of object encapsulation.
-
-Available Callbacks
--------------------
-
-Here is a list with all the available Active Record callbacks, listed in the same order in which they will get called during the respective operations:
-
-### Creating an Object
-
-* `before_validation`
-* `after_validation`
-* `before_save`
-* `around_save`
-* `before_create`
-* `around_create`
-* `after_create`
-* `after_save`
-
-### Updating an Object
-
-* `before_validation`
-* `after_validation`
-* `before_save`
-* `around_save`
-* `before_update`
-* `around_update`
-* `after_update`
-* `after_save`
-
-### Destroying an Object
-
-* `before_destroy`
-* `around_destroy`
-* `after_destroy`
-
-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.
-
-### `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.
-
-The `after_find` callback will be called whenever Active Record loads a record from the database. `after_find` is called before `after_initialize` if both are defined.
-
-The `after_initialize` and `after_find` callbacks have no `before_*` counterparts, but they can be registered just like the other Active Record callbacks.
-
-```ruby
-class User < ActiveRecord::Base
- after_initialize do |user|
- puts "You have initialized an object!"
- end
-
- after_find do |user|
- puts "You have found an object!"
- end
-end
-
->> User.new
-You have initialized an object!
-=> #<User id: nil>
-
->> User.first
-You have found an object!
-You have initialized an object!
-=> #<User id: 1>
-```
-
-Running Callbacks
------------------
-
-The following methods trigger callbacks:
-
-* `create`
-* `create!`
-* `decrement!`
-* `destroy`
-* `destroy_all`
-* `increment!`
-* `save`
-* `save!`
-* `save(validate: false)`
-* `toggle!`
-* `update`
-* `update_attribute`
-* `update_attributes`
-* `update_attributes!`
-* `valid?`
-
-Additionally, the `after_find` callback is triggered by the following finder methods:
-
-* `all`
-* `first`
-* `find`
-* `find_all_by_*`
-* `find_by_*`
-* `find_by_*!`
-* `find_by_sql`
-* `last`
-
-The `after_initialize` callback is triggered every time a new object of the class is initialized.
-
-NOTE: The `find_all_by_*`, `find_by_*` and `find_by_*!` methods are dynamic finders generated automatically for every attribute. Learn more about them at the [Dynamic finders section](active_record_querying.html#dynamic-finders)
-
-Skipping Callbacks
-------------------
-
-Just as with validations, it is also possible to skip callbacks. These methods should be used with caution, however, because important business rules and application logic may be kept in callbacks. Bypassing them without understanding the potential implications may lead to invalid data.
-
-* `decrement`
-* `decrement_counter`
-* `delete`
-* `delete_all`
-* `increment`
-* `increment_counter`
-* `toggle`
-* `touch`
-* `update_column`
-* `update_columns`
-* `update_all`
-* `update_counters`
-
-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 <em>before</em> callback method returns exactly `false` or raises an exception, the execution chain gets halted and a ROLLBACK is issued; <em>after</em> callbacks can only accomplish that by raising an exception.
-
-WARNING. Raising an arbitrary exception may break code that expects `save` and its friends not to fail like that. The `ActiveRecord::Rollback` exception is thought precisely to tell Active Record a rollback is going on. That one is internally captured but not reraised.
-
-Relational Callbacks
---------------------
-
-Callbacks work through model relationships, and can even be defined by them. Suppose an example where a user has many posts. A user's posts should be destroyed if the user is destroyed. Let's add an `after_destroy` callback to the `User` model by way of its relationship to the `Post` model:
-
-```ruby
-class User < ActiveRecord::Base
- has_many :posts, dependent: :destroy
-end
-
-class Post < ActiveRecord::Base
- after_destroy :log_destroy_action
-
- def log_destroy_action
- puts 'Post destroyed'
- end
-end
-
->> user = User.first
-=> #<User id: 1>
->> user.posts.create!
-=> #<Post id: 1, user_id: 1>
->> user.destroy
-Post destroyed
-=> #<User id: 1>
-```
-
-Conditional Callbacks
----------------------
-
-As with validations, we can also make the calling of a callback method conditional on the satisfaction of a given predicate. We can do this using the `:if` and `:unless` options, which can take a symbol, a string, a `Proc` or an `Array`. You may use the `:if` option when you want to specify under which conditions the callback **should** be called. If you want to specify the conditions under which the callback **should not** be called, then you may use the `:unless` option.
-
-### Using `:if` and `:unless` with a `Symbol`
-
-You can associate the `:if` and `:unless` options with a symbol corresponding to the name of a predicate method that will get called right before the callback. When using the `:if` option, the callback won't be executed if the predicate method returns false; when using the `:unless` option, the callback won't be executed if the predicate method returns true. This is the most common option. Using this form of registration it is also possible to register several different predicates that should be called to check if the callback should be executed.
-
-```ruby
-class Order < ActiveRecord::Base
- before_save :normalize_card_number, if: :paid_with_card?
-end
-```
-
-### Using `:if` and `:unless` with a String
-
-You can also use a string that will be evaluated using `eval` and hence needs to contain valid Ruby code. You should use this option only when the string represents a really short condition:
-
-```ruby
-class Order < ActiveRecord::Base
- before_save :normalize_card_number, if: "paid_with_card?"
-end
-```
-
-### Using `:if` and `:unless` with a `Proc`
-
-Finally, it is possible to associate `:if` and `:unless` with a `Proc` object. This option is best suited when writing short validation methods, usually one-liners:
-
-```ruby
-class Order < ActiveRecord::Base
- before_save :normalize_card_number,
- if: Proc.new { |order| order.paid_with_card? }
-end
-```
-
-### Multiple Conditions for Callbacks
-
-When writing conditional callbacks, it is possible to mix both `:if` and `:unless` in the same callback declaration:
-
-```ruby
-class Comment < ActiveRecord::Base
- after_create :send_email_to_author, if: :author_wants_emails?,
- unless: Proc.new { |comment| comment.post.ignore_comments? }
-end
-```
-
-Callback Classes
-----------------
-
-Sometimes the callback methods that you'll write will be useful enough to be reused by other models. Active Record makes it possible to create classes that encapsulate the callback methods, so it becomes very easy to reuse them.
-
-Here's an example where we create a class with an `after_destroy` callback for a `PictureFile` model:
-
-```ruby
-class PictureFileCallbacks
- def after_destroy(picture_file)
- if File.exists?(picture_file.filepath)
- File.delete(picture_file.filepath)
- end
- end
-end
-```
-
-When declared inside a class, as above, the callback methods will receive the model object as a parameter. We can now use the callback class in the model:
-
-```ruby
-class PictureFile < ActiveRecord::Base
- after_destroy PictureFileCallbacks.new
-end
-```
-
-Note that we needed to instantiate a new `PictureFileCallbacks` object, since we declared our callback as an instance method. This is particularly useful if the callbacks make use of the state of the instantiated object. Often, however, it will make more sense to declare the callbacks as class methods:
-
-```ruby
-class PictureFileCallbacks
- def self.after_destroy(picture_file)
- if File.exists?(picture_file.filepath)
- File.delete(picture_file.filepath)
- end
- end
-end
-```
-
-If the callback method is declared this way, it won't be necessary to instantiate a `PictureFileCallbacks` object.
-
-```ruby
-class PictureFile < ActiveRecord::Base
- after_destroy PictureFileCallbacks
-end
-```
-
-You can declare as many callbacks as you want inside your callback classes.
-
-Observers
----------
-
-Observers are similar to callbacks, but with important differences. Whereas callbacks can pollute a model with code that isn't directly related to its purpose, observers allow you to add the same functionality without changing the code of the model. For example, it could be argued that a `User` model should not include code to send registration confirmation emails. Whenever you use callbacks with code that isn't directly related to your model, you may want to consider creating an observer instead.
-
-### Creating Observers
-
-For example, imagine a `User` model where we want to send an email every time a new user is created. Because sending emails is not directly related to our model's purpose, we should create an observer to contain the code implementing this functionality.
-
-```bash
-$ rails generate observer User
-```
-
-generates `app/models/user_observer.rb` containing the observer class `UserObserver`:
-
-```ruby
-class UserObserver < ActiveRecord::Observer
-end
-```
-
-You may now add methods to be called at the desired occasions:
-
-```ruby
-class UserObserver < ActiveRecord::Observer
- def after_create(model)
- # code to send confirmation email...
- end
-end
-```
-
-As with callback classes, the observer's methods receive the observed model as a parameter.
-
-### Registering Observers
-
-Observers are conventionally placed inside of your `app/models` directory and registered in your application's `config/application.rb` file. For example, the `UserObserver` above would be saved as `app/models/user_observer.rb` and registered in `config/application.rb` this way:
-
-```ruby
-# Activate observers that should always be running.
-config.active_record.observers = :user_observer
-```
-
-As usual, settings in `config/environments` take precedence over those in `config/application.rb`. So, if you prefer that an observer doesn't run in all environments, you can simply register it in a specific environment instead.
-
-### Sharing Observers
-
-By default, Rails will simply strip "Observer" from an observer's name to find the model it should observe. However, observers can also be used to add behavior to more than one model, and thus it is possible to explicitly specify the models that our observer should observe:
-
-```ruby
-class MailerObserver < ActiveRecord::Observer
- observe :registration, :user
-
- def after_create(model)
- # code to send confirmation email...
- end
-end
-```
-
-In this example, the `after_create` method will be called whenever a `Registration` or `User` is created. Note that this new `MailerObserver` would also need to be registered in `config/application.rb` in order to take effect:
-
-```ruby
-# Activate observers that should always be running.
-config.active_record.observers = :mailer_observer
-```
-
-Transaction Callbacks
----------------------
-
-There are two additional callbacks that are triggered by the completion of a database transaction: `after_commit` and `after_rollback`. These callbacks are very similar to the `after_save` callback except that they don't execute until after database changes have either been committed or rolled back. They are most useful when your active record models need to interact with external systems which are not part of the database transaction.
-
-Consider, for example, the previous example where the `PictureFile` model needs to delete a file after the corresponding record is destroyed. If anything raises an exception after the `after_destroy` callback is called and the transaction rolls back, the file will have been deleted and the model will be left in an inconsistent state. For example, suppose that `picture_file_2` in the code below is not valid and the `save!` method raises an error.
-
-```ruby
-PictureFile.transaction do
- picture_file_1.destroy
- picture_file_2.save!
-end
-```
-
-By using the `after_commit` callback we can account for this case.
-
-```ruby
-class PictureFile < ActiveRecord::Base
- attr_accessor :delete_file
-
- after_destroy do |picture_file|
- picture_file.delete_file = picture_file.filepath
- end
-
- after_commit do |picture_file|
- if picture_file.delete_file && File.exist?(picture_file.delete_file)
- File.delete(picture_file.delete_file)
- picture_file.delete_file = nil
- end
- end
-end
-```
-
-The `after_commit` and `after_rollback` callbacks are guaranteed to be called for all models created, updated, or destroyed within a transaction block. If any exceptions are raised within one of these callbacks, they will be ignored so that they don't interfere with the other callbacks. As such, if your callback code could raise an exception, you'll need to rescue it and handle it appropriately within the callback.
diff --git a/guides/source/active_support_core_extensions.md b/guides/source/active_support_core_extensions.md
index 2baf8c2515..775da2a85c 100644
--- a/guides/source/active_support_core_extensions.md
+++ b/guides/source/active_support_core_extensions.md
@@ -2067,14 +2067,6 @@ The sum of an empty receiver can be customized in this form as well:
[].sum(1) {|n| n**3} # => 1
```
-The method `ActiveRecord::Observer#observed_subclasses` for example is implemented this way:
-
-```ruby
-def observed_subclasses
- observed_classes.sum([]) { |klass| klass.send(:subclasses) }
-end
-```
-
NOTE: Defined in `active_support/core_ext/enumerable.rb`.
### `index_by`
@@ -3728,6 +3720,25 @@ The auxiliary file is written in a standard directory for temporary files, but y
NOTE: Defined in `active_support/core_ext/file/atomic.rb`.
+Extensions to `Marshal`
+-----------------------
+
+### `load`
+
+Active Support adds constant autoloading support to `load`.
+
+For example, the file cache store deserializes this way:
+
+```ruby
+File.open(file_name) { |f| Marshal.load(f) }
+```
+
+If the cached data refers to a constant that is unknown at that point, the autoloading mechanism is triggered and if it succeeds the deserialization is retried transparently.
+
+WARNING. If the argument is an `IO` it needs to respond to `rewind` to be able to retry. Regular files respond to `rewind`.
+
+NOTE: Defined in `active_support/core_ext/marshal.rb`.
+
Extensions to `Logger`
----------------------
diff --git a/guides/source/caching_with_rails.md b/guides/source/caching_with_rails.md
index 12115a6a47..e737dcab83 100644
--- a/guides/source/caching_with_rails.md
+++ b/guides/source/caching_with_rails.md
@@ -67,8 +67,6 @@ class ProductsController < ActionController
end
```
-If you want a more complicated expiration scheme, you can use cache sweepers to expire cached objects when things change. This is covered in the section on Sweepers.
-
By default, page caching automatically gzips files (for example, to `products.html.gz` if user requests `/products`) to reduce the size of data transmitted (web servers are typically configured to use a moderate compression ratio as a compromise, but since precompilation happens once, compression ratio is maximum).
Nginx is able to serve compressed content directly from disk by enabling `gzip_static`:
@@ -176,102 +174,6 @@ This fragment is then available to all actions in the `ProductsController` using
expire_fragment('all_available_products')
```
-### Sweepers
-
-Cache sweeping is a mechanism which allows you to get around having a ton of `expire_{page,action,fragment}` calls in your code. It does this by moving all the work required to expire cached content into an `ActionController::Caching::Sweeper` subclass. This class is an observer and looks for changes to an Active Record object via callbacks, and when a change occurs it expires the caches associated with that object in an around or after filter.
-
-TIP: Sweepers rely on the use of Active Record and Active Record Observers. The object you are observing must be an Active Record model.
-
-Continuing with our Product controller example, we could rewrite it with a sweeper like this:
-
-```ruby
-class ProductSweeper < ActionController::Caching::Sweeper
- observe Product # This sweeper is going to keep an eye on the Product model
-
- # If our sweeper detects that a Product was created call this
- def after_create(product)
- expire_cache_for(product)
- end
-
- # If our sweeper detects that a Product was updated call this
- def after_update(product)
- expire_cache_for(product)
- end
-
- # If our sweeper detects that a Product was deleted call this
- def after_destroy(product)
- expire_cache_for(product)
- end
-
- private
- def expire_cache_for(product)
- # Expire the index page now that we added a new product
- expire_page(controller: 'products', action: 'index')
-
- # Expire a fragment
- expire_fragment('all_available_products')
- end
-end
-```
-
-You may notice that the actual product gets passed to the sweeper, so if we were caching the edit action for each product, we could add an expire method which specifies the page we want to expire:
-
-```ruby
-expire_action(controller: 'products', action: 'edit', id: product.id)
-```
-
-Then we add it to our controller to tell it to call the sweeper when certain actions are called. So, if we wanted to expire the cached content for the list and edit actions when the create action was called, we could do the following:
-
-```ruby
-class ProductsController < ActionController
-
- before_filter :authenticate
- caches_action :index
- cache_sweeper :product_sweeper
-
- def index
- @products = Product.all
- end
-
-end
-```
-
-Sometimes it is necessary to disambiguate the controller when you call `expire_action`, such as when there are two identically named controllers in separate namespaces:
-
-```ruby
-class ProductsController < ActionController
- caches_action :index
-
- def index
- @products = Product.all
- end
-end
-
-module Admin
- class ProductsController < ActionController
- cache_sweeper :product_sweeper
-
- def new
- @product = Product.new
- end
-
- def create
- @product = Product.create(params[:product])
- end
- end
-end
-
-class ProductSweeper < ActionController::Caching::Sweeper
- observe Product
-
- def after_create(product)
- expire_action(controller: '/products', action: 'index')
- end
-end
-```
-
-Note the use of '/products' here rather than 'products'. If you wanted to expire an action cache for the `Admin::ProductsController`, you would use 'admin/products' instead.
-
### SQL Caching
Query caching is a Rails feature that caches the result set returned by each query so that if Rails encounters the same query again for that request, it will use the cached result set as opposed to running the query against the database again.
diff --git a/guides/source/configuring.md b/guides/source/configuring.md
index f01051a3fe..dba2be3b71 100644
--- a/guides/source/configuring.md
+++ b/guides/source/configuring.md
@@ -39,7 +39,7 @@ config.filter_parameters += [:password]
This is a setting for Rails itself. If you want to pass settings to individual Rails components, you can do so via the same `config` object in `config/application.rb`:
```ruby
-config.active_record.observers = [:hotel_observer, :review_observer]
+config.active_record.schema_format = :ruby
```
Rails will use that particular setting to configure Active Record.
@@ -616,7 +616,7 @@ Rails.application.config.before_initialize do
end
```
-WARNING: Some parts of your application, notably observers and routing, are not yet set up at the point where the `after_initialize` block is called.
+WARNING: Some parts of your application, notably routing, are not yet set up at the point where the `after_initialize` block is called.
### `Rails::Railtie#initializer`
diff --git a/guides/source/documents.yaml b/guides/source/documents.yaml
index 19425765b8..d7c648681d 100644
--- a/guides/source/documents.yaml
+++ b/guides/source/documents.yaml
@@ -13,9 +13,13 @@
url: migrations.html
description: This guide covers how you can use Active Record migrations to alter your database in a structured and organized manner.
-
- name: Active Record Validations and Callbacks
- url: active_record_validations_callbacks.html
- description: This guide covers how you can use Active Record validations and callbacks.
+ name: Active Record Validations
+ url: active_record_validations.html
+ description: This guide covers how you can use Active Record validations
+ -
+ name: Active Record Callbacks
+ url: active_record_callbacks.html
+ description: This guide covers how you can use Active Record callbacks.
-
name: Active Record Associations
url: association_basics.html