使用 cancan 时如何设置范围集中分配?

发布于 2024-12-28 05:38:57 字数 1321 浏览 1 评论 0原文

假设我有一个这样的模型“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 的 if/else 中断其资源加载current_user.administrator 设置 :as => :administrator 范围,以便管理员可以访问课程属性。

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

Let's say I have a model "Channel" as such (Course is a boolean attribute):

class Channel < ActiveRecord::Base
  attr_accessible :title
  attr_accessible :course, :title, :as => :administrator
end

I'm using cancan with the following ability setup:

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

Here's my current controller setup:

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

I need cancan's load_and_authorize_resource method in my controller to prevent non-administrator users from having the ability to update an existing channel where course is true, but I also need to interrupt its resource loading with an if/else based on current_user.administrator to set the :as => :administrator scope so administrators have access to the course attribute.

Is there a sensible way to do this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

橙幽之幻 2025-01-04 05:38:57

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

Fixing the update method is pretty straightforward because the mass-assignment is done by update_attributes and not in 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

For the create action I think the easiest solution is to do the assignment and the authorization manually:

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

If you end up doing this a lot, it might be worth it to use a simple custom filter instead of load_and_authorize_resource.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文