Ошибка при подтверждении пользователя Devise при использовании cancancan

#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:

Согласно вашему объяснению, возможны следующие:

  1. uninitialized constant Confirmation Причиной может быть то, что он пытается выяснить модель, связанную с этим контроллером, используя имя контроллера, и результат, который он получает, Confirmation но модели с таким именем нет.
  2. 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 в каждом контроллере по мере необходимости.