Open sirn opened 12 years ago
@sirn Any way you can provide a use case for this?
Hmm, I'm not sure where to start about test case since from CanCan's side it's working properly by resolving subject name from class name (the subject.class.to_s.underscore.pluralize.to_sym
if I look at the right place) so this is more like a feature request for specifying a custom subject name than a bug report...
Sorry, I misread. (Oops)
I use Draper for data filtering and for presentation (e.g. I can just call content.created_at
via Draper instead of content.created_at.strftime(...)
). They're passed to controller like normal model objects.
def show
@content = ContentDecorator.decorate(Content.find(params[:id])
end
<% if can? :create, @content %>
<li><a href="..">Create content</a></li>
<% end %>
Aren't you really looking for a way to specify a wrapper for the object you're trying to authorize?
class ContentsController < ApplicationController
load_and_authorize_resource wrapper: :content_decorator
....
end
No, I'm not. There's no problem calling the wrapper, I just want a way to specify custom subject, so I could skip calling .model
for every can?
calls to decorator object. For example, I wish I could do this:
class ContentDecorator < Draper::Base
authorize_as :contents
...
end
...and have CanCan 2.0 resolve a subject name for ContentDecorator
as :contents
instead of :content_decorators
.
I haven't checked it yet, but could the usage of model_name
(something like subject.model_name.collection.to_sym
instead of subject.class.to_s.underscore.pluralize.to_sym
) help?
I've just stumbled across exactly the same issue. It feels to me like the decoration of an object needs to happen immediately prior to the render
call (or equivalent) - hence I'm not sure CanCan is the right place to solve this problem...
Indeed how about this. Assuming you have a User
model:
class UsersController < ApplicationController
load_and_authorize_resource
def render(options = nil, extra_options = {}, &block)
@users.map! { |u| u.decorate } unless @users.nil?
@user = @user.decorate unless @user.nil?
super(options, extra_options, &block)
end
# .....
In my views I then get the decorated objects whilst my controller code remains untouched.
But a more elegant solution not requiring the render
override would be better
Thoughts?
Dear submitter, Since cancan/raynB hasn't been active for more than 6 months and no body else then ryam himself has commit permissions the cancan project is on a stand still. Since cancan has several issues including missing support for rails 4 cancan is moving forward to cancancan. More details on: #994
If your feel that your pull request or bug is still applicable (and hasn't been merged in to cancan) it would be really appreciated if you would resubmit it to cancancan (https://github.com/cancancommunity/cancancan)
We hope to see you on the other side!
CanCan 2.0 currently doesn't correctly works with Draper, since Draper wraps over the model object, its class name become that of Draper's class name. So CanCan will fail to authorize any object wrapped by Draper's decorators:
This used to works fine in CanCan 1.x. I'm not sure if I should file this bug to Draper or here, or both, but it would be nice if there's any way to make CanCan generates subject name from something else than class name.
My current workaround is to access model object from Draper decorator in
can?
, but I think it's repetitive.