假设我有一个模型“频道”(课程是一个布尔属性):
class Channel < ActiveRecord::Base
attr_accessible :title
attr_accessible :course, :title, :as => :administrator
end
我正在使用具有以下功能设置的cancan:
class Ability
include CanCan::Ability
def initialize(user)
if user
if user.administrator
can :manage, Channel
else
can [:read, :create], Channel
can [:update, :destroy], Channel, :course => false
end
end
end
end
这是我当前的控制器设置:
class ChannelsController < ApplicationController
load_and_authorize_resource
###
def new
end
def create
if @channel.save
redirect_to @channel, :notice => "Successfully created channel."
else
render :action => 'new'
end
end
def edit
end
def update
if @channel.update_attributes(params[:channel])
redirect_to @channel, :notice => "Successfully updated channel."
else
render :action => 'edit'
end
end
###
end
我需要在我的控制器中使用cancan的load_and_authorize_resource
方法来防止非管理员用户能够更新当前为真的现有频道,但我还需要使用if / else来中断其资源加载在current_user.administrator
上设置:as => :administrator
范围,以便管理员可以访问课程属性。
有没有明智的方法可以做到这一点?
答案 0 :(得分:0)
修复update
方法非常简单,因为大量分配是由update_attributes
而不是load_and_authorize_resource
完成的:
def update
@channel.assign_attributes(params[:channel],
:as => (current_user.administrator ? :administrator : :default)
if @channel.save
redirect_to @channel, :notice => "Successfully updated channel."
else
render :action => 'edit'
end
end
对于create
操作,我认为最简单的解决方案是手动执行分配和授权:
load_and_authorize_resource :except => :create
## ----
def create
@channel = Channel.new
@channel.assign_attributes(params[:channel],
:as => (current_user.administrator ? :administrator : :default)
if @channel.save
redirect_to @channel, :notice => "Successfully created channel."
else
render :action => 'new'
end
end
如果您最终做了很多事情,那么使用简单的自定义过滤器代替load_and_authorize_resource
可能是值得的。