我有用户
class User < ActiveRecord::Base
devise :database_authenticatable,
:recoverable, :rememberable, :trackable, :validatable
attr_accessible :email, :password, :password_confirmation,
:remember_me, :site_id, :role_name
belongs_to :site
end
位点
class Site < ActiveRecord::Base
has_many :users
has_one :front_page_campaign
end
和front_page_campaigns
class FrontPageCampaign < ActiveRecord::Base
belongs_to :site
end
我正在使用cancan来限制访问权限,因此用户只能为自己的网站管理front_page_campaigns:
class Ability
include CanCan::Ability
def initialize(user)
user ||= User.new # guest user (not logged in)
case user.role_name
when "super_admin"
# can do everything
can :manage, :all
when "editor"
# can edit content for their site
can [:create, :read, :update], FrontPageCampaign, site_id: user.site_id
end
end
end
这适用于super_admin
上展示和编辑的role_name editor
以及front_page_campaigns
用户。但是当editor
尝试创建新的front_page_campaign时,我会收到一封禁止加入的cancan
You are not authorized to access this page.
标准表格提供了所有网站的下拉框,我想我需要将其限制在用户自己的网站上。我该怎么做呢?
答案 0 :(得分:1)
您的授权问题可以通过添加:
来解决can :new, FrontPageCampaign
到cancan ability init的编辑部分。 要在new和create对象上设置site_id,可以设置before_filter:
# FrontPageCampaignsController
before_filter :set_site_id, :only => [:new, :create]
protected
def set_site_id
@resource.site_id = current_user.site_id if current_user && current_user.role_name == 'editor'
end
您必须确保在创建资源之后但在可以授权之前触发此操作。
在您的表单中(如果您对superadmin和编辑器使用相同的内容),请在current_user.role_name == 'editor'
时将网站下拉列表选择为只读或隐藏。
请注意,如果有人篡改表单并发送外星人site_id作为编辑器,它将被前置过滤器更正,这不太好。如果你拿出:only => :new
,那么他们将获得cancan的授权错误。如果你是超级迂腐,你应该得到一个有效的回复,并带有验证错误。你可以通过1)将before_filter仅应用于new和2)在能力初始化
when "editor"
# can edit content for their site
can [:read, :update], FrontPageCampaign, site_id: user.site_id
can [:create, :new], FrontPageCampaign
end
和3)将网站所有者检查添加到模型验证中。这是我的首选方式,为非法访问现有资源保留授权错误。
希望这能回答你的问题