2015-01-05 2 views
2

У меня есть ресурсы, которые при необходимости могут быть доступны через другие ресурсы, например, такКак работать с дополнительными вложенными ресурсами и cancan?

resources :projects do 
    resources :tasks 
end 
resources :tasks 

Если задачи доступны через проект, я хочу сделать некоторую информацию, связанным с проектом, и это в значительной степени всей разница.

Однако я использую канкан и нужно разрешить все вещи так, в TasksController я пишу

load_and_authorize_resource :project 
load_and_authorize_resource :task, through: :project 

, но это нарушает функциональность, когда мы не гнездятся задач.

Как я могу решить эту проблему?

Моя первая мысль заключалась в том, чтобы использовать два контроллера вместо TasksController и делиться всеми распространенными вещами с помощью проблем, но это вроде беспорядочно (по крайней мере, мне нужно было бы явно указывать представления).

Еще один подход, который я могу придумать, заключается в том, чтобы разрешать вещи вручную вместо использования помощников cancan.

Есть ли другие способы?

+0

На мой взгляд, вы должны обрабатывать авторизацию по данным вручную. Для этого вам просто нужно простое условие. Использование cancan здесь может усложнить решение. Я предпочитаю проще, тем лучше. –

ответ

1

Я бы ограничить маршруты, которые могут быть без подъезда масштаба проекта:

resources :projects do 
    resources :tasks 
end 
resources :tasks, only: :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 

Примечание: если вы хотите, чтобы справиться с новыми/создавать действия/редактировать/обновления для обоих ресурсов, это потребует пользовательских представлений и будет легче с двумя контроллерами.