stffn/declarative_authorization — pull request #166 by tovodeverett (2012-12-10 18:53:38+00:00)
Title: Avoid call to current_user in AuthorizationInController#permitted_to* when :user option is passed.

I'm using Decl_Auth with Draper, and as part of cleaning up my code with Draper I've been working on passing context information to the Decorator objects during instantiation rather than having the Decorators attempt to extract the information directly from the controller.

In the Controller, when I set up the instance variable I do something like this:

@article = Article.find(param[:id]).decorate(current_user: current_user)

In the Decorator, I then write code like this:

h.permitted_to?(:edit, :articles, user: options[:current_user])

By doing this dependency injection, I reduce the stubbing and faking I have to do on the test controller because my Decorators and Views are no longer accessing the Controller - the Controller provides everything required as part of instantiating the Decorator, and then the View and Decorator are on their own and should be able to do everything they need with only the data attached to the instance variable.

However, the `user:` option for the `permitted_to*` methods in `AuthorizationInController` doesn't work if the Controller in the test environment doesn't implement `current_user`. The hash with default values in `options_for_permit` gets populated before the overrides happen with `merge`. All of the other values are local variables and so shouldn't be a problem. Only `:user` involves a method call. I modified the code so that it would only call `current_user` if `:user` was absent from `options`. It's not the prettiest code, but I've only coded in 1.9.3, so I wanted to stay away from idioms that may not work in 1.8.*.

I did also notice that there is no way to pass `:user` to the `has_*_role*` methods. I thought about modifying these so that the signatures would be `(*roles, options = {}, &block)` and passing `:user` in options would subvert any call to `current_user`. If you want, I'd be happy to make those changes.

I'm not worried about the in model authorization dependence on `Authorization.current_user` - that one is easy enough to setup in a before block and to clear in an after block, and I'm happy thinking of that as something akin to another instance variable.

I apologize for not making any updates to the test suite. I'm still fairly new to Ruby and Rails and I was having trouble trying to figure out how to get the test suite to run in the first place.