不能像我期望的那样加载嵌套的资源



Cancan在用户登录时工作正常。但是,当一个用户是"客人"时,我希望他们能够看到一些照片,但不是那些照片的父Post有限制employees_only标志设置的照片。

问题是,如果在@photos数组中有任何与employee_only帖子相关的照片,那么Cancan将抛出CanCan::AccessDenied in PhotosController#index。但是控制器中的load_and_authorize_resource :photo, :through => :event不应该从@photos中删除那些未经授权的记录吗?

ability.rb

class Ability
  include CanCan::Ability
  def initialize(user)  
    user ||= User.new # guest user (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
  ...

用户。rb #不确定这是否有必要解决这个问题,但是j.i.c.:

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

首先,在你的能力文件中删除

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

我认为你不需要那样做,因为你限制了职位。

然后在控制器中更改

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

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

我相信您要做的是通过post加载照片,并且由于post仅限于employee_only = false的照片,因此您隐含地限制了照片。然后,在photos控制器中,你需要加载post,这样它就可以用来加载和授权照片。什么应该发生在cancan(我认为)是一个内连接是在帖子和照片之间的帖子。

最新更新