diff options
author | Rafael Mendonça França <rafaelmfranca@gmail.com> | 2012-11-28 22:49:34 -0200 |
---|---|---|
committer | Rafael Mendonça França <rafaelmfranca@gmail.com> | 2012-11-28 22:49:34 -0200 |
commit | 39e85b3b90c58449164673909a6f1893cba290b2 (patch) | |
tree | a9d92a6f70cb839bb875e9cc867ed8dec6b5944d /guides/source | |
parent | e38d310912a610ffe8a0944a533bfb9e5950f3a5 (diff) | |
parent | f862376d169acfe362552787c095ff4b93834f9c (diff) | |
download | rails-39e85b3b90c58449164673909a6f1893cba290b2.tar.gz rails-39e85b3b90c58449164673909a6f1893cba290b2.tar.bz2 rails-39e85b3b90c58449164673909a6f1893cba290b2.zip |
Merge branch 'extract_observers'
Diffstat (limited to 'guides/source')
-rw-r--r-- | guides/source/active_record_validations_callbacks.md | 67 | ||||
-rw-r--r-- | guides/source/caching_with_rails.md | 98 | ||||
-rw-r--r-- | guides/source/configuring.md | 4 |
3 files changed, 3 insertions, 166 deletions
diff --git a/guides/source/active_record_validations_callbacks.md b/guides/source/active_record_validations_callbacks.md index 0f4140b650..4432df5e76 100644 --- a/guides/source/active_record_validations_callbacks.md +++ b/guides/source/active_record_validations_callbacks.md @@ -11,7 +11,6 @@ After reading this guide and trying out the presented concepts, we hope that you * 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 -------------------------------------------------------------------------------- @@ -20,7 +19,7 @@ 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 allow you to ensure that only valid data is stored in your database. Callbacks allow you to trigger logic before or after an alteration of an object's state. Validations Overview -------------------- @@ -1272,70 +1271,6 @@ 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 --------------------- diff --git a/guides/source/caching_with_rails.md b/guides/source/caching_with_rails.md index 826ddd264a..be2cd0e1a9 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 ac763d6e0e..486dc30acc 100644 --- a/guides/source/configuring.md +++ b/guides/source/configuring.md @@ -37,7 +37,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. @@ -614,7 +614,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` |