2012-01-20 2 views
1

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

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

# 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 

Я думаю, что я правильно добавил маршрут:

devise_for :users, :controllers => { :confirmations => "confirmations" } 

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

NoMethodError in ConfirmationsController#create 

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

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

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

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

[EDIT] Разрабатывают в версии 1.4.9 Rails является 3.0.10

+0

Какую версию Devise вы используете? Вы действительно скопировали код, используя «bundle open devise» (или эквивалент) из версии Devise, которую вы установили, или просто откуда-то в Интернете? Я не вижу success_sent? определенную в моей версии Devise. – Kyle

+0

Проверили маршруты, используя рейк-маршруты –

+0

@Kyle: Действительно, это ошибка моего новичка! Я смотрел последнюю последнюю версию на Github, которая не та, которую я использую ... Я отвечу на вопрос благодаря вашей помощи, поэтому ... спасибо! – rchampourlier

ответ

2

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

Вместо того, чтобы смотреть на мою собственную версию 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, но я не могу заставить его работать, и я не уверен, что все еще могу изменить визуализированный вид после того, как я уступил его из метода фильтра ... Комментарии приветствуются!

1

Это может помочь вам понять, почему перекрывая контроллер Разрабатывают не удается, но он будет держать ваш код DRY в том, что вы делаете не нужно копировать код из Devise::ConfirmationsController#crete

Так что, если вы просто хотите установить флэш сообщение, посмотрите на Filters for ActionControllers

в частности, обратите внимание на Around Фильтр:

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

    private 

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

Я напишу еще один ответ, который лучше соответствует моей проблеме, но мне нравится ваше предложение, и мы будем использовать его, поэтому тоже спасибо! (и +1 для этой подсказки). – rchampourlier

+0

Ну, я не могу найти, как добавить флеш-сообщение из round_filter. Мне интересно, возможно ли это. Когда я вызываю 'yield' в методе фильтра around, представление получается визуализированным, поэтому я не вижу (пока), как я мог бы изменить содержимое, чтобы добавить флеш-сообщение. Если вы можете мне помочь в этом, это было бы хорошо. – rchampourlier

Смежные вопросы