#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
. Ваше решение является правильным.