Sophie

Sophie

distrib > Mandriva > 2010.0 > i586 > media > contrib-release > by-pkgid > 8b99df826c3b6cf56a1caaae5f931d50 > files > 292

ruby-actionpack-2.3.4-1mdv2010.0.noarch.rpm

<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html 
     PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
  <title>Module: ActionController::Filters::ClassMethods</title>
  <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
  <meta http-equiv="Content-Script-Type" content="text/javascript" />
  <link rel="stylesheet" href="../../.././rdoc-style.css" type="text/css" media="screen" />
  <script type="text/javascript">
  // <![CDATA[

  function popupCode( url ) {
    window.open(url, "Code", "resizable=yes,scrollbars=yes,toolbar=no,status=no,height=150,width=400")
  }

  function toggleCode( id ) {
    if ( document.getElementById )
      elem = document.getElementById( id );
    else if ( document.all )
      elem = eval( "document.all." + id );
    else
      return false;

    elemStyle = elem.style;
    
    if ( elemStyle.display != "block" ) {
      elemStyle.display = "block"
    } else {
      elemStyle.display = "none"
    }

    return true;
  }
  
  // Make codeblocks hidden by default
  document.writeln( "<style type=\"text/css\">div.method-source-code { display: none }</style>" )
  
  // ]]>
  </script>

</head>
<body>



    <div id="classHeader">
        <table class="header-table">
        <tr class="top-aligned-row">
          <td><strong>Module</strong></td>
          <td class="class-name-in-header">ActionController::Filters::ClassMethods</td>
        </tr>
        <tr class="top-aligned-row">
            <td><strong>In:</strong></td>
            <td>
                <a href="../../../files/lib/action_controller/filters_rb.html">
                lib/action_controller/filters.rb
                </a>
        <br />
            </td>
        </tr>

        </table>
    </div>
  <!-- banner header -->

  <div id="bodyContent">



  <div id="contextContent">

    <div id="description">
      <p>
Filters enable controllers to run shared pre- and post-processing code for
its actions. These filters can be used to do authentication, caching, or
auditing before the intended action is performed. Or to do localization or
output compression after the action has been performed. Filters have access
to the request, response, and all the instance variables set by other
filters in the chain or by the action (in the case of after filters).
</p>
<h2>Filter inheritance</h2>
<p>
Controller inheritance hierarchies share filters downwards, but subclasses
can also add or skip filters without affecting the superclass. For example:
</p>
<pre>
  class BankController &lt; ActionController::Base
    before_filter :audit

    private
      def audit
        # record the action and parameters in an audit log
      end
  end

  class VaultController &lt; BankController
    before_filter :verify_credentials

    private
      def verify_credentials
        # make sure the user is allowed into the vault
      end
  end
</pre>
<p>
Now any actions performed on the BankController will have the audit method
called before. On the VaultController, first the audit method is called,
then the verify_credentials method. If the audit method renders or
redirects, then verify_credentials and the intended action are never
called.
</p>
<h2>Filter types</h2>
<p>
A filter can take one of three forms: method reference (symbol), external
class, or inline method (proc). The first is the most common and works by
referencing a protected or private method somewhere in the inheritance
hierarchy of the controller by use of a symbol. In the bank example above,
both BankController and VaultController use this form.
</p>
<p>
Using an external class makes for more easily reused generic filters, such
as output compression. External filter classes are implemented by having a
static <tt>filter</tt> method on any class and then passing this class to
the filter method. Example:
</p>
<pre>
  class OutputCompressionFilter
    def self.filter(controller)
      controller.response.body = compress(controller.response.body)
    end
  end

  class NewspaperController &lt; ActionController::Base
    after_filter OutputCompressionFilter
  end
</pre>
<p>
The filter method is passed the controller instance and is hence granted
access to all aspects of the controller and can manipulate them as it sees
fit.
</p>
<p>
The inline method (using a proc) can be used to quickly do something small
that doesn&#8216;t require a lot of explanation. Or just as a quick test.
It works like this:
</p>
<pre>
  class WeblogController &lt; ActionController::Base
    before_filter { |controller| head(400) if controller.params[&quot;stop_action&quot;] }
  end
