Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 7893103
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 3, 20262026-06-03T07:02:24+00:00 2026-06-03T07:02:24+00:00

tl;dr I use CanCan for authorization in a single-author blog. I want non-admin users

  • 0

tl;dr

I use CanCan for authorization in a single-author blog. I want non-admin users to not be able to view unpublished posts. The following does not do the trick:

can :read, Post do |post|
  post.published_at && post.published_at <= Time.zone.now
end

Why doesn’t it work, and what can I do to make it work?

Thanks. 😉

The long version

Hello World,

I have a single-user blogging application and use CanCan for authorization purposes. I want administrators (user.admin? # => true) to be able to do whatever they wish with everything (they are administrators after all…). I also want regular users (both those who are logged in, but does not have the admin role, and those who are not logged in) to be able to view blog posts that have been published. I do not want them to see those that are not published.

Blog posts (of the model Post) each have an attribute called published_at (which is a DateTime and nil by default). Needless to say: when published_at is nil, the post is not published, otherwise it is published at the set date and time.

I have the following in my Ability class:

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

However, this does not seem to work as I intend it to. I have read on the CanCan wiki that this might not always work. However, I believe it should work in my case here, as I do have an instance of the Post model called @post in my PostsController#show action:

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

Even with this code I am able to visit the blog post through the show action and view. I have also tried removing the authorize_resource call from the PostsController, realizing it might override some abilities or something, but it didn’t help.

I have figured out a temporary solution, although I find it ugly and really want to utilize the CanCan abilities. My ugly temporary solution checks internally in the PostsController#show if the user has access to view the resource:

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

As I said, this works. But I don’t really want to go with this solution, as I believe there’s a better way of doing this as a CanCan ability.

I’d much appreciate an explanation of why my approach does not work as well as a good solution to the problem. Thanks in advance. 🙂

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-03T07:02:26+00:00Added an answer on June 3, 2026 at 7:02 am

    At the point where authorize_resource is being called (before_filter) you don’t have a post object to authorize.

    Assuming CanCan 1.6 or later, try this..

    In your Post model

    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
    

    In your Ability model

    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
    

    In your controller

    class PostsController < ApplicationController
      load_and_authorize_resource
      respond_to :html, :json
    
      # other actions omitted ...
    
      def show
        respond_with @post
      end
    end
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

How can i use scoping with active admin & cancan. I have admin users
I am using cancan for authorization. I have a shared view which need authorize
I'm trying to incorporate Devise and Cancan into a web app. I want users
I am trying to use a Forem gem which happens to utilise CanCan authorisation
use C#,want to upload excel file on google doc. bellow syntax use to upload
I have 3 kind of users in my app: Club, Person, and Admin .
(sorry for my English ;) I started to use CanCan from rbates, this is
I'm trying to use Devise authorisation with CanCan roles in my rails3+mongoid app. Now
In trying to debug use of cancan i found that if use the following
i use a php class to make tag cloud from article, but i want

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.