Merge docrails
This commit is contained in:
parent
1ab7c37671
commit
632bbbfe1c
|
@ -408,7 +408,7 @@ module ActionController #:nodoc:
|
|||
|
||||
# Return an array containing the names of public methods that have been marked hidden from the action processor.
|
||||
# By default, all methods defined in ActionController::Base and included modules are hidden.
|
||||
# More methods can be hidden using <tt>hide_actions</tt>.
|
||||
# More methods can be hidden using <tt>hide_action</tt>.
|
||||
def hidden_actions
|
||||
read_inheritable_attribute(:hidden_actions) || write_inheritable_attribute(:hidden_actions, [])
|
||||
end
|
||||
|
@ -1338,6 +1338,7 @@ module ActionController #:nodoc:
|
|||
end
|
||||
end
|
||||
|
||||
# Returns true if a render or redirect has already been performed.
|
||||
def performed?
|
||||
@performed_render || @performed_redirect
|
||||
end
|
||||
|
@ -1346,6 +1347,7 @@ module ActionController #:nodoc:
|
|||
@action_name = (params['action'] || 'index')
|
||||
end
|
||||
|
||||
# Returns a set of the methods defined as actions in your controller
|
||||
def action_methods
|
||||
self.class.action_methods
|
||||
end
|
||||
|
@ -1372,6 +1374,7 @@ module ActionController #:nodoc:
|
|||
@request_origin ||= "#{request.remote_ip} at #{Time.now.to_s(:db)}"
|
||||
end
|
||||
|
||||
# Returns the request URI used to get to the current location
|
||||
def complete_request_uri
|
||||
"#{request.protocol}#{request.host}#{request.request_uri}"
|
||||
end
|
||||
|
|
|
@ -68,29 +68,17 @@ module ActionController
|
|||
# This generates, among other things, the method <tt>users_path</tt>. By default,
|
||||
# this method is accessible from your controllers, views and mailers. If you need
|
||||
# to access this auto-generated method from other places (such as a model), then
|
||||
# you can do that in two ways.
|
||||
#
|
||||
# The first way is to include ActionController::UrlWriter in your class:
|
||||
# you can do that by including ActionController::UrlWriter in your class:
|
||||
#
|
||||
# class User < ActiveRecord::Base
|
||||
# include ActionController::UrlWriter # !!!
|
||||
# include ActionController::UrlWriter
|
||||
#
|
||||
# def name=(value)
|
||||
# write_attribute('name', value)
|
||||
# write_attribute('base_uri', users_path) # !!!
|
||||
# def base_uri
|
||||
# user_path(self)
|
||||
# end
|
||||
# end
|
||||
#
|
||||
# The second way is to access them through ActionController::UrlWriter.
|
||||
# The autogenerated named routes methods are available as class methods:
|
||||
#
|
||||
# class User < ActiveRecord::Base
|
||||
# def name=(value)
|
||||
# write_attribute('name', value)
|
||||
# path = ActionController::UrlWriter.users_path # !!!
|
||||
# write_attribute('base_uri', path) # !!!
|
||||
# end
|
||||
# end
|
||||
# User.find(1).base_uri # => "/users/1"
|
||||
module UrlWriter
|
||||
def self.included(base) #:nodoc:
|
||||
ActionController::Routing::Routes.install_helpers(base)
|
||||
|
|
|
@ -175,6 +175,8 @@ module ActiveRecord
|
|||
# end # RELEASE savepoint active_record_1
|
||||
# # ^^^^ BOOM! database error!
|
||||
# end
|
||||
#
|
||||
# Note that "TRUNCATE" is also a MySQL DDL statement!
|
||||
module ClassMethods
|
||||
# See ActiveRecord::Transactions::ClassMethods for detailed documentation.
|
||||
def transaction(options = {}, &block)
|
||||
|
|
|
@ -3,5 +3,5 @@
|
|||
# You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces.
|
||||
# Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ }
|
||||
|
||||
# You can also remove all the silencers if you're trying do debug a problem that might steem from framework code.
|
||||
# You can also remove all the silencers if you're trying to debug a problem that might stem from framework code.
|
||||
# Rails.backtrace_cleaner.remove_silencers!
|
|
@ -32,7 +32,7 @@ Here's a summary of the rack-related changes:
|
|||
* +CGI::Session::MemCacheStore+ has been replaced by +ActionController::Session::MemCacheStore+.
|
||||
* +CGI::Session::ActiveRecordStore+ has been replaced by +ActiveRecord::SessionStore+.
|
||||
* You can still change your session store with +ActionController::Base.session_store = :active_record_store+.
|
||||
* Default sessions options are still set with +ActionController::Base.session = { :key => "..." }+.
|
||||
* Default sessions options are still set with +ActionController::Base.session = { :key => "..." }+. However, the +:session_domain+ option has been renamed to +:domain+.
|
||||
* The mutex that normally wraps your entire request has been moved into middleware, +ActionController::Lock+.
|
||||
* +ActionController::AbstractRequest+ and +ActionController::Request+ have been unified. The new +ActionController::Request+ inherits from +Rack::Request+. This affects access to +response.headers['type']+ in test requests. Use +response.content_type+ instead.
|
||||
* +ActiveRecord::QueryCache+ middleware is automatically inserted onto the middleware stack if +ActiveRecord+ has been loaded. This middleware sets up and flushes the per-request Active Record query cache.
|
||||
|
|
|
@ -18,9 +18,11 @@ h3. Basic Caching
|
|||
This is an introduction to the three types of caching techniques that Rails
|
||||
provides by default without the use of any third party plugins.
|
||||
|
||||
To get started make sure +config.action_controller.perform_caching+ is set
|
||||
to +true+ for your environment. This flag is normally set in the
|
||||
corresponding config/environments/*.rb. By default, caching is disabled for development and test, and enabled for production.
|
||||
To start playing with testing you'll want to ensure that
|
||||
+config.action_controller.perform_caching+ is set
|
||||
to +true+ if you're running in development mode. This flag is normally set in the
|
||||
corresponding config/environments/*.rb and caching is disabled by default
|
||||
for development and test, and enabled for production.
|
||||
|
||||
<ruby>
|
||||
config.action_controller.perform_caching = true
|
||||
|
@ -29,51 +31,56 @@ config.action_controller.perform_caching = true
|
|||
h4. Page Caching
|
||||
|
||||
Page caching is a Rails mechanism which allows the request for a generated
|
||||
page to be fulfilled by the webserver, without ever having to go through the
|
||||
page to be fulfilled by the webserver (i.e. apache or nginx), without ever having to go through the
|
||||
Rails stack at all. Obviously, this is super-fast. Unfortunately, it can't be
|
||||
applied to every situation (such as pages that need authentication) and since
|
||||
the webserver is literally just serving a file from the filesystem, cache
|
||||
expiration is an issue that needs to be dealt with.
|
||||
|
||||
So, how do you enable this super-fast cache behavior? Suppose you
|
||||
So, how do you enable this super-fast cache behavior? Simple, let's say you
|
||||
have a controller called +ProductsController+ and an +index+ action that lists all
|
||||
the products. You could enable caching for this action like this:
|
||||
the products
|
||||
|
||||
<ruby>
|
||||
class ProductsController < ActionController
|
||||
|
||||
caches_page :index
|
||||
|
||||
def index; end
|
||||
def index
|
||||
@products = Products.all
|
||||
end
|
||||
|
||||
end
|
||||
</ruby>
|
||||
|
||||
The first time anyone requests products/index, Rails will generate a file
|
||||
called +index.html+. If a web server see this file, it will be served in response to the
|
||||
next request for products/index, without your Rails application being called.
|
||||
The first time anyone requests +/products+, Rails will generate a file
|
||||
called +products.html+ and the webserver will then look for that file before it
|
||||
passes the next request for +/products+ to your Rails application.
|
||||
|
||||
By default, the page cache directory is set to Rails.public_path (which is
|
||||
usually set to +File.join(self.root, "public")+ - that is, the public directory under your Rails application's root). This can be configured by
|
||||
By default, the page cache directory is set to +Rails.public_path+ (which is
|
||||
usually set to the +public+ folder) and this can be configured by
|
||||
changing the configuration setting +config.action_controller.page_cache_directory+.
|
||||
Changing the default from /public helps avoid naming conflicts, since you may
|
||||
want to put other static html in /public, but changing this will require web
|
||||
Changing the default from +public+ helps avoid naming conflicts, since you may
|
||||
want to put other static html in +public+, but changing this will require web
|
||||
server reconfiguration to let the web server know where to serve the cached
|
||||
files from.
|
||||
|
||||
The page caching mechanism will automatically add a +.html+ extension to
|
||||
The Page Caching mechanism will automatically add a +.html+ extension to
|
||||
requests for pages that do not have an extension to make it easy for the
|
||||
webserver to find those pages. This can be configured by changing the
|
||||
webserver to find those pages and this can be configured by changing the
|
||||
configuration setting +config.action_controller.page_cache_extension+.
|
||||
|
||||
In order to expire this page when a new product is added you could extend the products controller like this:
|
||||
In order to expire this page when a new product is added we could extend our
|
||||
example controller like this:
|
||||
|
||||
<ruby>
|
||||
class ProductsController < ActionController
|
||||
|
||||
caches_page :index
|
||||
|
||||
def index; end
|
||||
def index
|
||||
@products = Products.all
|
||||
end
|
||||
|
||||
def create
|
||||
expire_page :action => :index
|
||||
|
@ -85,45 +92,42 @@ 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.
|
||||
|
||||
Note: Page caching ignores all parameters, so /products/list?page=1 will be written out to the filesystem as /products/list.html and if someone requests /products/list?page=2, they will be returned the same result as page=1. Be careful when page caching GET parameters in the URL!
|
||||
Note: Page caching ignores all parameters. For example +/products?page=1+ will be written out to the filesystem as +products.html+ with no reference to the +page+ parameter. Thus, if someone requests +/products?page=2+ later, they will get the cached first page. Be careful when page caching GET parameters in the URL!
|
||||
|
||||
h4. Action Caching
|
||||
|
||||
One of the issues with page caching is that you cannot use it for pages that
|
||||
require checking code to determine whether the user should be permitted access. This is where Action Caching comes in.
|
||||
action caching works like page caching except for the fact that the incoming
|
||||
web request does go from the web server to the Rails stack and Action Pack so
|
||||
that before filters can be run on it before the cache is served. This allows you to use
|
||||
authentication and other restrictions while still serving the
|
||||
One of the issues with Page Caching is that you cannot use it for pages that
|
||||
require to restrict access somehow. This is where Action Caching comes in.
|
||||
Action Caching works like Page Caching except for the fact that the incoming
|
||||
web request does go from the webserver to the Rails stack and Action Pack so
|
||||
that before filters can be run on it before the cache is served. This allows
|
||||
authentication and other restriction to be run while still serving the
|
||||
result of the output from a cached copy.
|
||||
|
||||
Clearing the cache works in the exact same way as with page caching.
|
||||
Clearing the cache works in the exact same way as with Page Caching.
|
||||
|
||||
Let's say you only wanted authenticated users to edit or create a Product
|
||||
object, but still cache those pages:
|
||||
Let's say you only wanted authenticated users to call actions on +ProductsController+.
|
||||
|
||||
<ruby>
|
||||
class ProductsController < ActionController
|
||||
|
||||
before_filter :authenticate, :only => [ :edit, :create ]
|
||||
caches_page :index
|
||||
caches_action :edit
|
||||
before_filter :authenticate
|
||||
caches_action :index
|
||||
|
||||
def index; end
|
||||
|
||||
def create
|
||||
expire_page :action => :index
|
||||
expire_action :action => :edit
|
||||
def index
|
||||
@products = Product.all
|
||||
end
|
||||
|
||||
def edit; end
|
||||
def create
|
||||
expire_action :action => :index
|
||||
end
|
||||
|
||||
end
|
||||
</ruby>
|
||||
|
||||
You can also use +:if+ (or +:unless+) to pass a Proc that specifies when the
|
||||
action should be cached. Also, you can use +:layout => false+ to cache without
|
||||
layout so that dynamic information in the layout such as the name of the logged-in user
|
||||
layout so that dynamic information in the layout such as logged in user info
|
||||
or the number of items in the cart can be left uncached. This feature is
|
||||
available as of Rails 2.2.
|
||||
|
||||
|
@ -149,7 +153,7 @@ Fragment Caching allows a fragment of view logic to be wrapped in a cache
|
|||
block and served out of the cache store when the next request comes in.
|
||||
|
||||
As an example, if you wanted to show all the orders placed on your website
|
||||
in real time and didn't want to cache that part of the page, but did want
|
||||
in real time and didn't want to cache that part of the page, but did want
|
||||
to cache the part of the page which lists all products available, you
|
||||
could use this piece of code:
|
||||
|
||||
|
@ -160,35 +164,33 @@ could use this piece of code:
|
|||
|
||||
<% cache do %>
|
||||
All available products:
|
||||
<% Product.find(:all).each do |p| %>
|
||||
<% Product.all.each do |p| %>
|
||||
<%= link_to p.name, product_url(p) %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</ruby>
|
||||
|
||||
The cache block in our example will bind to the action that called it and is
|
||||
written out to the same place as the action cache, which means that if you
|
||||
written out to the same place as the Action Cache, which means that if you
|
||||
want to cache multiple fragments per action, you should provide an +action_suffix+ to the cache call:
|
||||
|
||||
<ruby>
|
||||
<% cache(:action => 'recent', :action_suffix => 'all_prods') do %>
|
||||
<% cache(:action => 'recent', :action_suffix => 'all_products') do %>
|
||||
All available products:
|
||||
</ruby>
|
||||
|
||||
You can expire the cache using the +expire_fragment+ method, like so:
|
||||
and you can expire it using the +expire_fragment+ method, like so:
|
||||
|
||||
<ruby>
|
||||
expire_fragment(:controller => 'products', :action => 'recent',
|
||||
:action_suffix => 'all_prods)
|
||||
expire_fragment(:controller => 'products', :action => 'recent', :action_suffix => 'all_products')
|
||||
</ruby>
|
||||
|
||||
If you don't want the cache block to bind to the action that called it, you can
|
||||
also use globally keyed fragments. To do this, call the +cache+ method with a key, like
|
||||
If you don't want the cache block to bind to the action that called it, You can
|
||||
also use globally keyed fragments by calling the +cache+ method with a key, like
|
||||
so:
|
||||
|
||||
<ruby>
|
||||
<% cache(:key =>
|
||||
['all_available_products', @latest_product.created_at].join(':')) do %>
|
||||
<% cache('all_available_products') do %>
|
||||
All available products:
|
||||
<% end %>
|
||||
</ruby>
|
||||
|
@ -197,16 +199,15 @@ This fragment is then available to all actions in the +ProductsController+ using
|
|||
the key and can be expired the same way:
|
||||
|
||||
<ruby>
|
||||
expire_fragment(:key =>
|
||||
['all_available_products', @latest_product.created_at].join(':'))
|
||||
expire_fragment('all_available_products')
|
||||
</ruby>
|
||||
|
||||
h4. 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 na +ActionController::Caching::Sweeper+
|
||||
class. This class is an Observer that looks for changes to an object via callbacks,
|
||||
+expire_{page,action,fragment}+ calls in your code. It does this by moving all the work
|
||||
required to expire cached content into a +ActionController::Caching::Sweeper+
|
||||
class. This class is an Observer and looks for changes to an object via callbacks,
|
||||
and when a change occurs it expires the caches associated with that object in
|
||||
an around or after filter.
|
||||
|
||||
|
@ -214,9 +215,8 @@ Continuing with our Product controller example, we could rewrite it with a
|
|||
sweeper like this:
|
||||
|
||||
<ruby>
|
||||
class StoreSweeper < ActionController::Caching::Sweeper
|
||||
# This sweeper is going to keep an eye on the Product model
|
||||
observe Product
|
||||
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)
|
||||
|
@ -234,91 +234,82 @@ class StoreSweeper < ActionController::Caching::Sweeper
|
|||
end
|
||||
|
||||
private
|
||||
def expire_cache_for(record)
|
||||
# Expire the list page now that we added a new product
|
||||
expire_page(:controller => '#{record}', :action => 'list')
|
||||
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(:controller => '#{record}',
|
||||
:action => 'recent', :action_suffix => 'all_products')
|
||||
expire_fragment('all_available_products')
|
||||
end
|
||||
end
|
||||
</ruby>
|
||||
|
||||
The sweeper has to be added to the controller that will use it. So, if we wanted to expire the cached content for the
|
||||
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 a expire method
|
||||
which specifies the page we want to expire:
|
||||
|
||||
<ruby>
|
||||
expire_action(:controller => 'products', :action => 'edit', :id => product)
|
||||
</ruby>
|
||||
|
||||
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, :only => [ :edit, :create ]
|
||||
caches_page :list
|
||||
caches_action :edit
|
||||
cache_sweeper :store_sweeper, :only => [ :create ]
|
||||
before_filter :authenticate
|
||||
caches_action :index
|
||||
cache_sweeper :product_sweeper
|
||||
|
||||
def list; end
|
||||
|
||||
def create
|
||||
expire_page :action => :list
|
||||
expire_action :action => :edit
|
||||
def index
|
||||
@products = Product.all
|
||||
end
|
||||
|
||||
def edit; end
|
||||
|
||||
end
|
||||
</ruby>
|
||||
|
||||
h4. SQL Caching
|
||||
|
||||
Query caching is a Rails feature that caches the result set returned by each
|
||||
query. If Rails encounters the same query again during the current request, it
|
||||
query so that if Rails encounters the same query again for that request, it
|
||||
will used the cached result set as opposed to running the query against the
|
||||
database.
|
||||
database again.
|
||||
|
||||
For example:
|
||||
|
||||
<ruby>
|
||||
class ProductsController < ActionController
|
||||
|
||||
before_filter :authenticate, :only => [ :edit, :create ]
|
||||
caches_page :list
|
||||
caches_action :edit
|
||||
cache_sweeper :store_sweeper, :only => [ :create ]
|
||||
|
||||
def list
|
||||
def index
|
||||
# Run a find query
|
||||
Product.find(:all)
|
||||
@products = Product.all
|
||||
|
||||
...
|
||||
|
||||
# Run the same query again
|
||||
Product.find(:all)
|
||||
@products = Product.all
|
||||
end
|
||||
|
||||
def create
|
||||
expire_page :action => :list
|
||||
expire_action :action => :edit
|
||||
end
|
||||
|
||||
def edit; end
|
||||
|
||||
end
|
||||
</ruby>
|
||||
|
||||
In the 'list' action above, the result set returned by the first
|
||||
Product.find(:all) will be cached and will be used to avoid querying the
|
||||
database again the second time that finder is called.
|
||||
The second time the same query is run against the database, it's not actually
|
||||
going to hit the database. The first time the result is returned from the query
|
||||
it is stored in the query cache (in memory) and the second time it's pulled from memory.
|
||||
|
||||
Query caches are created at the start of an action and destroyed at the end of
|
||||
that action and thus persist only for the duration of the action.
|
||||
However, it's important to note that query caches are created at the start of an action and destroyed at the end of
|
||||
that action and thus persist only for the duration of the action. If you'd like to store query results in a more
|
||||
persistent fashion, you can in Rails by using low level caching.
|
||||
|
||||
h4. Cache Stores
|
||||
h4. Cache stores
|
||||
|
||||
Rails (as of 2.1) provides different stores for the cached data created by action and
|
||||
fragment caches. Page caches are always stored on disk.
|
||||
|
||||
Rails 2.1 and above provide ActiveSupport::Cache::Store which can be used to
|
||||
Rails 2.1 and above provide +ActiveSupport::Cache::Store+ which can be used to
|
||||
cache strings. Some cache store implementations, like MemoryStore, are able to
|
||||
cache arbitrary Ruby objects, but don't count on every cache store to be able
|
||||
to do that.
|
||||
|
@ -344,12 +335,13 @@ need thread-safety.
|
|||
ActionController::Base.cache_store = :memory_store
|
||||
</ruby>
|
||||
|
||||
2) ActiveSupport::Cache::FileStore: Cached data is stored on the disk. This is
|
||||
2) ActiveSupport::Cache::FileStore: Cached data is stored on the disk, this is
|
||||
the default store and the default path for this store is: /tmp/cache. Works
|
||||
well for all types of environments and allows all processes running from the
|
||||
same application directory to access the cached content. If /tmp/cache does not
|
||||
exist, the default store becomes MemoryStore.
|
||||
|
||||
|
||||
<ruby>
|
||||
ActionController::Base.cache_store = :file_store, "/path/to/cache/directory"
|
||||
</ruby>
|
||||
|
@ -359,6 +351,7 @@ DRb process that all servers communicate with. This works for all environments
|
|||
and only keeps one cache around for all processes, but requires that you run
|
||||
and manage a separate DRb process.
|
||||
|
||||
|
||||
<ruby>
|
||||
ActionController::Base.cache_store = :drb_store, "druby://localhost:9192"
|
||||
</ruby>
|
||||
|
@ -368,28 +361,26 @@ Rails uses the bundled memcached-client gem by default. This is currently the
|
|||
most popular cache store for production websites.
|
||||
|
||||
Special features:
|
||||
|
||||
* Clustering and load balancing. One can specify multiple memcached servers,
|
||||
* Clustering and load balancing. One can specify multiple memcached servers,
|
||||
and MemCacheStore will load balance between all available servers. If a
|
||||
server goes down, then MemCacheStore will ignore it until it goes back
|
||||
online.
|
||||
* Time-based expiry support. See +write+ and the +:expires_in+ option.
|
||||
* Per-request in memory cache for all communication with the MemCache server(s).
|
||||
* Time-based expiry support. See +write+ and the +:expires_in+ option.
|
||||
* Per-request in memory cache for all communication with the MemCache server(s).
|
||||
|
||||
It also accepts a hash of additional options:
|
||||
|
||||
* +:namespace+- specifies a string that will automatically be prepended to keys when accessing the memcached store.
|
||||
* +:readonly+- a boolean value that when set to true will make the store read-only, with an error raised on any attempt to write.
|
||||
* +:multithread+ - a boolean value that adds thread safety to read/write operations - it is unlikely you'll need to use this option as the Rails threadsafe! method offers the same functionality.
|
||||
* +:namespace+- specifies a string that will automatically be prepended to keys when accessing the memcached store.
|
||||
* +:readonly+- a boolean value that when set to true will make the store read-only, with an error raised on any attempt to write.
|
||||
* +:multithread+ - a boolean value that adds thread safety to read/write operations - it is unlikely you'll need to use this option as the Rails threadsafe! method offers the same functionality.
|
||||
|
||||
The read and write methods of the MemCacheStore accept an options hash too.
|
||||
When reading you can specify +:raw => true+ to prevent the object being
|
||||
marshaled
|
||||
When reading you can specify +:raw => true+ to prevent the object being marshaled
|
||||
(by default this is false which means the raw value in the cache is passed to
|
||||
+Marshal.load+ before being returned to you.)
|
||||
|
||||
When writing to the cache it is also possible to specify +:raw => true+. This means
|
||||
that the value is not passed to +Marshal.dump+ before being stored in the cache (by
|
||||
When writing to the cache it is also possible to specify +:raw => true+ means
|
||||
the value is not passed to +Marshal.dump+ before being stored in the cache (by
|
||||
default this is false).
|
||||
|
||||
The write method also accepts an +:unless_exist+ flag which determines whether
|
||||
|
@ -424,15 +415,14 @@ ActionController::Base.cache_store = :compressed_mem_cache_store, "localhost"
|
|||
ActionController::Base.cache_store = MyOwnStore.new("parameter")
|
||||
</ruby>
|
||||
|
||||
NOTE: +config.cache_store+ can be used in place of
|
||||
+ActionController::Base.cache_store+ in the +Rails::Initializer.run+ block in
|
||||
environment.rb.
|
||||
+Note: +config.cache_store+ can be used in place of
|
||||
+ActionController::Base.cache_store+ in your +Rails::Initializer.run+ block in
|
||||
+environment.rb+
|
||||
|
||||
In addition to all of this, Rails also adds the +ActiveRecord::Base#cache_key+
|
||||
method that generates a key using the class name, id and updated_at timestamp
|
||||
(if available).
|
||||
method that generates a key using the class name, +id+ and +updated_at+ timestamp (if available).
|
||||
|
||||
An example:
|
||||
You can access these cache stores at a low level for storing queries and other objects. Here's an example:
|
||||
|
||||
<ruby>
|
||||
Rails.cache.read("city") # => nil
|
||||
|
@ -440,18 +430,18 @@ Rails.cache.write("city", "Duckburgh")
|
|||
Rails.cache.read("city") # => "Duckburgh"
|
||||
</ruby>
|
||||
|
||||
h3. Conditional GET Support
|
||||
h3. Conditional GET support
|
||||
|
||||
Conditional GETs are a feature of the HTTP specification that provide a way for web
|
||||
servers to tell browsers that the response to a GET request hasn't changed
|
||||
since the last request and can be safely pulled from the browser cache.
|
||||
|
||||
They work by using the HTTP_IF_NONE_MATCH and HTTP_IF_MODIFIED_SINCE headers to
|
||||
pass back and forth both a unique content identifier and the timestamp of when
|
||||
the content was last changed. If the browser makes a request where the content
|
||||
identifier (etag) or last modified since timestamp matches the server’s version
|
||||
then the server only needs to send back an empty response with a not modified
|
||||
status.
|
||||
They work by using the +HTTP_IF_NONE_MATCH+ and +HTTP_IF_MODIFIED_SINCE+ headers
|
||||
to pass back and forth both a unique content identifier and the timestamp of
|
||||
when the content was last changed. If the browser makes a request where the
|
||||
content identifier (etag) or last modified since timestamp matches the server’s
|
||||
version then the server only needs to send back an empty response with a not
|
||||
modified status.
|
||||
|
||||
It is the server's (i.e. our) responsibility to look for a last modified
|
||||
timestamp and the if-none-match header and determine whether or not to send
|
||||
|
@ -509,16 +499,18 @@ Also the new "Cache money":http://github.com/nkallen/cache-money/tree/master plu
|
|||
|
||||
h3. References
|
||||
|
||||
* "Scaling Rails Screencasts":http://railslab.newrelic.com/scaling-rails
|
||||
* "RailsEnvy, Rails Caching Tutorial, Part 1":http://www.railsenvy.com/2007/2/28/rails-caching-tutorial
|
||||
* "RailsEnvy, Rails Caching Tutorial, Part 1":http://www.railsenvy.com/2007/3/20/ruby-on-rails-caching-tutorial-part-2
|
||||
* "ActiveSupport::Cache documentation":http://api.rubyonrails.org/classes/ActiveSupport/Cache.html
|
||||
* "Rails 2.1 integrated caching tutorial":http://thewebfellas.com/blog/2008/6/9/rails-2-1-now-with-better-integrated-caching
|
||||
|
||||
h3. Changelog
|
||||
|
||||
h3. Changelog
|
||||
"Lighthouse ticket":http://rails.lighthouseapp.com/projects/16213-rails-guides/tickets/10-guide-to-caching
|
||||
|
||||
* February 22, 2009: Beefed up the section on cache_stores
|
||||
* December 27, 2008: Typo fixes
|
||||
* November 23, 2008: Incremental updates with various suggested changes and formatting cleanup
|
||||
* September 15, 2008: Initial version by Aditya Chadha
|
||||
April 1, 2009: Made a bunch of small fixes
|
||||
February 22, 2009: Beefed up the section on cache_stores
|
||||
December 27, 2008: Typo fixes
|
||||
November 23, 2008: Incremental updates with various suggested changes and formatting cleanup
|
||||
September 15, 2008: Initial version by Aditya Chadha
|
||||
|
|
|
@ -312,7 +312,7 @@ Now if you navigate to +http://localhost:3000+ in your browser, you'll see the +
|
|||
|
||||
NOTE. For more information about routing, refer to "Rails Routing from the Outside In":routing.html.
|
||||
|
||||
h3. Getting Up and Running Quickly With Scaffolding
|
||||
h3. Getting Up and Running Quickly with Scaffolding
|
||||
|
||||
Rails _scaffolding_ is a quick way to generate some of the major pieces of an application. If you want to create the models, views, and controllers for a new resource in a single operation, scaffolding is the tool for the job.
|
||||
|
||||
|
@ -474,7 +474,7 @@ This code sets the +@posts+ instance variable to an array of all posts in the da
|
|||
|
||||
TIP: For more information on finding records with Active Record, see "Active Record Query Interface":active_record_querying.html.
|
||||
|
||||
The +respond_to+ block handles both HTML and XML calls to this action. If you browse to +http://localhost:3000/posts.xml+, you'll see all of the posts in XML format. The HTML format looks for a view in +app/views/posts/+ with a name that corresponds to the action name. Rails makes all of the instance variables from the action available to the view. Here's +app/view/posts/index.html.erb+:
|
||||
The +respond_to+ block handles both HTML and XML calls to this action. If you browse to +http://localhost:3000/posts.xml+, you'll see all of the posts in XML format. The HTML format looks for a view in +app/views/posts/+ with a name that corresponds to the action name. Rails makes all of the instance variables from the action available to the view. Here's +app/views/posts/index.html.erb+:
|
||||
|
||||
<erb>
|
||||
<h1>Listing posts</h1>
|
||||
|
|
|
@ -9,7 +9,7 @@ This guide covers Rails integration with Rack and interfacing with other Rack co
|
|||
|
||||
endprologue.
|
||||
|
||||
WARNING: This guide assumes a working knowledge of Rack protocol and Rack concepts such as middlewares, url maps and Rack::Builder.
|
||||
WARNING: This guide assumes a working knowledge of Rack protocol and Rack concepts such as middlewares, url maps and +Rack::Builder+.
|
||||
|
||||
h3. Introduction to Rack
|
||||
|
||||
|
@ -51,9 +51,9 @@ app = Rack::Builder.new {
|
|||
Middlewares used in the code above are primarily useful only in the development envrionment. The following table explains their usage:
|
||||
|
||||
|_.Middleware|_.Purpose|
|
||||
|Rails::Rack::LogTailer|Appends log file output to console|
|
||||
|Rails::Rack::Static|Serves static files inside +RAILS_ROOT/public+ directory|
|
||||
|Rails::Rack::Debugger|Starts Debugger|
|
||||
|+Rails::Rack::LogTailer+|Appends log file output to console|
|
||||
|+Rails::Rack::Static+|Serves static files inside +RAILS_ROOT/public+ directory|
|
||||
|+Rails::Rack::Debugger+|Starts Debugger|
|
||||
|
||||
h4. +rackup+
|
||||
|
||||
|
@ -109,7 +109,7 @@ use ActiveRecord::QueryCache
|
|||
run ActionController::Dispatcher.new
|
||||
</ruby>
|
||||
|
||||
Purpose of each of this middlewares is explained in "Internal Middlewares":#internal-middleware-stack section.
|
||||
Purpose of each of this middlewares is explained in the "Internal Middlewares":#internal-middleware-stack section.
|
||||
|
||||
h4. Configuring Middleware Stack
|
||||
|
||||
|
@ -128,7 +128,7 @@ You can add a new middleware to the middleware stack using any of the following
|
|||
<strong>Example:</strong>
|
||||
|
||||
<ruby>
|
||||
# environment.rb
|
||||
# config/environment.rb
|
||||
|
||||
# Push Rack::BounceFavicon at the bottom
|
||||
config.middleware.use Rack::BounceFavicon
|
||||
|
@ -145,7 +145,7 @@ You can swap an existing middleware in the middleware stack using +config.middle
|
|||
<strong>Example:</strong>
|
||||
|
||||
<ruby>
|
||||
# environment.rb
|
||||
# config/environment.rb
|
||||
|
||||
# Replace ActionController::Failsafe with Lifo::Failsafe
|
||||
config.middleware.swap ActionController::Failsafe, Lifo::Failsafe
|
||||
|
@ -166,14 +166,14 @@ h4. Internal Middleware Stack
|
|||
Much of Action Controller's functionality is implemented as Middlewares. The following table explains the purpose of each of them:
|
||||
|
||||
|_.Middleware|_.Purpose|
|
||||
|Rack::Lock|Sets +env["rack.multithread"]+ flag to +true+ and wraps the application within a Mutex.|
|
||||
|ActionController::Failsafe|Returns HTTP Status +500+ to the client if an exception gets raised while dispatching.|
|
||||
|ActiveRecord::QueryCache|Enable the Active Record query cache.|
|
||||
|ActionController::Session::CookieStore|Uses the cookie based session store.|
|
||||
|ActionController::Session::MemCacheStore|Uses the memcached based session store.|
|
||||
|ActiveRecord::SessionStore|Uses the database based session store.|
|
||||
|Rack::MethodOverride|Sets HTTP method based on +_method+ parameter or +env["HTTP_X_HTTP_METHOD_OVERRIDE"]+.|
|
||||
|Rack::Head|Discards the response body if the client sends a +HEAD+ request.|
|
||||
|+Rack::Lock+|Sets +env["rack.multithread"]+ flag to +true+ and wraps the application within a Mutex.|
|
||||
|+ActionController::Failsafe+|Returns HTTP Status +500+ to the client if an exception gets raised while dispatching.|
|
||||
|+ActiveRecord::QueryCache+|Enable the Active Record query cache.|
|
||||
|+ActionController::Session::CookieStore+|Uses the cookie based session store.|
|
||||
|+ActionController::Session::MemCacheStore+|Uses the memcached based session store.|
|
||||
|+ActiveRecord::SessionStore+|Uses the database based session store.|
|
||||
|+Rack::MethodOverride+|Sets HTTP method based on +_method+ parameter or +env["HTTP_X_HTTP_METHOD_OVERRIDE"]+.|
|
||||
|+Rack::Head+|Discards the response body if the client sends a +HEAD+ request.|
|
||||
|
||||
TIP: It's possible to use any of the above middlewares in your custom Rack stack.
|
||||
|
||||
|
@ -229,7 +229,7 @@ h3. Rails Metal Applications
|
|||
|
||||
Rails Metal applications are minimal Rack applications specially designed for integrating with a typical Rails application. As Rails Metal Applications skip all of the Action Controller stack, serving a request has no overhead from the Rails framework itself. This is especially useful for infrequent cases where the performance of the full stack Rails framework is an issue.
|
||||
|
||||
Ryan Bates' railscast on the "Rails Metal":http://railscasts.com/episodes/150-rails-metal provides a nice walkthrough generating and using Rails Metal.
|
||||
Ryan Bates' "railscast on Rails Metal":http://railscasts.com/episodes/150-rails-metal provides a nice walkthrough generating and using Rails Metal.
|
||||
|
||||
h4. Generating a Metal Application
|
||||
|
||||
|
@ -256,7 +256,7 @@ class Poller
|
|||
end
|
||||
</ruby>
|
||||
|
||||
Metal applications within +app/metal+ folders in plugins will also be discovered and added to the list
|
||||
Metal applications within +app/metal+ folders in plugins will also be discovered and added to the list.
|
||||
|
||||
Metal applications are an optimization. You should make sure to "understand the related performance implications":http://weblog.rubyonrails.org/2008/12/20/performance-of-rails-metal before using it.
|
||||
|
||||
|
|
|
@ -582,7 +582,7 @@ To add a member route, use the +:member+ option:
|
|||
map.resources :photos, :member => { :preview => :get }
|
||||
</ruby>
|
||||
|
||||
This will enable Rails to recognize URLs such as +/photos/1/preview+ using the GET HTTP verb, and route them to the preview action of the Photos controller. It will also create a +preview_photo+ route helper.
|
||||
This will enable Rails to recognize URLs such as +/photos/1/preview+ using the GET HTTP verb, and route them to the preview action of the Photos controller. It will also create the +preview_photo_url+ and +preview_photo_path+ route helpers.
|
||||
|
||||
Within the hash of member routes, each route name specifies the HTTP verb that it will recognize. You can use +:get+, +:put+, +:post+, +:delete+, or +:any+ here. You can also specify an array of methods, if you need more than one but you don't want to allow just anything:
|
||||
|
||||
|
@ -598,7 +598,7 @@ To add a collection route, use the +:collection+ option:
|
|||
map.resources :photos, :collection => { :search => :get }
|
||||
</ruby>
|
||||
|
||||
This will enable Rails to recognize URLs such as +/photos/search+ using the GET HTTP verb, and route them to the search action of the Photos controller. It will also create a +search_photos+ route helper.
|
||||
This will enable Rails to recognize URLs such as +/photos/search+ using the GET HTTP verb, and route them to the search action of the Photos controller. It will also create the +search_photos_url+ and +search_photos_path+ route helpers.
|
||||
|
||||
Just as with member routes, you can specify an array of methods for a collection route:
|
||||
|
||||
|
@ -614,7 +614,7 @@ To add a new route (one that creates a new resource), use the +:new+ option:
|
|||
map.resources :photos, :new => { :upload => :post }
|
||||
</ruby>
|
||||
|
||||
This will enable Rails to recognize URLs such as +/photos/upload+ using the POST HTTP verb, and route them to the upload action of the Photos controller. It will also create a +upload_photos+ route helper.
|
||||
This will enable Rails to recognize URLs such as +/photos/upload+ using the POST HTTP verb, and route them to the upload action of the Photos controller. It will also create the +upload_photos_path+ and +upload_photos_url+ route helpers.
|
||||
|
||||
TIP: If you want to redefine the verbs accepted by one of the standard actions, you can do so by explicitly mapping that action. For example:<br/>+map.resources :photos, :new => { :new => :any }+<br/>This will allow the new action to be invoked by any request to +photos/new+, no matter what HTTP verb you use.
|
||||
|
||||
|
|
Loading…
Reference in New Issue