Как настроить массовое назначение при использовании cancan? - PullRequest
3 голосов
/ 20 января 2012

Допустим, у меня есть модель "Канал" как таковая (курс является логическим атрибутом):

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 голосов
/ 06 июня 2012

Исправить метод 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.

...