我在单作者博客中使用CanCan进行授权。我希望非管理员用户无法查看未发布的帖子。以下不起作用:
can :read, Post do |post|
post.published_at && post.published_at <= Time.zone.now
end
为什么它不起作用,我该怎么做才能使它发挥作用?
感谢。 ; - )
Hello World,
我有一个单用户博客应用程序,并使用CanCan进行授权。我希望管理员(user.admin? # => true
)能够随心所欲地做任何事情(毕竟他们是管理员......)。我还希望普通用户(包括已登录但没有admin
角色的用户和未登录的用户)能够查看已发布的博客帖子。我不希望他们看到那些没有发表的内容。
博客帖子(模型Post
)每个都有一个名为published_at
的属性(默认为DateTime
和nil
)。不用说:当published_at
为nil
时,帖子不会发布,否则会在设定的日期和时间发布。
我的Ability
课程中有以下内容:
class Ability
include CanCan::Ability
def initialize user
user ||= User.new # guest user (not logged in)
if user.admin?
can :manage, :all
else
can :read, Post do |post|
post.published_at && post.published_at <= Time.zone.now
end
end
end
end
然而,这似乎并不像我想的那样有效。我已阅读CanCan wiki,这可能并不总是有效。但是,我认为它应该适用于我的情况,因为我在Post
操作中有一个名为@post
的{{1}}模型的实例:
PostsController#show
即使使用此代码,我也可以通过class PostsController < ApplicationController
authorize_resource
respond_to :html, :json
# other actions omitted ...
def show
@post = Post.find params[:id]
respond_with @post
end
# other actions omitted ...
end
操作和视图访问博客文章。我还尝试从show
删除authorize_resource
来电,意识到它可能会覆盖某些功能或某些功能,但它没有帮助。
我已经找到了一个临时解决方案,虽然我发现它很难看并且真的想要利用CanCan的能力。如果用户有权查看资源,那么我丑陋的临时解决方案会在PostsController
内部进行检查:
PostsController#show
正如我所说,这是有效的。但我真的不想采用这种解决方案,因为我相信有更好的方法可以做到这一点作为CanCan能力。
我非常感谢我解释为什么我的方法不能很好地解决问题。提前致谢。 : - )
答案 0 :(得分:0)
在调用authorize_resource(before_filter)时,您没有要授权的帖子对象。
假设CanCan 1.6或更高版本,试试这个..
在你的帖子模型中
class Post < ActiveRecord::Base
scope :published, lambda { where('published_at IS NOT NULL AND published_at <= ?', Time.zone.now) }
# the rest of your model code
end
在你的能力模型中
class Ability
include CanCan::Ability
def initialize user
user ||= User.new # guest user (not logged in)
if user.admin?
can :manage, :all
else
can :read, Post, Post.published do |post|
post.published_at && post.published_at <= Time.zone.now
end
end
end
end
在您的控制器中
class PostsController < ApplicationController
load_and_authorize_resource
respond_to :html, :json
# other actions omitted ...
def show
respond_with @post
end
end