无法按照我的预期加载嵌套资源

发布于 2024-12-02 04:50:23 字数 2201 浏览 3 评论 0原文

当用户登录时,Cancan 工作正常。但是当用户是“访客”时,我希望他们能够看到一些照片,但不能看到照片的父帖子有限制的照片 employees_only标志设置。

问题是,如果 @photos 数组中存在与 employee_only 帖子相关的任何照片,则 Cancan 将在 PhotosController#index 中抛出 CanCan::AccessDenied 。但不应该 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 # 不确定这对于解决此问题是否必要,但 JIC:

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

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 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 # 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
  ...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

黑寡妇 2024-12-09 04:50:23

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

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。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文