#ruby-on-rails #devise #cancancan #devise-confirmable
#ruby-on-rails #devise #cancancan #разработка-подтверждаемая
Вопрос:
Переход по ссылке подтверждения в электронном письме, которое отправляется для регистрации пользователя, выдает эту ошибку:
uninitialized constant Confirmation
NameError in Devise::ConfirmationsController#show
Но если я отключусь, Cancancan
удалив load_and_authorize_resource
из ApplicationController
, ошибка не произойдет, и пользователь сможет успешно перейти по ссылке подтверждения.
Я попытался добавить skip_load_and_authorize_resource
в переопределенный контроллер Devise для подтверждений — Users::ConfirmationsController < Devise::ConfirmationsController
.
Комментарии:
1. Можете ли вы добавить еще несколько строк stacktrace? Чтобы мы могли проанализировать.
Ответ №1:
Согласно вашему объяснению, возможны следующие:
uninitialized constant Confirmation
Причиной может быть то, что он пытается выяснить модель, связанную с этим контроллером, используя имя контроллера, и результат, который он получает,Confirmation
но модели с таким именем нет.skip_load_and_authorize_resource
Может не сработать, пока у вас не будетshow
действия в самом вашем переопределенном контроллере (добавление действия before в дочернем классе, я думаю, не должно работать в родительском классе)
Я не уверен, сработает это или нет, но вы можете попробовать что-то подобное и посмотреть в своем ApplicationController
:
load_and_authorize_resource unless: :devise_controller?
Таким образом, это пропустит это before_action
для всех контроллеров devise.
Комментарии:
1. Спасибо! Выполнение unless: :devise_controller? сработало, но я изменил на, если: :confirmations_controller? потому что некоторые контроллеры devise должны следовать некоторым правилам cancancann (которые находятся в abilities.rb) — таким как обновление пользователя / профиля. Меня заинтересовала ваша первая идея — я хотел бы пропустить ее в реальном контроллере. Но я добавил действие show и все равно не сработало. Также я сделал то же самое (добавил skip_load_and_authorize_resource) в другом контроллере devise ранее, и это сработало в обход его без каких-либо действий, определенных в классе. Есть идеи?
2. Просто чтобы подтвердить, использовали ли вы те же контроллеры в файле routes, что-то вроде этого:
devise_for :users, :controllers => {:registrations => "registrations"}
, я думаю, после этого это должно сработать.3. Вот и все! После добавления этого обратно в файл routes, только добавление skip_load_and_authorize_resource в переопределенный ConfirmationsController исправило ошибку (не нужно было определять действие show). Огромное спасибо.
Ответ №2:
load_and_authorize_resource
Не следует использовать в ApplicationController
, поскольку он несовместим с устройствами и контроллерами, у которых нет моделей с таким же именем. Вместо этого установите load_and_authorize_resource
в каждом контроллере по мере необходимости.