Browse files

Updated documentation

git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@780 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
  • Loading branch information...
1 parent 5d94fb3 commit e4efcfd43e60c4a6eb1def4ecb976e2a3fc8702f @dhh dhh committed Feb 24, 2005
View
156 actionpack/README
@@ -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"
-
- 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))
+ 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))
+ 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
-
- redirect_to(:path_params => { "type" => "XTC", "code" => "12354345" }) =>
- /library/books/XTC/12354345/show
+ /clients/37signals/basecamp/project/dash
- redirect_to(:controller_prefix => "admin", :controller => "accounts") =>
- /admin/accounts/
+ redirect_to(:client_name => "nextangle", :project_name => "rails") =>
+ /clients/nextangle/rails/project/dash
- 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,14 +210,66 @@ 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
will be presented with a tailored debugging screen that includes exception
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:
View
50 actionpack/lib/action_controller/base.rb
@@ -14,7 +14,7 @@ class SessionRestoreError < ActionControllerError #: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 @@ class MissingFile < ActionControllerError #: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 @@ class MissingFile < ActionControllerError #: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 @@ def process(request, response, method = :perform_action, *arguments) #: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 @@ def process(request, response, method = :perform_action, *arguments) #: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 @@ def render_text(text = nil, status = nil, &block) #:doc:
# 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
View
28 actionpack/lib/action_controller/components.rb
@@ -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 @@ def render_component(options)
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
View
3 actionpack/lib/action_controller/dependencies.rb
@@ -26,6 +26,9 @@ def self.append_features(base)
# # 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.
View
3 actionpack/lib/action_controller/helpers.rb
@@ -35,8 +35,7 @@ def add_template_helper(helper_module) #: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
View
4 actionpack/lib/action_controller/routing.rb
@@ -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 @@ def requirements_for(name)
end
end
- class RouteSet
+ class RouteSet#:nodoc:
def initialize
@routes = []
end

0 comments on commit e4efcfd

Please sign in to comment.