简体   繁体   English

CanCan索引动作能力

[英]CanCan index action ability

I'm having some trouble defining permissions for my albums#index action. 我在为我的albums#index操作定义权限时遇到了麻烦。 The path to it is /user/:user_id/albums - this is the ability for my :show action (:read => [:index, :show]) which is working well. 它的路径是/ user /:user_id / albums-这是我的:show动作(:read => [:index,:show])正常运行的能力。 The path to it is /user/:user_id/albums/:id/. 它的路径是/ user /:user_id / albums /:id /。

can :read, Album do |album|
  @user.friends_with?(album.user_id)
end

I'm not sure how to write a similar rule for the index action, or if I even want to use CanCan here. 我不确定如何为索引操作编写类似的规则,或者我什至不想在这里使用CanCan。 The rule is: 规则是:

current_user MUST be .friends_with?(user_id) to view any albums belonging to user_id. current_user 必须是.friends_with?(user_id)才能查看属于user_id的所有相册。

user_id is of course taken from params[:user_id]. user_id当然是从params [:user_id]中获取的。 Note: /user/eml/albums/ would be the path, I'm not fetching users by their .id but by their .username! 注意:/ user / eml / albums /是路径,我不是通过.id而是通过.username来获取用户!

class Ability
  include CanCan::Ability

  def initialize(user)
    @user = user || User.new # for guest, probably not needed
    @user.roles.each { |role| send(role) }
  end

  def user
    can :read, Album do |album|
      @user.friends_with?(album.user_id)
    end

    can :manage, Album do |album|
      album.user_id == @user.id
    end
  end
end

UPDATE: Turns out the solution is really simple, I was just not paying attention to my routes: 更新:事实证明,解决方案非常简单,我只是不注意自己的路线:

resources users do
  resources albums
end

In the controller that becomes pretty easy then: 然后在变得非常简单的控制器中:

  load_and_authorize_resource :user, :find_by => :username
  load_and_authorize_resource :album, :through => :user

And the rule: 规则:

can :read, Album, :user_id => @user.friend_ids # I don't need @user.id

I'm not perfectly happy with it though, as using the user.friends_with?(other_user) method would be much quicker and doesn't have to fetch (potentially) a thousand ids from the database. 不过,我对此并不十分满意,因为使用user.friends_with?(other_user)方法会更快,并且不必从数据库中(可能)获取一千个id。 Any other solution is most welcome. 任何其他解决方案都是最欢迎的。

On IRC you told me that the .roles_mask isn't important... then shouldn't this be something like: 在IRC上,您告诉我.roles_mask并不重要...那么这不应该是这样的:

class Ability
  include CanCan::Ability

  def initialize(user)
    if user
      can :read, Album, :user_id => [user.id] + user.friend_ids
      can :manage, Album, :user_id => user.id
    end
  end
end

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM