Skip to content

Handle derived controllers better #6

@be9

Description

@be9

Some people expect ACL block in derived controller to extend its counterpart from the base controller. So they put rather restrictive rules to the base (e.g. deny all), trynig to loosen the restrictions in descendant controllers.

Unfortunately this doesn't work. Each access_control call with a block results in a filter being appended to the "before" filter chain. Now add more filters, get more restrictive behavior.

skip_before_filter comes to the rescue when you need to circumvent ACL block from the base controller, but how could we truly inherit ACL rules?

I see several possibilities.

  1. Declare "virtual" ACL blocks, which are used only for inheritance. Something like:

    class BaseController < ApplicationController
      # ...
      access_control :base, :virtual => true do
        deny anonymous
      end
      # ...
    end
    
    class DerivedController < BaseController
      access_control do
        extends :base
        allow anonymous, :to => [:show, :index]
        allow logged_in
      end
    end
    

Here :base block doesn't get installed in BaseController as a filter.

  1. Modification of (1).

Install the filter, but also save the rules into inheritable array. Each derived controller will append its rules, calling skip_before_filter against the inherited filter.

    class BaseController < ApplicationController
      # ...
      access_control :base, :virtual => true do
        deny anonymous
      end
      # ...
    end

    class DerivedController < BaseController
      access_control :base do
        allow anonymous, :to => [:show, :index]
        allow logged_in
      end
    end

    class DerivedDerivedController < DerivedController
      access_control :base do
        allow anonymous, :to => [:custom]
      end
    end

We get 3 blocks here. The 3rd block is used to match first (both for allow and for deny). If it doesn't bring a match, the 2nd block is tried and then the 1st.

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions