views:

244

answers:

4

I want to use the before action to optionally interrupt the processing if it fails to comply certain criteria (e.g. the object is not owned by such user etc)

I need to use this because I have a more complicated scenario that I need the object to be loaded before the access rights could be determined, so I would have situations where I want to interrupt the action if it is invalid access, anyway I could achieve this?

A: 

Assuming you are referring to before_filter:

Any render or redirect call should abort the filter chain and the execution of the action. So simply put your access control filter after the one to load 'stuff', then render an error message (with an appropriate status code for good web karma and to prevent a w3c beat down).

It's just another area of rails that works fine as long as you don't think too hard.

Any help or am I missing the point?

cwninja
yep you missed, its the determine by object security (ownership) that has problem. But Vitaly is right there, its cached, so I could use before filter actually.
goodwill
+1  A: 

OK, this is something I was thinking about myself when working with RC.

the usual RC action is something like:

def show
  load_object
  before :show
  response_for :show
rescue ActiveRecord::RecordNotFound
  response_for :show_fails
end

So suppose you want to interrupt the show just after load_object if some conditions fail.

The best way to do it that I could think of (except for modifying RC :) is:

  • use before_filter to check the condition
  • in the the before_filter use the object or collection helpers (according to the action). this way the load_object/load_collection in the RC action implementation will use the same value cached from your usage of the helper so no extra queries will be made.
Vitaly Kushner
yep it sounds correct- I ignored the fact its cached.
goodwill
A: 

Vitaly's approach is probably correct, but I have a interesting over-engineered approach too, so to post as a reference:

  1. Use around_filter
  2. At the before hook, throw AccessDeniedException
  3. Capture the exception in the around filter

That would do the job as well.

goodwill
A: 

If you find yourself writing before_filters for precondition checks very often, you might find Aegis useful. It allows you to define access rules in a single file so you can see at a glance who may access what.

It was also built for easy integration with resource_controller.

henning-koch