</pre>
<p>
As you can see, the block expects to be passed the controller after it has
assigned the request to the internal variables. This means that the block
has access to both the request and response objects complete with
convenience methods for params, session, template, and assigns. Note: The
inline method doesn&#8216;t strictly have to be a block; any object that
responds to call and returns 1 or -1 on arity will do (such as a Proc or an
Method object).
</p>
<p>
Please note that around_filters function a little differently than the
normal before and after filters with regard to filter types. Please see the
section dedicated to around_filters below.
</p>
<h2>Filter chain ordering</h2>
<p>
Using <tt><a href="ClassMethods.html#M000164">before_filter</a></tt> and
<tt><a href="ClassMethods.html#M000167">after_filter</a></tt> appends the
specified filters to the existing chain. That&#8216;s usually just fine,
but some times you care more about the order in which the filters are
executed. When that&#8216;s the case, you can use <tt><a
href="ClassMethods.html#M000163">prepend_before_filter</a></tt> and <tt><a
href="ClassMethods.html#M000166">prepend_after_filter</a></tt>. Filters
added by these methods will be put at the beginning of their respective
chain and executed before the rest. For example:
</p>
<pre>
  class ShoppingController &lt; ActionController::Base
    before_filter :verify_open_shop

  class CheckoutController &lt; ShoppingController
    prepend_before_filter :ensure_items_in_cart, :ensure_items_in_stock
</pre>
<p>
The filter chain for the CheckoutController is now
<tt>:ensure_items_in_cart, :ensure_items_in_stock,</tt>
<tt>:verify_open_shop</tt>. So if either of the ensure filters renders or
redirects, we&#8216;ll never get around to see if the shop is open or not.
</p>
<p>
You may pass multiple filter arguments of each type as well as a filter
block. If a block is given, it is treated as the last argument.
</p>
<h2>Around filters</h2>
<p>
Around filters wrap an action, executing code both before and after. They
may be declared as method references, blocks, or objects responding to
<tt>filter</tt> or to both <tt>before</tt> and <tt>after</tt>.
</p>
<p>
To use a method as an <tt><a
href="ClassMethods.html#M000170">around_filter</a></tt>, pass a symbol
naming the Ruby method. Yield (or <tt>block.call</tt>) within the method to
run the action.
</p>
<pre>
  around_filter :catch_exceptions

  private
    def catch_exceptions
      yield
    rescue =&gt; exception
      logger.debug &quot;Caught exception! #{exception}&quot;
      raise
    end
</pre>
<p>
To use a block as an <tt><a
href="ClassMethods.html#M000170">around_filter</a></tt>, pass a block
taking as args both the controller and the action block. You can&#8216;t
call yield directly from an <tt><a
href="ClassMethods.html#M000170">around_filter</a></tt> block; explicitly
call the action block instead:
</p>
<pre>
  around_filter do |controller, action|
    logger.debug &quot;before #{controller.action_name}&quot;
    action.call
    logger.debug &quot;after #{controller.action_name}&quot;
  end
</pre>
<p>
To use a filter object with <tt><a
href="ClassMethods.html#M000170">around_filter</a></tt>, pass an object
responding to <tt>:filter</tt> or both <tt>:before</tt> and
<tt>:after</tt>. With a filter method, yield to the block as above:
</p>
<pre>
  around_filter BenchmarkingFilter

  class BenchmarkingFilter
    def self.filter(controller, &amp;block)
      Benchmark.measure(&amp;block)
    end
  end
</pre>
<p>
With <tt>before</tt> and <tt>after</tt> methods:
</p>
<pre>
  around_filter Authorizer.new

  class Authorizer
    # This will run before the action. Redirecting aborts the action.
    def before(controller)
      unless user.authorized?
        redirect_to(login_url)
      end
    end

    # This will run after the action if and only if before did not render or redirect.
    def after(controller)
    end
  end
