【问题标题】:How do you set up scoped mass-assignment while using cancan?使用 cancan 时如何设置范围批量分配?
【发布时间】:2012-01-20 13:58:38
【问题描述】:

假设我有一个模型“Channel”(当然是一个布尔属性):

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 中断其资源加载987654325@ 设置:as =&gt; :administrator 范围,以便管理员可以访问课程属性。

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

【问题讨论】:

  • 嗨,你有没有设法做到这一点?我的情况完全一样!
  • 我最终将频道和课程拆分为两个单独的模型,因为在我希望如何处理每个模型方面有足够的分离,这比将它们保持为一个模型更有意义。抱歉,这可能对您没有多大帮助。

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


【解决方案1】:

修复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 可能是值得的。

【讨论】:

    猜你喜欢
    • 2013-11-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-01
    • 1970-01-01
    • 2013-09-01
    • 1970-01-01
    • 2011-09-20
    相关资源
    最近更新 更多