如何使用可选的嵌套资源和cancan?

时间:2015-01-05 20:52:29

标签: ruby-on-rails ruby-on-rails-4 cancan

我有可以选择通过其他资源访问的资源,例如

resources :projects do
  resources :tasks
end
resources :tasks

如果通过项目访问任务,我想呈现一些与项目相关的信息,这几乎完全不同。

但是,我使用cancan并且需要在TasksController中编写所有内容以便我编写

load_and_authorize_resource :project
load_and_authorize_resource :task, through: :project

但是当我们不嵌套任务时,这会破坏功能。

我怎样才能优雅地解决这个问题?

我的第一个想法是使用两个控制器而不是TasksController并使用关注点共享所有常见的东西,但这有点混乱(至少我必须明确指定视图)。

我能想到的另一种方法是手动授权而不是使用cancan帮助程序。

还有其他方法吗?

1 个答案:

答案 0 :(得分:1)

我在没有项目范围的情况下限制可以访问的路线:

resources :projects do
  resources :tasks
end
resources :tasks, only: :index

然后你可以为其余的动作调用cancan helper方法,并处理索引方法的自定义加载和授权:

class TasksController < ActionController::Base
  load_and_authorize_resource :project, except: :index
  load_and_authorize_resource :task, through: :project, except: :index

  def index
    authorize! :index, Task
    if params[:project_id].present?
      @project = Project.find(params[:project])
      authorize! :show, @project
      @tasks = @project.tasks.accessible_by(current_ability)
    else
      @tasks = Task.accessible_by(current_ability)
    end
  end

注意:如果您要处理两个资源的新/创建/编辑/更新操作,则需要自定义视图,并且使用两个控制器会更容易。