</pre>
<p>
If the filter has <tt>before</tt> and <tt>after</tt> methods, the
<tt>before</tt> method will be called before the action. If <tt>before</tt>
renders or redirects, the filter chain is halted and <tt>after</tt> will
not be run. See Filter Chain Halting below for an example.
</p>
<h2>Filter chain skipping</h2>
<p>
Declaring a filter on a base class conveniently applies to its subclasses,
but sometimes a subclass should skip some of its superclass&#8217; filters:
</p>
<pre>
  class ApplicationController &lt; ActionController::Base
    before_filter :authenticate
    around_filter :catch_exceptions
  end

  class WeblogController &lt; ApplicationController
    # Will run the :authenticate and :catch_exceptions filters.
  end

  class SignupController &lt; ApplicationController
    # Skip :authenticate, run :catch_exceptions.
    skip_before_filter :authenticate
  end

  class ProjectsController &lt; ApplicationController
    # Skip :catch_exceptions, run :authenticate.
    skip_filter :catch_exceptions
  end

  class ClientsController &lt; ApplicationController
    # Skip :catch_exceptions and :authenticate unless action is index.
    skip_filter :catch_exceptions, :authenticate, :except =&gt; :index
  end
</pre>
<h2>Filter conditions</h2>
<p>
Filters may be limited to specific actions by declaring the actions to
include or exclude. Both options accept single actions (<tt>:only =&gt;
:index</tt>) or arrays of actions (<tt>:except =&gt; [:foo, :bar]</tt>).
</p>
<pre>
  class Journal &lt; ActionController::Base
    # Require authentication for edit and delete.
    before_filter :authorize, :only =&gt; [:edit, :delete]

    # Passing options to a filter with a block.
    around_filter(:except =&gt; :index) do |controller, action_block|
      results = Profiler.run(&amp;action_block)
      controller.response.sub! &quot;&lt;/body&gt;&quot;, &quot;#{results}&lt;/body&gt;&quot;
    end

    private
      def authorize
        # Redirect to login unless authenticated.
      end
  end
</pre>
<h2>Filter Chain Halting</h2>
<p>
<tt><a href="ClassMethods.html#M000164">before_filter</a></tt> and <tt><a
href="ClassMethods.html#M000170">around_filter</a></tt> may halt the
request before a controller action is run. This is useful, for example, to
deny access to unauthenticated users or to redirect from HTTP to HTTPS.
Simply call render or redirect. After filters will not be executed if the
filter chain is halted.
</p>
<p>
Around filters halt the request unless the action block is called. Given
these filters
</p>
<pre>
  after_filter :after
  around_filter :around
  before_filter :before
</pre>
<p>
The filter chain will look like:
</p>
<pre>
  ...
  .      #   .  #around (code before yield)
  .  .       #   .  .  #before (actual filter code is run)
  .  .  .       #   .  .  .  execute controller action
  .  .  .  /
  .  .  ...
  .  .  /
  .  #around (code after yield)
  . /
  #after (actual filter code is run, unless the around filter does not yield)
</pre>
<p>
If <tt>around</tt> returns before yielding, <tt>after</tt> will still not
be run. The <tt>before</tt> filter and controller action will not be run.
If <tt>before</tt> renders or redirects, the second half of <tt>around</tt>
and will still run but <tt>after</tt> and the action will not. If
<tt>around</tt> fails to yield, <tt>after</tt> will not be run.
</p>

    </div>


   </div>

    <div id="method-list">
      <h3 class="section-bar">Methods</h3>

      <div class="name-list">
      <a href="#M000167">after_filter</a>&nbsp;&nbsp;
      <a href="#M000165">append_after_filter</a>&nbsp;&nbsp;
      <a href="#M000168">append_around_filter</a>&nbsp;&nbsp;
      <a href="#M000162">append_before_filter</a>&nbsp;&nbsp;
      <a href="#M000170">around_filter</a>&nbsp;&nbsp;
      <a href="#M000164">before_filter</a>&nbsp;&nbsp;
      <a href="#M000174">filter_chain</a>&nbsp;&nbsp;
      <a href="#M000166">prepend_after_filter</a>&nbsp;&nbsp;
      <a href="#M000169">prepend_around_filter</a>&nbsp;&nbsp;
      <a href="#M000163">prepend_before_filter</a>&nbsp;&nbsp;
      <a href="#M000172">skip_after_filter</a>&nbsp;&nbsp;
      <a href="#M000171">skip_before_filter</a>&nbsp;&nbsp;
      <a href="#M000173">skip_filter</a>&nbsp;&nbsp;
      </div>
    </div>

  </div>


    <!-- if includes -->

    <div id="section">





      


    <!-- if method_list -->
    <div id="methods">
      <h3 class="section-bar">Public Instance methods</h3>

      <div id="method-M000167" class="method-detail">
        <a name="M000167"></a>

        <div class="method-heading">
          <span class="method-name">after_filter</span><span class="method-args">(*filters, &amp;block)</span>
        </div>
      
        <div class="method-description">
          <p>
