gpt4 book ai didi

ruby-on-rails-3 - 如何使用非标准关系名称指定嵌套 CanCan 授权?

转载 作者:行者123 更新时间:2023-12-03 01:15:43 26 4
gpt4 key购买 nike

我使用 Devise 进行身份验证,使用 CanCan 进行授权。

目标

我有两个模型:用户和赞助,其中赞助提供了一个 has_many :through 用户作为赞助者和用户作为客户之间的关系。

我想将 CanCan 配置为 sponsor? 的用户权限可以管理自己的赞助,即只赞助Sponsorship#client_id == user.id 。用户还可以拥有 admin?特权,在这种情况下,他或她可以管理任何赞助。

模型

class User < ActiveRecord::Base
has_many :sponsor_links, :class_name => 'Sponsorship', :foreign_key => 'client_id'
has_many :sponsors, :through => :sponsor_links, :class_name => 'User'

has_many :client_links, :class_name => 'Sponsorship', :foreign_key => 'sponsor_id'
has_many :clients, :through => :client_links, :class_name => 'User'

def has_role?(role)
... return true if this user has <role> privileges
end
end

class Sponsorship
belongs_to :sponsor, :class_name => 'User'
belongs_to :client, :class_name => 'User'
end

class Ability
include CanCan::Ability

def initialize(user)
user ||= User.new # handle guest user (not logged in)
if user.has_role?(:admin)
can :manage, :all
elsif user.has_role?(:sponsor)
# not sure if the third argument is correct...
can :manage, Sponsorship, :sponsor => {:user_id => user.id}
end
end
end

路线

我设置了嵌套路由来反射(reflect)赞助用户拥有其客户的事实:

resource :users, :only => [:index]
resource :sponsorships
end

问题

在 SponsorshipsController 中加载和授权用户和赞助资源的正确方法是什么?

我尝试过的

这类似于普通的嵌套资源,CanCan 可以轻松处理。但这些关系具有非标准名称(例如:sponsor_links而不是:sponsorships),而且我还没有弄清楚如何配置 load_and_authorize_resource我的 SponsorshipsController 中的声明。

在我尝试过的许多不起作用的事情中;),这是一个更简单的版本。 (另请注意,我的能力可能未正确设置 - 见上文):

class SponsorshipsController < ApplicationController
load_and_authorize_resource :sponsor_links, :class_name => "User"
load_and_authorize_resource :sponsorships, :through => :sponsor_links
respond_to :json

# GET /users/:user_id/sponsorships.json
def index
respond_to @sponsorships
end

# GET /users/:user_id/sponsorships/:id.json
def show
respond_to @sponsorship
end
end

通过挽救 CanCan::AccessDenied 错误,我知道:

  • index:sponsor用户,用户身份验证失败。
  • index:admin用户,赞助身份验证失败。
  • show ,无论角色如何,赞助身份验证都会失败。

最佳答案

部分答案

第一个问题出现在能力规范中,内容如下:

...if user.has_role?(:sponsor)
can :manage, Sponsorship, :sponsor => {:user_id => user.id}
end

但应该刚刚

...if user.has_role?(:sponsor)
can :manage, Sponsorship, :user_id => user.id
end

(记住, children ,unit tests是你的 friend !不知怎的,我忘记了那节课。)

在 Controller 中,我还更改了:

  load_and_authorize_resource :sponsor_links, :class_name => "User"
load_and_authorize_resource :sponsorships, :through => :sponsor_links

只是

  load_and_authorize_resource :user
load_and_authorize_resource :sponsorship

大部分有效:它设置@user和@sponsorship并授权对它们的访问。但索引函数加载当前用户可访问的所有赞助,而不仅仅是 :user_id 拥有的赞助。我的解决办法——可能不是最佳的——是重写索引函数

  def index
respond_with(@user, @sponsorships)
end

  def index
@sponsorships = @sponsorships.where(:sponsor_id => @user.id)
respond_with(@user, @sponsorships)
end

通过这些更改,一切正常。

如果有人有更合适的方式来表达这一点,我想知道。

关于ruby-on-rails-3 - 如何使用非标准关系名称指定嵌套 CanCan 授权?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10093725/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com