Проблема с загрузкой ресурсов CanCan

#ruby-on-rails #ruby-on-rails-3 #cancan

#ruby-on-rails #ruby-on-rails-3 #cancan

Вопрос:

Я использую CanCan и столкнулся с ошибкой, которую мне трудно диагностировать.

Некоторые пользователи, тестирующие мое приложение, получили NoMethodError: undefined method 'where' for nil:NilClass исходящие из строки, указанной ниже.

При каких обстоятельствах load_and_authorize_resource оставить @jobs as nil в этот момент?

 class JobsController < ApplicationController
  load_and_authorize_resource

  def index
    if Job::STATES.include? params[:state]
      if params[:state] == 'in_progress'
        @jobs = @jobs.where(['state = ? or state = ?', params[:state], 'needs_confirmation'])
      else
        ###################################################
        # Error thrown here
        @jobs = @jobs.where(['state = ?', params[:state]])
        ###################################################
      end
    end
  end

end
  

И соответствующий код CanCan:

 if user.role? :employee
  can :read, Job do |j|
    (j.employee == user) or ( j.employee == nil )
  end
end
  

Комментарии:

1. Можете ли вы показать соответствующий cancan код?

2. отредактировано с помощью соответствующего кода CanCan

Ответ №1:

Вы должны делать Job.where(...) — вы получаете эту ошибку, потому что вы действительно вызываете where переменную экземпляра с нулевым значением. Я лично не слишком полагаюсь на load_resource , нет никакого вреда в том, чтобы быть явным.

Комментарии:

1. Я использую load_and_authorize_resource , потому что он обрабатывает сортировку только тех заданий, которые разрешены для просмотра текущему пользователю. Я согласен, что нет никакого вреда в том, чтобы быть явным, но я не понимаю, почему вспомогательный метод не работает в этой ситуации. Его цель — установить @jobs переменную, поэтому я не понимаю, почему она остается nil . Я что-то упускаю?

2. Вы проверили свою авторизацию? Возможно, текущий пользователь не может получить доступ к ресурсу, поэтому он загружается как nil. Установите для своей авторизации значение can :manage, :all и посмотрите, @jobs равно нулю или нет. Вы также можете захотеть обрабатывать то, что вы делаете внутри jobs#index по-разному в зависимости от авторизации пользователя — проверьте документы CanCan для получения подробной информации об этом.

3. Я думаю, что это связано с авторизацией, потому что у пользователей с admin ролью, которые can :manage, :all не имеют этой проблемы. Это происходит только для пользователей с employee ролью, указанной в коде CanCan. Но эта роль явно уполномочена читать определенные задания, поэтому я не знаю, что может привести к load_resource возврату nil . Если нет подходящих заданий, он должен возвращать пустой массив.

4. Найдено почему: документы . Способности, определенные в блоках, должны быть указаны в строке условия SQL, иначе они не установят переменную экземпляра в load_resource . Ваше решение является правильным.