如何使用可选的嵌套资源和 cancan?
How to work with optionally nested resources and 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 助手。
还有其他方法吗?
我会限制在没有项目范围的情况下可以访问的路线:
resources :projects do
resources :tasks
end
resources :tasks, only: :index
然后您可以为其余操作调用 cancan 辅助方法,并处理自定义加载和对 index 方法的授权:
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
注意:如果您想为两种资源处理 new/create/edit/update 操作,则需要自定义视图,使用两个控制器会更容易。
我有可以选择通过其他资源访问的资源,就像这样
resources :projects do
resources :tasks
end
resources :tasks
如果通过项目访问任务,我想呈现一些与项目相关的信息,这几乎是完全不同的。
但是,我使用 cancan 并且需要授权所有的东西,所以在我写的 TasksController 中
load_and_authorize_resource :project
load_and_authorize_resource :task, through: :project
但是当我们不嵌套任务时,这会破坏功能。
如何优雅地解决这个问题?
我的第一个想法是使用两个控制器而不是 TasksController 并使用关注点共享所有常见的东西,但这有点混乱(至少我必须明确指定视图)。
我能想到的另一种方法是手动授权,而不是使用 cancan 助手。
还有其他方法吗?
我会限制在没有项目范围的情况下可以访问的路线:
resources :projects do
resources :tasks
end
resources :tasks, only: :index
然后您可以为其余操作调用 cancan 辅助方法,并处理自定义加载和对 index 方法的授权:
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
注意:如果您想为两种资源处理 new/create/edit/update 操作,则需要自定义视图,使用两个控制器会更容易。