在使用cancan时如何设置范围的质量分配?

时间:2012-01-20 13:58:39

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

假设我有一个模型“频道”(课程是一个布尔属性):

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范围,以便管理员可以访问课程属性。

有没有明智的方法可以做到这一点?

1 个答案:

答案 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可能是值得的。