Alias for <a href="ClassMethods.html#M000165">append_after_filter</a>
</p>
        </div>
      </div>

      <div id="method-M000165" class="method-detail">
        <a name="M000165"></a>

        <div class="method-heading">
          <a href="ClassMethods.src/M000165.html" target="Code" class="method-signature"
            onclick="popupCode('ClassMethods.src/M000165.html');return false;">
          <span class="method-name">append_after_filter</span><span class="method-args">(*filters, &amp;block)</span>
          </a>
        </div>
      
        <div class="method-description">
          <p>
The passed <tt>filters</tt> will be appended to the array of filters that
run <em>after</em> actions on this controller are performed.
</p>
        </div>
      </div>

      <div id="method-M000168" class="method-detail">
        <a name="M000168"></a>

        <div class="method-heading">
          <a href="ClassMethods.src/M000168.html" target="Code" class="method-signature"
            onclick="popupCode('ClassMethods.src/M000168.html');return false;">
          <span class="method-name">append_around_filter</span><span class="method-args">(*filters, &amp;block)</span>
          </a>
        </div>
      
        <div class="method-description">
          <p>
If you <tt><a href="ClassMethods.html#M000168">append_around_filter</a>
A.new, B.new</tt>, the filter chain looks like
</p>
<pre>
  B#before
    A#before
      # run the action
    A#after
  B#after
</pre>
<p>
With around filters which yield to the action block, <tt>before</tt> and
<tt>after</tt> are the code before and after the yield.
</p>
        </div>
      </div>

      <div id="method-M000162" class="method-detail">
        <a name="M000162"></a>

        <div class="method-heading">
          <a href="ClassMethods.src/M000162.html" target="Code" class="method-signature"
            onclick="popupCode('ClassMethods.src/M000162.html');return false;">
          <span class="method-name">append_before_filter</span><span class="method-args">(*filters, &amp;block)</span>
          </a>
        </div>
      
        <div class="method-description">
          <p>
The passed <tt>filters</tt> will be appended to the <a
href="ClassMethods.html#M000174">filter_chain</a> and will execute before
the action on this controller is performed.
</p>
        </div>
      </div>

      <div id="method-M000170" class="method-detail">
        <a name="M000170"></a>

        <div class="method-heading">
          <span class="method-name">around_filter</span><span class="method-args">(*filters, &amp;block)</span>
        </div>
      
        <div class="method-description">
          <p>
Alias for <a href="ClassMethods.html#M000168">append_around_filter</a>
</p>
        </div>
      </div>

      <div id="method-M000164" class="method-detail">
        <a name="M000164"></a>

        <div class="method-heading">
          <span class="method-name">before_filter</span><span class="method-args">(*filters, &amp;block)</span>
        </div>
      
        <div class="method-description">
          <p>
Alias for <a href="ClassMethods.html#M000162">append_before_filter</a>
</p>
        </div>
      </div>

      <div id="method-M000174" class="method-detail">
        <a name="M000174"></a>

        <div class="method-heading">
          <a href="ClassMethods.src/M000174.html" target="Code" class="method-signature"
            onclick="popupCode('ClassMethods.src/M000174.html');return false;">
          <span class="method-name">filter_chain</span><span class="method-args">()</span>
          </a>
        </div>
      
        <div class="method-description">
          <p>
Returns an array of Filter objects for this controller.
</p>
        </div>
      </div>

      <div id="method-M000166" class="method-detail">
        <a name="M000166"></a>

        <div class="method-heading">
          <a href="ClassMethods.src/M000166.html" target="Code" class="method-signature"
            onclick="popupCode('ClassMethods.src/M000166.html');return false;">
          <span class="method-name">prepend_after_filter</span><span class="method-args">(*filters, &amp;block)</span>
          </a>
        </div>
      
        <div class="method-description">
          <p>
