开发者

Cancan not loading nested resources as I expect it to

Cancan is working fine when user's are logged in. But when a user is a "guest" I would like them to be able to see some photos, but not those where the Photo's parent Post has a restriction employees_only flag set.

Problem is if there is any photo related to an employee_only post in the @photos array then Cancan will throw CanCan::AccessDenied in PhotosController#index. But shouldn't load_and_authorize_resource :photo, :through => :event in the controller have eliminated those unauthorized records from @photos?

ability.rb

class Ability
  include CanCan::Ability

  def initialize(user)  
    user ||= User.new # guest use开发者_Python百科r (not logged in)

    if user.role? :admin
      can :manage, :all
    elsif user.role? :moderator
      can :read, :all
      can :manage, Post
      can :manage, Event
    elsif user.role? :employee
      can :read, :all
      can :create, Post
      can :update, Post, :user_id => user.id
      can :destroy, Post, :user_id => user.id
      can :update, User, :id => user.id
      can :create, Photo
      can :update, Photo, :id => user.id
      can :destroy, Photo, :id => user.id
    else
      can :read, :all
      cannot :read, Post, :employee_only => true
      cannot :read, Photo, :post => { :employee_only => true } ## <- problem?
    end
  end
end

event.rb:

class Event < ActiveRecord::Base
Event has_many :posts
Event has_many :photos, :through => :posts

post.rb

class Post < ActiveRecord::Base
  belongs_to :user
  belongs_to :event
  has_many :photos, :dependent => :destroy

photos_controller:

class PhotosController < ApplicationController
  load_and_authorize_resource :event                       ## <- problem?
  load_and_authorize_resource :photo, :through => :event   ## <- problem?

  def index
    # @event = Event.find(params[:event_id])
    # @photos = @event.photos.all

    respond_to do |format|
      format.html # index.html.erb
      format.json { render json: @events }
    end
  end
  ...

user.rb # not sure this is necessary to troubleshoot this issue but J.I.C.:

class User < ActiveRecord::Base
  attr_protected :roles_mask
  has_many :posts
  has_many :photos, :through => :posts
  ...


First, in your ability file remove

cannot :read, Photo, :post => { :employee_only => true } ## <- problem?

I don't think you need that as you are limiting on the post.

Then in your controller change

load_and_authorize_resource :event                       ## <- problem?
load_and_authorize_resource :photo, :through => :event   ## <- problem?

To

load_and_authorize_resource :post
load_and_authorize_resource :photo, :through => :post

I believe what you are trying to do is load the photos through the post- and because the post is limited to those with employee_only = false, you are implicitly limiting the photos. Then, in your photos controller you need to load the post so that it can be used to load and authorize the photos. What should happen in cancan (I think) is an inner join is done between posts and photos where posts.employee_only = false.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