CanCan索引动作能力

时间:2011-08-03 08:25:25

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

我在为我的相册#dedex action定义权限时遇到了一些麻烦。它的路径是/ user /:user_id / albums - 这是我的:show action(:read => [:index,:show])能够正常运行的能力。它的路径是/ user /:user_id / albums /:id /.

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

我不确定如何为索引操作编写类似的规则,或者我是否想在此处使用CanCan。规则是:

  

current_user 必须是.friends_with?(user_id)来查看属于user_id的任何相册。

user_id当然取自params [:user_id]。注意:/ 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

更新: 事实证明解决方案非常简单,我只是没注意我的路线:

resources users do
  resources albums
end

在控制器中变得非常简单:

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

规则:

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

我对此并不十分满意,因为使用user.friends_with?(other_user)方法会更快,并且不必从数据库中获取(可能)数千个ID。任何其他解决方案都是最受欢迎的。

1 个答案:

答案 0 :(得分:1)

在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