CanCan 和数据集
我已经为此苦苦挣扎了一段时间,最后我发现 CanCan 似乎不允许您授权记录集合。例如:
ads_controller.rbability.rb
def index
@ads = Ad.where("ads.published_at >= ?", 30.days.ago).order("ads.published_at DESC")
authorize! :read, @ads
end
。
def initialize(user)
user ||= User.new # Guest user
if user
if user.role? :admin # Logged in as admin
can :manage, :all
else # Logged in as general user
can :read, Ad
can :read_own, Ad, :user_id => user.id
can :create, Ad
end
else # Not logged in (Guest)
can :read, Ad
end
end
当尝试访问索引操作时,这会导致未经授权的访问消息
You are not authorized to access this page.
但是,如果您更改索引操作中的授权调用以检查 Ad 类而不是像这样的集合
def index
@ads = Ad.where("ads.published_at >= ?", 30.days.ago)
authorize! :read, Ad
end
......它工作正常。
任何解释这一点的帮助将不胜感激。
提前致谢。
附:我最初在尝试解决这个问题时遇到了重定向循环。事实证明,有一个问题,其中包含推荐的rescue_from,您将其放入应用程序控制器中以提供不错的错误消息。如果你的root_path设置为你授权的地方!调用不正确(或失败),您将得到一个重定向循环。注释掉rescue_from 通过艰难的方式了解到这一点。
I've been struggling through this for some time and I've finally got to the point where it seems that CanCan doesn't allow you to authorize a collection of records. For example:
ads_controller.rb
def index
@ads = Ad.where("ads.published_at >= ?", 30.days.ago).order("ads.published_at DESC")
authorize! :read, @ads
end
ability.rb
def initialize(user)
user ||= User.new # Guest user
if user
if user.role? :admin # Logged in as admin
can :manage, :all
else # Logged in as general user
can :read, Ad
can :read_own, Ad, :user_id => user.id
can :create, Ad
end
else # Not logged in (Guest)
can :read, Ad
end
end
This results the unauthorised access message when trying to access the index action.
You are not authorized to access this page.
However, if you change the authorize call in the index action to check on the Ad class rather than the collection like so
def index
@ads = Ad.where("ads.published_at >= ?", 30.days.ago)
authorize! :read, Ad
end
... it works fine.
Any help in explaining this one would be greatly appreciated.
Thanks in advance.
ps. I was originally getting redirect loops when trying to work this out. It turns out there's a gotchya with the recommended rescue_from that you put in the application controller to give you nice error messages. If your root_path is set to the same place where your authorize! call is not true (or failing), you'll get a redirect loop. Comment out the rescue_from Learnt that one the hard way.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
CanCan 并不是为这样的使用而设计的。您可以检查用户是否拥有模型类(例如
Ad
)或单个实例(例如@ad
)的权限。我建议您只使用
accessible_by
来过滤您的集合:另一种方法是根据您用于检索集合的条件定义自定义权限:
CanCan is not designed to be used like that. You can check whether a user has permissions on the model class (e.g.
Ad
) or a single instance (e.g.@ad
).I suggest you just use
accessible_by
to filter your collection:Another approach would be to define a custom permission based on the conditions you use to retrieve the collection:
我使用 splats 解决了这个问题。在此代码示例中,我尝试向用户授权
TimeOffRequests
集合。如果用户是管理员、经理或休假请求属于他们,则他们应该获得授权。如果您有兴趣,我在这里详细写了它:http://zacstewart.com/2012/01/08/defining-powered-for-collections-of-records-using-cancan.html
I solved this problem usings splats. In this code example, I am trying to authorize users on a collection of
TimeOffRequests
. They should be authorized if the User is an admin, a manager or the time off request belongs to them.I wrote about it in detail here if you're interested: http://zacstewart.com/2012/01/08/defining-abilities-for-collections-of-records-using-cancan.html