The passed <tt>filters</tt> will be prepended to the array of filters that
run <em>after</em> actions on this controller are performed.
</p>
        </div>
      </div>

      <div id="method-M000169" class="method-detail">
        <a name="M000169"></a>

        <div class="method-heading">
          <a href="ClassMethods.src/M000169.html" target="Code" class="method-signature"
            onclick="popupCode('ClassMethods.src/M000169.html');return false;">
          <span class="method-name">prepend_around_filter</span><span class="method-args">(*filters, &amp;block)</span>
          </a>
        </div>
      
        <div class="method-description">
          <p>
If you <tt><a href="ClassMethods.html#M000169">prepend_around_filter</a>
A.new, B.new</tt>, the filter chain looks like:
</p>
<pre>
  A#before
    B#before
      # run the action
    B#after
  A#after
</pre>
<p>
With around filters which yield to the action block, <tt>before</tt> and
<tt>after</tt> are the code before and after the yield.
</p>
        </div>
      </div>

      <div id="method-M000163" class="method-detail">
        <a name="M000163"></a>

        <div class="method-heading">
          <a href="ClassMethods.src/M000163.html" target="Code" class="method-signature"
            onclick="popupCode('ClassMethods.src/M000163.html');return false;">
          <span class="method-name">prepend_before_filter</span><span class="method-args">(*filters, &amp;block)</span>
          </a>
        </div>
      
        <div class="method-description">
          <p>
The passed <tt>filters</tt> will be prepended to the <a
href="ClassMethods.html#M000174">filter_chain</a> and will execute before
the action on this controller is performed.
</p>
        </div>
      </div>

      <div id="method-M000172" class="method-detail">
        <a name="M000172"></a>

        <div class="method-heading">
          <a href="ClassMethods.src/M000172.html" target="Code" class="method-signature"
            onclick="popupCode('ClassMethods.src/M000172.html');return false;">
          <span class="method-name">skip_after_filter</span><span class="method-args">(*filters)</span>
          </a>
        </div>
      
        <div class="method-description">
          <p>
Removes the specified filters from the <tt>after</tt> filter chain. Note
that this only works for skipping method-reference filters, not procs. This
is especially useful for managing the chain in inheritance hierarchies
where only one out of many sub-controllers need a different hierarchy.
</p>
<p>
You can control the actions to skip the filter for with the <tt>:only</tt>
and <tt>:except</tt> options, just like when you apply the filters.
</p>
        </div>
      </div>

      <div id="method-M000171" class="method-detail">
        <a name="M000171"></a>

        <div class="method-heading">
          <a href="ClassMethods.src/M000171.html" target="Code" class="method-signature"
            onclick="popupCode('ClassMethods.src/M000171.html');return false;">
          <span class="method-name">skip_before_filter</span><span class="method-args">(*filters)</span>
          </a>
        </div>
      
        <div class="method-description">
          <p>
Removes the specified filters from the <tt>before</tt> filter chain. Note
that this only works for skipping method-reference filters, not procs. This
is especially useful for managing the chain in inheritance hierarchies
where only one out of many sub-controllers need a different hierarchy.
</p>
<p>
You can control the actions to skip the filter for with the <tt>:only</tt>
and <tt>:except</tt> options, just like when you apply the filters.
</p>
        </div>
      </div>

      <div id="method-M000173" class="method-detail">
        <a name="M000173"></a>

        <div class="method-heading">
          <a href="ClassMethods.src/M000173.html" target="Code" class="method-signature"
            onclick="popupCode('ClassMethods.src/M000173.html');return false;">
          <span class="method-name">skip_filter</span><span class="method-args">(*filters)</span>
          </a>
        </div>
      
        <div class="method-description">
          <p>
Removes the specified filters from the filter chain. This only works for
method reference (symbol) filters, not procs. This method is different from
<a href="ClassMethods.html#M000172">skip_after_filter</a> and <a
href="ClassMethods.html#M000171">skip_before_filter</a> in that it will
match any before, after or yielding around filter.
</p>
<p>
You can control the actions to skip the filter for with the <tt>:only</tt>
and <tt>:except</tt> options, just like when you apply the filters.
</p>
        </div>
      </div>


    </div>


  </div>


<div id="validator-badges">
  <p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p>
</div>

</body>
</html>