无法按照我的预期加载嵌套资源
当用户登录时,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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
首先,在你的能力文件中删除
我认为你不需要它,因为你限制了帖子。
然后在你的控制器中更改
为
我相信你想要做的是通过帖子加载照片,并且因为帖子仅限于那些employee_only = false,所以你隐式地限制了照片。然后,在照片控制器中,您需要加载帖子,以便可以使用它来加载和授权照片。 cancan 中应该发生的情况(我认为)是在帖子和照片之间完成内部联接,其中 posts.employee_only = false。
First, in your ability file remove
I don't think you need that as you are limiting on the post.
Then in your controller change
To
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.