Проблемы с переопределением контроллеров Devise - PullRequest
1 голос
/ 20 января 2012

Я пытаюсь переопределить контроллер Devise, чтобы внести некоторые незначительные изменения, например, добавить флэш-сообщение при запросе электронного письма с подтверждением для незарегистрированного адреса электронной почты.

Я пытался переопределить Devise::ConfirmationsController 1 таким образом:

# app/controllers/confirmations_controller.rb
class ConfirmationsController < Devise::ConfirmationsController

  include Devise::Controllers::InternalHelpers # tried to add this, no success

  def create
    self.resource = resource_class.send_confirmation_instructions(params[resource_name])

    if successfully_sent?(resource)
      respond_with({}, :location => after_resending_confirmation_instructions_path_for(resource_name))
    else
      respond_with(resource)
    end
  end

end

Мне кажется, я правильно добавил маршрут:

* * 1010

Мой метод контроллера вызывается, однако он вызывает это исключение:

NoMethodError in ConfirmationsController#create

undefined method `successfully_sent?' for #<ConfirmationsController:0x007fa49e229030>

В моем переопределенном контроллере я просто скопировал код Devise:: ConfirmationsController#create, который сам вызывает successfully_sent?(resource)

Метод successfully_sent? определен в InternalHelpers 2 , поэтому я попытался добавить include Devise::Controllers::InternalHelpers

Это не первый раз, когда я пытаюсь переопределить контроллер Devise, и это не первый раз, когда я терплю неудачу. Мне всегда удавалось найти обходной путь, но я хотел бы понять, чего мне не хватает ... Заранее спасибо за вашу помощь!

[EDIT] Разработать в версии 1.4.9 Рельсы 3.0.10

Ответы [ 2 ]

2 голосов
/ 22 января 2012

Что ж, благодаря помощи Кайла в комментариях к моему вопросу, я напишу правильный ответ на ошибку этого новичка.

Вместо того, чтобы смотреть на мою собственную версию Devise для переопределения контроллера,Я просто смотрел на репозиторий Devise's Github.Поскольку контроллер, который я пытался переопределить, имел изменения между моей версией и последней зафиксированной, вспомогательный метод, который я пытался использовать, просто не был определен в моей версии ...

Как указано Кайлом, вы можете использовать bundle open devise, чтобы посмотреть на код драгоценного камня, который вы на самом деле используете, или вы можете посмотреть его номер версии с помощью gem list devise и найти код для этого выпуска на Github (для Devise они устанавливают теги дляв каждом выпуске, чтобы можно было просмотреть код для выпуска 1.4.9, выбрав соответствующий тег).

Сделав это, я бы вместо этого переопределил метод create моего контроллера следующим кодом:

def create
  self.resource = resource_class.send_confirmation_instructions(params[resource_name])

  if successful_and_sane?(resource)
    set_flash_message(:notice, :send_instructions) if is_navigational_format?
    respond_with({}, :location => after_resending_confirmation_instructions_path_for(resource_name))
  else
    respond_with_navigational(resource){ render_with_scope :new }
  end
end

, который использует successful_and_sane?, а не successfully_sent? ...

Чтобы завершить этот ответ, может быть лучший способ добавить флэш-сообщение к этому методу, чем его переопределение.jarrad рекомендует использовать around_filter, но я пока не могу заставить его работать, и я не уверен, что смогу изменить отображаемое представление после того, как получу его из метода filter ... Комментарии приветствуются!

1 голос
/ 20 января 2012

Это может не помочь вам понять, почему не удается переопределить контроллер Devise, но это сохранит ваш код СУХИМЫМ, так как вам не нужно копировать код из Devise::ConfirmationsController#crete

Итак, если вы просто хотитечтобы установить флэш-сообщение, посмотрите на Фильтры для ActionControllers

В частности, посмотрите на Around Filter:

class ConfirmationsController < Devise::ConfirmationsController
  around_filter :my_custom_stuff, :only => :create

  private

  def my_custom_stuff
    # do your thing here...
  end
end
...