CanCan索引行动能力
我在定义 albums#index 操作的权限时遇到一些问题。它的路径是 /user/:user_id/albums - 这是我的 :show 操作 (:read => [:index, :show]) 的功能,效果很好。它的路径是/user/:user_id/albums/:id/。
can :read, Album do |album|
@user.friends_with?(album.user_id)
end
我不确定如何为索引操作编写类似的规则,或者我是否想在此处使用 CanCan。规则是:
当前用户必须是.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。任何其他解决方案都是最受欢迎的。
I'm having some trouble defining permissions for my albums#index action. The path to it is /user/:user_id/albums - this is the ability for my :show action (:read => [:index, :show]) which is working well. The path to it is /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. The rule is:
current_user MUST be .friends_with?(user_id) to view any albums belonging to user_id.
user_id is of course taken from params[:user_id]. Note: /user/eml/albums/ would be the path, I'm not fetching users by their .id but by their .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. Any other solution is most welcome.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
在 IRC 上你告诉我 .roles_mask 并不重要...那么这不应该是这样的:
On IRC you told me that the .roles_mask isn't important... then shouldn't this be something like: