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

时间:2011-08-30 20:09:38

标签: ruby-on-rails ruby-on-rails-3.1 cancan nested-resources

当用户登录时,Cancan工作正常。但是当用户是“访客”时,我希望他们能够看到一些照片,但不能看到Photo的父Post有限制employees_only国旗集。

问题是,如果employee_only数组中的@photos帖子中有任何相关照片,则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
  ...

user.rb#不确定这是解决此问题所必需的,但J.I.C。:

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

1 个答案:

答案 0 :(得分:0)

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

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

我相信你要做的是通过帖子加载照片,因为帖子仅限于employee_only = false的帖子,你隐含地限制了照片。然后,在您的照片控制器中,您需要加载帖子,以便它可用于加载和授权照片。 cancan(我认为)应该发生的事情是在帖子和照片之间进行内连接,其中posts.employee_only = false。