0
@@ -49,13 +49,15 @@ module ActionController #:nodoc:
0
- # Action Controllers are made up of one or more actions that performs its purpose and then either renders a template or
0
- # redirects to another action. An action is defined as a public method on the controller, which will automatically be
0
- # made accessible to the web-server through a mod_rewrite mapping. A sample controller could look like this:
0
+ # Action Controllers are the core of a web request in Rails. They are made up of one or more actions that are executed
0
+ # on request and then either render a template or redirect to another action. An action is defined as a public method
0
+ # on the controller, which will automatically be made accessible to the web-server through Rails Routes.
0
+ # A sample controller could look like this:
0
# class GuestBookController < ActionController::Base
0
- # @entries = Entry.find
_all0
+ # @entries = Entry.find
(:all)0
@@ -64,26 +66,17 @@ module ActionController #:nodoc:
0
- # GuestBookController.template_root = "templates/"
0
- # GuestBookController.process_cgi
0
- # All actions assume that you want to render a template matching the name of the action at the end of the performance
0
- # unless you tell it otherwise. The index action complies with this assumption, so after populating the @entries instance
0
- # variable, the GuestBookController will render "templates/guestbook/index.rhtml".
0
+ # Actions, by default, render a template in the <tt>app/views</tt> directory corresponding to the name of the controller and action
0
+ # after executing code in the action. For example, the +index+ action of the +GuestBookController+ would render the
0
+ # template <tt>app/views/guestbook/index.rhtml</tt> by default after populating the <tt>@entries</tt> instance variable.
0
- # Unlike index, the sign action isn't interested in rendering a template. So after performing its main purpose (creating a
0
- # new entry in the guest book), it sheds the rendering assumption and initiates a redirect instead. This redirect works by
0
- # returning an external "302 Moved" HTTP response that takes the user to the index action.
0
+ # Unlike index, the sign action will not render a template. After performing its main purpose (creating a
0
+ # new entry in the guest book), it initiates a redirect instead. This redirect works by returning an external
0
+ # "302 Moved" HTTP response that takes the user to the index action.
0
# The index and sign represent the two basic action archetypes used in Action Controllers. Get-and-show and do-and-redirect.
0
# Most actions are variations of these themes.
0
- # Also note that it's the final call to <tt>process_cgi</tt> that actually initiates the action performance. It will extract
0
- # request and response objects from the CGI
0
- # When Action Pack is used inside of Rails, the template_root is automatically configured and you don't need to call process_cgi
0
# Requests are processed by the Action Controller framework by extracting the value of the "action" key in the request parameters.
0
@@ -94,16 +87,16 @@ module ActionController #:nodoc:
0
# The full request object is available with the request accessor and is primarily used to query for http headers. These queries
0
# are made by accessing the environment hash, like this:
0
- # location = request.env["REMOTE_IP"]
0
- # render :text => "Hello stranger from #{location}"
0
+ # location = request.env["SERVER_ADDR"]
0
+ # render :text => "This server hosted at #{location}"
0
- # All request parameters, whether they come from a GET or POST request, or from the URL, are available through the params hash.
0
- # So an action that was performed through /weblog/list?category=All&limit=5 will include { "category" => "All", "limit" => 5 }
0
+ # All request parameters, whether they come from a GET or POST request, or from the URL, are available through the params method
0
+ # which returns a hash. For example, an action that was performed through <tt>/weblog/list?category=All&limit=5</tt> will include
0
+ # <tt>{ "category" => "All", "limit" => 5 }</tt> in params.
0
# It's also possible to construct multi-dimensional parameter hashes by specifying keys using brackets, such as:
0
@@ -116,12 +109,12 @@ module ActionController #:nodoc:
0
- # Sessions allows you to store objects in
memory between requests. This is useful for objects that are not yet ready to be persisted,
0
+ # Sessions allows you to store objects in
between requests. This is useful for objects that are not yet ready to be persisted,
0
# such as a Signup object constructed in a multi-paged process, or objects that don't change much and are needed all the time, such
0
# as a User object for a system that requires login. The session should not be used, however, as a cache for objects where it's likely
0
# they could be changed unknowingly. It's usually too much work to keep it all synchronized -- something databases already excel at.
0
- # You can place objects in the session by using the <tt>session</tt>
hash accessor:
0
+ # You can place objects in the session by using the <tt>session</tt>
method, which accesses a hash:
0
# session[:person] = Person.authenticate(user_name, password)
0
@@ -129,17 +122,24 @@ module ActionController #:nodoc:
0
# Hello #{session[:person]}
0
- # Any object can be placed in the session (as long as it can be Marshalled). But remember that 1000 active sessions each storing a
0
- # 50kb object could lead to a 50MB memory overhead. In other words, think carefully about size and caching before resorting to the use
0
# For removing objects from the session, you can either assign a single key to nil, like <tt>session[:person] = nil</tt>, or you can
0
# remove the entire session with reset_session.
0
+ # By default, sessions are stored on the file system in <tt>RAILS_ROOT/tmp/sessions</tt>. Any object can be placed in the session
0
+ # (as long as it can be Marshalled). But remember that 1000 active sessions each storing a 50kb object could lead to a 50MB store on the filesystem.
0
+ # In other words, think carefully about size and caching before resorting to the use of the session on the filesystem.
0
+ # An alternative to storing sessions on disk is to use ActiveRecordStore to store sessions in your database, which can solve problems
0
+ # caused by storing sessions in the file system and may speed up your application. To use ActiveRecordStore, uncomment the line:
0
+ # config.action_controller.session_store = :active_record_store
0
+ # in your <tt>environment.rb</tt> and run <tt>rake db:sessions:create</tt>.
0
# Each action results in a response, which holds the headers and document to be sent to the user's browser. The actual response
0
- # object is generated automatically through the use of renders and redirects
, so it's normally nothing you'll need to be concerned about.
0
+ # object is generated automatically through the use of renders and redirects
and requires no user intervention.
0
@@ -161,9 +161,9 @@ module ActionController #:nodoc:
0
# @results = Search.find(params[:query])
0
- # when 0 then render :action=> "no_results"
0
- # when 1 then render :action=> "show"
0
- # when 2..10 then render :action=> "show_many"
0
+ # when 0 then render :action => "no_results"
0
+ # when 1 then render :action => "show"
0
+ # when 2..10 then render :action => "show_many"
0
@@ -171,32 +171,21 @@ module ActionController #:nodoc:
0
- # Redirecting is what actions that update the model do when they're done. The <tt>save_post</tt> method shouldn't be responsible for also
0
- # showing the post once it's saved -- that's the job for <tt>show_post</tt>. So once <tt>save_post</tt> has completed its business, it'll
0
- # redirect to <tt>show_post</tt>. All redirects are external, which means that when the user refreshes his browser, it's not going to save
0
- # the post again, but rather just show it one more time.
0
- # This sounds fairly simple, but the redirection is complicated by the quest for a phenomenon known as "pretty urls". Instead of accepting
0
- # the dreadful being that is "weblog_controller?action=show&post_id=5", Action Controller goes out of its way to represent the former as
0
- # "/weblog/show/5". And this is even the simple case. As an example of a more advanced pretty url consider
0
- # "/library/books/ISBN/0743536703/show", which can be mapped to books_controller?action=show&type=ISBN&id=0743536703.
0
- # Redirects work by rewriting the URL of the current action. So if the show action was called by "/library/books/ISBN/0743536703/show",
0
- # we can redirect to an edit action simply by doing <tt>redirect_to(:action => "edit")</tt>, which could throw the user to
0
- # "/library/books/ISBN/0743536703/edit". Naturally, you'll need to setup the routes configuration file to point to the proper controller
0
- # and action in the first place, but once you have, it can be rewritten with ease.
0
- # Let's consider a bunch of examples on how to go from "/clients/37signals/basecamp/project/dash" to somewhere else:
0
- # redirect_to(:action => "edit") =>
0
- # /clients/37signals/basecamp/project/dash
0
- # redirect_to(:client_name => "nextangle", :project_name => "rails") =>
0
- # /clients/nextangle/rails/project/dash
0
+ # Redirects are used to move from one action to another. For example, after a <tt>create</tt> action, which stores a blog entry to a database,
0
+ # we might like to show the user the new entry. Because we're following good DRY principles (Don't Repeat Yourself), we're going to reuse (and redirect to)
0
+ # a <tt>show</tt> action that we'll assume has already been created. The code might look like this:
0
- # Those redirects happen under the configuration of:
0
+ # @entry = Entry.new(params[:entry])
0
+ # # The entry was saved correctly, redirect to show
0
+ # redirect_to :action => 'show', :id => @entry.id
0
+ # # things didn't go so well, do something else
0
- #
map.connect 'clients/:client_name/:project_name/:controller/:action'0
+ #
In this case, after saving our new entry to the database, the user is redirected to the <tt>show</tt> method which is then executed.0
# == Calling multiple redirects or renders
0
@@ -214,15 +203,6 @@ module ActionController #:nodoc:
0
# render :action => "overthere" # won't be called unless monkeys is nil
0
- # Action Controller works out of the box with CGI, FastCGI, and mod_ruby. CGI and mod_ruby controllers are triggered just the same using:
0
- # WeblogController.process_cgi
0
- # FastCGI controllers are triggered using:
0
- # FCGI.each_cgi{ |cgi| WeblogController.process_cgi(cgi) }
0
DEFAULT_RENDER_STATUS_CODE = "200 OK"
0
@@ -263,10 +243,10 @@ module ActionController #:nodoc:
0
# Modern REST web services often need to submit complex data to the web application.
0
# The param_parsers hash lets you register handlers wich will process the http body and add parameters to the
0
- #
@params hash. These handlers are invoked for post and put requests.
0
+ #
<tt>params</tt> hash. These handlers are invoked for post and put requests.
0
# By default application/xml is enabled. A XmlSimple class with the same param name as the root will be instanciated
0
- # in the
@params. This allows XML requests to mask themselves as regular form submissions, so you can have one
0
+ # in the
<tt>params</tt>. This allows XML requests to mask themselves as regular form submissions, so you can have one
0
# action serve both regular forms and web service requests.
0
# Example of doing your own parser for a custom content type:
0
@@ -366,6 +346,53 @@ module ActionController #:nodoc:
0
def hide_action(*names)
0
write_inheritable_attribute(:hidden_actions, hidden_actions | names.collect { |n| n.to_s })
0
+ # Replace sensitive paramater data from the request log.
0
+ # Filters paramaters that have any of the arguments as a substring.
0
+ # Looks in all subhashes of the param hash for keys to filter.
0
+ # If a block is given, each key and value of the paramater hash and all
0
+ # subhashes is passed to it, the value or key
0
+ # can be replaced using String#replace or similar method.
0
+ # filter_parameter_logging
0
+ # => Does nothing, just slows the logging process down
0
+ # filter_parameter_logging :password
0
+ # => replaces the value to all keys matching /password/i with "[FILTERED]"
0
+ # filter_parameter_logging :foo, "bar"
0
+ # => replaces the value to all keys matching /foo|bar/i with "[FILTERED]"
0
+ # filter_parameter_logging { |k,v| v.reverse! if k =~ /secret/i }
0
+ # => reverses the value to all keys matching /secret/i
0
+ # filter_parameter_logging(:foo, "bar") { |k,v| v.reverse! if k =~ /secret/i }
0
+ # => reverses the value to all keys matching /secret/i, and
0
+ # replaces the value to all keys matching /foo|bar/i with "[FILTERED]"
0
+ def filter_parameter_logging(*filter_words, &block)
0
+ parameter_filter = Regexp.new(filter_words.collect{ |s| s.to_s }.join('|'), true) if filter_words.length > 0
0
+ define_method(:filter_parameters) do |unfiltered_parameters|
0
+ filtered_parameters = {}
0
+ unfiltered_parameters.each do |key, value|
0
+ if key =~ parameter_filter
0
+ filtered_parameters[key] = '[FILTERED]'
0
+ elsif value.is_a?(Hash)
0
+ filtered_parameters[key] = filter_parameters(value)
0
+ key, value = key.dup, value.dup
0
+ filtered_parameters[key] = value
0
+ filtered_parameters[key] = value
0
@@ -803,6 +830,10 @@ module ActionController #:nodoc:
0
# The redirection happens as a "302 Moved" header.
0
+ # When using <tt>redirect_to :back</tt>, if there is no referrer,
0
+ # RedirectBackError will be raised. You may specify some fallback
0
+ # behavior for this case by rescueing RedirectBackError.
0
def redirect_to(options = {}, *parameters_for_method_reference) #:doc:
0
@@ -901,7 +932,7 @@ module ActionController #:nodoc:
0
logger.info "\n\nProcessing #{controller_class_name}\##{action_name} (for #{request_origin}) [#{request.method.to_s.upcase}]"
0
logger.info " Session ID: #{@session.session_id}" if @session and @session.respond_to?(:session_id)
0
- logger.info " Parameters: #{
@params.inspect}"
0
+ logger.info " Parameters: #{
respond_to?(:filter_parameters) ? filter_parameters(@params).inspect : @params.inspect}"