tl; dr
単著ブログでの承認にはCanCanを使用しています。管理者以外のユーザーが未公開の投稿を表示できないようにしたい。以下はトリックを行いません:
can :read, Post do |post|
post.published_at && post.published_at <= Time.zone.now
end
なぜそれが機能しないのですか、そしてそれを機能させるために私は何ができますか?
ありがとう。;-)
ロングバージョン
こんにちは世界、
私はシングルユーザーのブログアプリケーションを持っており、承認の目的で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
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
私はまた、呼び出しをから削除しようとしましたPostsController
が、それがいくつかの能力などをオーバーライドする可能性があることに気づきましたが、それは役に立ちませんでした。
私は一時的な解決策を見つけましたが、それは醜く、CanCanの能力を本当に活用したいと思っています。PostsController#show
私の醜い一時的な解決策は、ユーザーがリソースを表示するためのアクセス権を持っているかどうかを内部的にチェックします。
def show
@post = Post.find params[:id]
unless @post.published_at
raise CanCan::AccessDenied unless current_user && current_user.admin?
end
respond_with @post
end
私が言ったように、これはうまくいきます。しかし、CanCanの能力としてこれを行うためのより良い方法があると私は信じているので、私はこの解決策を実際に使いたくありません。
私のアプローチがうまくいかない理由の説明と、問題の良い解決策をいただければ幸いです。前もって感謝します。:-)