mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Updated documentation
git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@780 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
This commit is contained in:
parent
5d94fb33c6
commit
e4efcfd43e
6 changed files with 147 additions and 95 deletions
|
@ -50,7 +50,7 @@ A short rundown of the major features:
|
|||
def find_customer() Customer.find(@params["id"]) end
|
||||
end
|
||||
|
||||
Learn more in link:classes/ActionController/Base.html
|
||||
{Learn more}[link:classes/ActionController/Base.html]
|
||||
|
||||
|
||||
* Embedded Ruby for templates (no new "easy" template language)
|
||||
|
@ -65,30 +65,32 @@ A short rundown of the major features:
|
|||
Not for clients to see...
|
||||
<% end %>
|
||||
|
||||
Learn more in link:classes/ActionView.html
|
||||
{Learn more}[link:classes/ActionView.html]
|
||||
|
||||
|
||||
* Builder-based templates (great for XML content, like RSS)
|
||||
|
||||
xml.rss("version" => "2.0") do
|
||||
xml.channel do
|
||||
xml.title(@feed_title)
|
||||
xml.link(@url)
|
||||
xml.description "Basecamp: Recent items"
|
||||
xml.language "en-us"
|
||||
xml.ttl "40"
|
||||
xml.rss("version" => "2.0") do
|
||||
xml.channel do
|
||||
xml.title(@feed_title)
|
||||
xml.link(@url)
|
||||
xml.description "Basecamp: Recent items"
|
||||
xml.language "en-us"
|
||||
xml.ttl "40"
|
||||
|
||||
for item in @recent_items
|
||||
xml.item do
|
||||
xml.title(item_title(item))
|
||||
xml.description(item_description(item))
|
||||
xml.pubDate(item_pubDate(item))
|
||||
xml.guid(@recent_items.url(item))
|
||||
xml.link(@recent_items.url(item))
|
||||
for item in @recent_items
|
||||
xml.item do
|
||||
xml.title(item_title(item))
|
||||
xml.description(item_description(item))
|
||||
xml.pubDate(item_pubDate(item))
|
||||
xml.guid(@recent_items.url(item))
|
||||
xml.link(@recent_items.url(item))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
{Learn more}[link:classes/ActionView/Base.html]
|
||||
|
||||
|
||||
* Filters for pre and post processing of the response (as methods, procs, and classes)
|
||||
|
@ -113,7 +115,7 @@ A short rundown of the major features:
|
|||
end
|
||||
end
|
||||
|
||||
Learn more in link:classes/ActionController/Filters/ClassMethods.html
|
||||
{Learn more}[link:classes/ActionController/Filters/ClassMethods.html]
|
||||
|
||||
|
||||
* Helpers for forms, dates, action links, and text
|
||||
|
@ -123,7 +125,7 @@ A short rundown of the major features:
|
|||
<%= link_to "New post", :controller => "post", :action => "new" %>
|
||||
<%= truncate(post.title, 25) %>
|
||||
|
||||
Learn more in link:classes/ActionView/Helpers.html
|
||||
{Learn more}[link:classes/ActionView/Helpers.html]
|
||||
|
||||
|
||||
* Layout sharing for template reuse (think simple version of Struts
|
||||
|
@ -145,28 +147,25 @@ A short rundown of the major features:
|
|||
Result of running hello_world action:
|
||||
<html><body><h1>Hello world</h1></body></html>
|
||||
|
||||
Learn more in link:classes/ActionController/Layout/ClassMethods.html
|
||||
{Learn more}[link:classes/ActionController/Layout/ClassMethods.html]
|
||||
|
||||
|
||||
* Advanced redirection that makes pretty urls easy
|
||||
* Routing makes pretty urls incredibly easy
|
||||
|
||||
RewriteRule ^/library/books/([A-Z]+)([0-9]+)/([-_a-zA-Z0-9]+)$ \
|
||||
/books_controller.cgi?action=$3&type=$1&code=$2 [QSA] [L]
|
||||
map.connect 'clients/:client_name/:project_name/:controller/:action'
|
||||
|
||||
Accessing /library/books/ISBN/0743536703/show calls BooksController#show
|
||||
Accessing /clients/37signals/basecamp/project/dash calls ProjectController#dash with
|
||||
{ "client_name" => "37signals", "project_name" => "basecamp" } in @params["params"]
|
||||
|
||||
From that URL, you can rewrite the redirect in a number of ways:
|
||||
|
||||
redirect_to(:action => "edit") =>
|
||||
/library/books/ISBN/0743536703/edit
|
||||
/clients/37signals/basecamp/project/dash
|
||||
|
||||
redirect_to(:path_params => { "type" => "XTC", "code" => "12354345" }) =>
|
||||
/library/books/XTC/12354345/show
|
||||
redirect_to(:client_name => "nextangle", :project_name => "rails") =>
|
||||
/clients/nextangle/rails/project/dash
|
||||
|
||||
redirect_to(:controller_prefix => "admin", :controller => "accounts") =>
|
||||
/admin/accounts/
|
||||
|
||||
Learn more in link:classes/ActionController/Base.html
|
||||
{Learn more}[link:classes/ActionController/Base.html]
|
||||
|
||||
|
||||
* Easy testing of both controller and template result through TestRequest/Response
|
||||
|
@ -185,7 +184,7 @@ A short rundown of the major features:
|
|||
end
|
||||
end
|
||||
|
||||
Learn more in link:classes/ActionController/TestRequest.html
|
||||
{Learn more}[link:classes/ActionController/TestRequest.html]
|
||||
|
||||
|
||||
* Automated benchmarking and integrated logging
|
||||
|
@ -211,6 +210,58 @@ A short rundown of the major features:
|
|||
ActionController::Base.logger = Log4r::Logger.new("Application Log")
|
||||
|
||||
|
||||
* Caching at three levels of granularity (page, action, fragment)
|
||||
|
||||
class WeblogController < ActionController::Base
|
||||
caches_page :show
|
||||
caches_action :account
|
||||
|
||||
def show
|
||||
# the output of the method will be cached as
|
||||
# ActionController::Base.page_cache_directory + "/weblog/show/n.html"
|
||||
# and the web server will pick it up without even hitting Rails
|
||||
end
|
||||
|
||||
def account
|
||||
# the output of the method will be cached in the fragment store
|
||||
# but Rails is hit to retrieve it, so filters are run
|
||||
end
|
||||
|
||||
def update
|
||||
List.update(@params["list"]["id"], @params["list"])
|
||||
expire_page :action => "show", :id => @params["list"]["id"]
|
||||
expire_action :action => "account"
|
||||
redirect_to :action => "show", :id => @params["list"]["id"]
|
||||
end
|
||||
end
|
||||
|
||||
{Learn more}[link:classes/ActionController/Caching.html]
|
||||
|
||||
|
||||
* Component requests from one controller to another
|
||||
|
||||
class WeblogController < ActionController::Base
|
||||
# Performs a method and then lets hello_world output its render
|
||||
def delegate_action
|
||||
do_other_stuff_before_hello_world
|
||||
render_component :controller => "greeter", :action => "hello_world"
|
||||
end
|
||||
end
|
||||
|
||||
class GreeterController < ActionController::Base
|
||||
def hello_world
|
||||
render_text "Hello World!"
|
||||
end
|
||||
end
|
||||
|
||||
The same can be done in a view to do a partial rendering:
|
||||
|
||||
Let's see a greeting:
|
||||
<%= render_component :controller => "greeter", :action => "hello_world" %>
|
||||
|
||||
{Learn more}[link:classes/ActionController/Components.html]
|
||||
|
||||
|
||||
* Powerful debugging mechanism for local requests
|
||||
|
||||
All exceptions raised on actions performed on the request of a local user
|
||||
|
@ -218,7 +269,7 @@ A short rundown of the major features:
|
|||
message, stack trace, request parameters, session contents, and the
|
||||
half-finished response.
|
||||
|
||||
Learn more in link:classes/ActionController/Rescue.html
|
||||
{Learn more}[link:classes/ActionController/Rescue.html]
|
||||
|
||||
|
||||
* Scaffolding for Action Record model objects
|
||||
|
@ -231,7 +282,7 @@ A short rundown of the major features:
|
|||
The AccountController now has the full CRUD range of actions and default
|
||||
templates: list, show, destroy, new, create, edit, update
|
||||
|
||||
Learn more in link:classes/ActionController/Scaffolding/ClassMethods.html
|
||||
{Learn more}link:classes/ActionController/Scaffolding/ClassMethods.html
|
||||
|
||||
|
||||
* Form building for Active Record model objects
|
||||
|
@ -272,42 +323,21 @@ A short rundown of the major features:
|
|||
end
|
||||
end
|
||||
|
||||
Learn more in link:classes/ActionView/Helpers/ActiveRecordHelper.html
|
||||
{Learn more}[link:classes/ActionView/Helpers/ActiveRecordHelper.html]
|
||||
|
||||
|
||||
* Automated mapping of URLs to controller/action pairs through Apache's
|
||||
mod_rewrite
|
||||
|
||||
Requesting /blog/display/5 will call BlogController#display and
|
||||
make 5 available as an instance variable through @params["id"]
|
||||
|
||||
|
||||
* Runs on top of CGI, FCGI, and mod_ruby
|
||||
|
||||
See the address_book_controller example for all three forms
|
||||
* Runs on top of WEBrick, CGI, FCGI, and mod_ruby
|
||||
|
||||
|
||||
== Simple example
|
||||
|
||||
This example will implement a simple weblog system using inline templates and
|
||||
an Active Record model. The first thing we need to do is setup an .htaccess to
|
||||
interpret pretty URLs into something the controller can use. Let's use the
|
||||
simplest form for starters:
|
||||
|
||||
RewriteRule ^weblog/([-_a-zA-Z0-9]+)/([0-9]+)$ \
|
||||
/weblog_controller.cgi?action=$2&id=$3 [QSA]
|
||||
RewriteRule ^weblog/([-_a-zA-Z0-9]+)$ \
|
||||
/weblog_controller.cgi?action=$2 [QSA]
|
||||
RewriteRule ^weblog/$ \
|
||||
/weblog_controller.cgi?action=index [QSA]
|
||||
|
||||
Now we'll be able to access URLs like weblog/display/5 and have
|
||||
WeblogController#display called with { "id" => 5 } in the @params array
|
||||
available for the action. So let's build that WeblogController with just a few
|
||||
an Active Record model. So let's build that WeblogController with just a few
|
||||
methods:
|
||||
|
||||
require 'action_controller'
|
||||
require 'post'
|
||||
|
||||
class WeblogController < ActionController::Base
|
||||
layout "weblog/layout"
|
||||
|
||||
|
@ -362,7 +392,7 @@ which is called by accessing /weblog/. It uses the form builder for the Active
|
|||
Record model to make the new screen, which in turns hand everything over to
|
||||
the create action (that's the default target for the form builder when given a
|
||||
new model). After creating the post, it'll redirect to the display page using
|
||||
an URL such as /weblog/display/5 (where 5 is the id of the post.
|
||||
an URL such as /weblog/display/5 (where 5 is the id of the post).
|
||||
|
||||
|
||||
== Examples
|
||||
|
@ -386,7 +416,7 @@ The latest version of Action Pack can be found at
|
|||
|
||||
Documentation can be found at
|
||||
|
||||
* http://actionpack.rubyonrails.org
|
||||
* http://ap.rubyonrails.com
|
||||
|
||||
|
||||
== Installation
|
||||
|
@ -405,7 +435,7 @@ Action Pack is released under the same license as Ruby.
|
|||
|
||||
== Support
|
||||
|
||||
The Action Pack homepage is http://actionpack.rubyonrails.org. You can find
|
||||
The Action Pack homepage is http://www.rubyonrails.com. You can find
|
||||
the Action Pack RubyForge page at http://rubyforge.org/projects/actionpack.
|
||||
And as Jim from Rake says:
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ module ActionController #:nodoc:
|
|||
end
|
||||
class MissingTemplate < ActionControllerError #:nodoc:
|
||||
end
|
||||
class RoutingError < ActionControllerError
|
||||
class RoutingError < ActionControllerError#:nodoc:
|
||||
attr_reader :failures
|
||||
def initialize(message, failures=[])
|
||||
super(message)
|
||||
|
@ -86,9 +86,9 @@ module ActionController #:nodoc:
|
|||
# <input type="text" name="post[name]" value="david">
|
||||
# <input type="text" name="post[address]" value="hyacintvej">
|
||||
#
|
||||
# A request stemming from a form holding these inputs will include { "post" # => { "name" => "david", "address" => "hyacintvej" } }.
|
||||
# A request stemming from a form holding these inputs will include <tt>{ "post" => { "name" => "david", "address" => "hyacintvej" } }</tt>.
|
||||
# If the address input had been named "post[address][street]", the @params would have included
|
||||
# { "post" => { "address" => { "street" => "hyacintvej" } } }. There's no limit to the depth of the nesting.
|
||||
# <tt>{ "post" => { "address" => { "street" => "hyacintvej" } } }</tt>. There's no limit to the depth of the nesting.
|
||||
#
|
||||
# == Sessions
|
||||
#
|
||||
|
@ -156,22 +156,20 @@ module ActionController #:nodoc:
|
|||
#
|
||||
# Redirects work by rewriting the URL of the current action. So if the show action was called by "/library/books/ISBN/0743536703/show",
|
||||
# we can redirect to an edit action simply by doing <tt>redirect_to(:action => "edit")</tt>, which could throw the user to
|
||||
# "/library/books/ISBN/0743536703/edit". Naturally, you'll need to setup the .htaccess (or other means of URL rewriting for the web server)
|
||||
# to point to the proper controller and action in the first place, but once you have, it can be rewritten with ease.
|
||||
# "/library/books/ISBN/0743536703/edit". Naturally, you'll need to setup the routes configuration file to point to the proper controller
|
||||
# and action in the first place, but once you have, it can be rewritten with ease.
|
||||
#
|
||||
# Let's consider a bunch of examples on how to go from "/library/books/ISBN/0743536703/edit" to somewhere else:
|
||||
# Let's consider a bunch of examples on how to go from "/clients/37signals/basecamp/project/dash" to somewhere else:
|
||||
#
|
||||
# redirect_to(:action => "show", :action_prefix => "XTC/123") =>
|
||||
# "http://www.singlefile.com/library/books/XTC/123/show"
|
||||
# redirect_to(:action => "edit") =>
|
||||
# /clients/37signals/basecamp/project/dash
|
||||
#
|
||||
# redirect_to(:client_name => "nextangle", :project_name => "rails") =>
|
||||
# /clients/nextangle/rails/project/dash
|
||||
#
|
||||
# redirect_to(:path_params => {"type" => "EXBC"}) =>
|
||||
# "http://www.singlefile.com/library/books/EXBC/0743536703/show"
|
||||
# Those redirects happen under the configuration of:
|
||||
#
|
||||
# redirect_to(:controller => "settings") =>
|
||||
# "http://www.singlefile.com/library/settings/"
|
||||
#
|
||||
# For more examples of redirecting options, have a look at the unit test in test/controller/url_test.rb. It's very readable and will give
|
||||
# you an excellent understanding of the different options and what they do.
|
||||
# map.connect 'clients/:client_name/:project_name/:controller/:action'
|
||||
#
|
||||
# == Calling multiple redirects or renders
|
||||
#
|
||||
|
@ -337,20 +335,20 @@ module ActionController #:nodoc:
|
|||
# * <tt>:anchor</tt> -- specifies the anchor name to be appended to the path. For example,
|
||||
# <tt>url_for :controller => 'posts', :action => 'show', :id => 10, :anchor => 'comments'</tt>
|
||||
# will produce "/posts/show/10#comments".
|
||||
# * <tt>:only-path</tt> -- if true, returns the absolute URL (omitting the protocol, host name, and port)
|
||||
# * <tt>:only_path</tt> -- if true, returns the absolute URL (omitting the protocol, host name, and port)
|
||||
# * <tt>:host</tt> -- overrides the default (current) host if provided
|
||||
# * <tt>:protocol</tt> -- overrides the default (current) protocol if provided
|
||||
#
|
||||
#
|
||||
# The URL is generated from the remaining keys in the hash. A URL contains two key parts: the <base> and a query string.
|
||||
# Routes composes a query string as the key/value pairs not included in the <base>.
|
||||
#
|
||||
#
|
||||
# The default Routes setup supports a typical Rails path of "controller/action/id" where action and id are optional, with
|
||||
# action defaulting to 'index' when not given. Here are some typical url_for statements and their corresponding URLs:
|
||||
#
|
||||
# url_for :controller => 'posts', :action => 'recent' # => 'proto://host.com/posts/recent'
|
||||
# url_for :controller => 'posts', :action => 'index' # => 'proto://host.com/posts'
|
||||
# url_for :controller => 'posts', :action => 'show', :id => 10 # => 'proto://host.com/posts/show/10'
|
||||
#
|
||||
#
|
||||
# When generating a new URL, missing values may be filled in from the current request's parameters. For example,
|
||||
# <tt>url_for :action => 'some_action'</tt> will retain the current controller, as expected. This behavior extends to
|
||||
# other parameters, including <tt>:controller</tt>, <tt>:id</tt>, and any other parameters that are placed into a Route's
|
||||
|
@ -359,21 +357,21 @@ module ActionController #:nodoc:
|
|||
# The URL helpers such as <tt>url_for</tt> have a limited form of memory: when generating a new URL, they can look for
|
||||
# missing values in the current request's parameters. Routes attempts to guess when a value should and should not be
|
||||
# taken from the defaults. There are a few simple rules on how this is performed:
|
||||
#
|
||||
#
|
||||
# * If the controller name begins with a slash, no defaults are used: <tt>url_for :controller => '/home'</tt>
|
||||
# * If the controller changes, the action will default to index unless provided
|
||||
#
|
||||
#
|
||||
# The final rule is applied while the URL is being generated and is best illustrated by an example. Let us consider the
|
||||
# route given by <tt>map.connect 'people/:last/:first/:action', :action => 'bio', :controller => 'people'</tt>.
|
||||
#
|
||||
#
|
||||
# Suppose that the current URL is "people/hh/david/contacts". Let's consider a few different cases URLs which are generated
|
||||
# from this page.
|
||||
#
|
||||
#
|
||||
# * <tt>url_for :action => 'bio'</tt> -- During the generation of this URL, default values will be used for the first and
|
||||
# last components, and the action shall change. The generated URL will be, "people/david/hh/bio".
|
||||
# * <tt>url_for :first => 'davids-little-brother'</tt> This generates the URL 'people/hh/davids-little-brother' -- note
|
||||
# that this URL leaves out the assumed action of 'bio'.
|
||||
#
|
||||
#
|
||||
# However, you might ask why the action from the current request, 'contacts', isn't carried over into the new URL. The
|
||||
# answer has to do with the order in which the parameters appear in the generated path. In a nutshell, since the
|
||||
# value that appears in the slot for <tt>:first</tt> is not equal to default value for <tt>:first</tt> we stop using
|
||||
|
@ -472,12 +470,12 @@ module ActionController #:nodoc:
|
|||
|
||||
# Renders an empty response that can be used when the request is only interested in triggering an effect. Do note that good
|
||||
# HTTP manners mandate that you don't use GET requests to trigger data changes.
|
||||
def render_nothing(status = nil)
|
||||
def render_nothing(status = nil) #:doc:
|
||||
render_text "", status
|
||||
end
|
||||
|
||||
# Returns the result of the render as a string.
|
||||
def render_to_string(template_name = default_template_name)
|
||||
def render_to_string(template_name = default_template_name) #:doc:
|
||||
add_variables_to_assigns
|
||||
@template.render_file(template_name)
|
||||
end
|
||||
|
|
|
@ -1,7 +1,27 @@
|
|||
module ActionController #:nodoc:
|
||||
# TODO: Cookies and session variables set in render_component that happens inside a view should be copied over.
|
||||
module Components #:nodoc:
|
||||
def self.append_features(base)
|
||||
# Components allows you to call other actions for their rendered response while execution another action. You can either delegate
|
||||
# the entire response rendering or you can mix a partial response in with your other content.
|
||||
#
|
||||
# class WeblogController < ActionController::Base
|
||||
# # Performs a method and then lets hello_world output its render
|
||||
# def delegate_action
|
||||
# do_other_stuff_before_hello_world
|
||||
# render_component :controller => "greeter", :action => "hello_world"
|
||||
# end
|
||||
# end
|
||||
#
|
||||
# class GreeterController < ActionController::Base
|
||||
# def hello_world
|
||||
# render_text "Hello World!"
|
||||
# end
|
||||
# end
|
||||
#
|
||||
# The same can be done in a view to do a partial rendering:
|
||||
#
|
||||
# Let's see a greeting:
|
||||
# <%= render_component :controller => "greeter", :action => "hello_world" %>
|
||||
module Components
|
||||
def self.append_features(base) #:nodoc:
|
||||
super
|
||||
base.helper do
|
||||
def render_component(options)
|
||||
|
@ -11,10 +31,12 @@ module ActionController #:nodoc:
|
|||
end
|
||||
|
||||
protected
|
||||
# Renders the component specified as the response for the current method
|
||||
def render_component(options = {}) #:doc:
|
||||
component_logging(options) { render_text(component_response(options).body, response.headers["Status"]) }
|
||||
end
|
||||
|
||||
# Returns the component response as a string
|
||||
def render_component_as_string(options) #:doc:
|
||||
component_logging(options) { component_response(options, false).body }
|
||||
end
|
||||
|
|
|
@ -26,6 +26,9 @@ module ActionController #:nodoc:
|
|||
# # model :post (already required)
|
||||
# # helper :post (already required)
|
||||
# end
|
||||
#
|
||||
# Also note, that if the models follow the pattern of just 1 class per file in the form of MyClass => my_class.rb, then these
|
||||
# classes doesn't have to be required as Active Support will auto-require them.
|
||||
module ClassMethods
|
||||
# Specifies a variable number of models that this controller depends on. Models are normally Active Record classes or a similar
|
||||
# backend for modelling entity classes.
|
||||
|
|
|
@ -35,8 +35,7 @@ module ActionController #:nodoc:
|
|||
template_class.class_eval "include #{helper_module}"
|
||||
end
|
||||
|
||||
# Declare a helper. If you use this method in your controller, you don't
|
||||
# have to do the +self.append_features+ incantation in your helper class.
|
||||
# Declare a helper:
|
||||
# helper :foo
|
||||
# requires 'foo_helper' and includes FooHelper in the template class.
|
||||
# helper FooHelper
|
||||
|
|
|
@ -2,7 +2,7 @@ module ActionController
|
|||
module Routing
|
||||
ROUTE_FILE = defined?(RAILS_ROOT) ? File.expand_path(File.join(RAILS_ROOT, 'config', 'routes')) : nil
|
||||
|
||||
class Route
|
||||
class Route #:nodoc:
|
||||
attr_reader :defaults # The defaults hash
|
||||
|
||||
def initialize(path, hash={})
|
||||
|
@ -185,7 +185,7 @@ module ActionController
|
|||
end
|
||||
end
|
||||
|
||||
class RouteSet
|
||||
class RouteSet#:nodoc:
|
||||
def initialize
|
||||
@routes = []
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue