Rails & Devise: Override SessionsController

Я пытаюсь настроить форму на моей домашней странице. Мне удалось это сделать, следуя Wiki

Кроме того, если неверные данные входа в систему, отображается /devise/session/new.html.erb. Я не хочу этого. Я хочу, чтобы мой пользователь был перенаправлен на root_url WITH ошибки во флэш-сообщении.

Я смог переопределить registrations_controller.rb для другой функции, но переопределить sessions_controller.rb вызывает много проблем.

Что я могу изменить, чтобы делать то, что хочу? Я по-прежнему хочу, чтобы пользователь был перенаправлен на after_sign_in_path, если знак прошел правильно. Исходный контроллер здесь

До сих пор я знаю, что должен сделать это в своем routes.rb

devise_for :users, :controllers => { :registrations => "registrations", :sessions => "sessions" }

И я также установил controller/sessions_controller.rb

class SessionsController < Devise::SessionsController

  # GET /resource/sign_in
  def new
    resource = build_resource
    clean_up_passwords(resource)
    respond_with_navigational(resource, stub_options(resource)){ render_with_scope :new }
  end

end

У меня такое ощущение, что мне нужно изменить render_with_scope :new, но... как? С этой версией я получаю сообщение об ошибке undefined method 'users_url' for #<SessionsController:0x5072c88>

Хорошо, я буду ждать вашей драгоценной помощи

PS: Это сообщение помогло мне многое для обработки ошибок при подписке. Может быть, это поможет вам в регистрации ошибок?

==== EDIT ====

Следуя совету 1-го ответа, я также добавил к initializers/devise.rb:

config.warden do |manager|
  manager.failure_app = CustomFailure
 end

Когда пользователь не регистрируется и пытается получить доступ к "ограниченной" области, он перенаправляется на root_url, но когда ошибка входа идет не так, у меня теперь есть следующая ошибка:

The action 'devise/sessions#new' could not be found for Devise::SessionsController

(PS: я удалил все, что я сделал с Session Controller, и журнал работает в случае успеха)

=== РЕДАКТИРОВАТЬ 2 ===

После этого Wiki перенаправление работает отлично НО У меня нет уведомления об ошибке.

И я показываю сообщение с предупреждением/уведомлением с этим, если это что-то меняет

<% flash.each do |name, msg| %>          
  <% if msg.class == Array %>
    <% msg.each do |message| %>
    <%= content_tag :p, message, :id => "flash_#{name}" %>
  <% end %>
  <% else %>          
    <%= content_tag :p, msg, :id => "flash_#{name}" %>          
  <% end %>
<% end %>

=== ЗАКЛЮЧИТЕЛЬНОЕ ОБНОВЛЕНИЕ ===

Принятый ответ работает. Просто не забудьте отобразить flash alerts

Ответы

Ответ 1

Вы должны переопределить свой класс отказоустойчивости.

Добавьте этот настраиваемый класс отказов в lib/custom_failure.rb

class CustomFailure < Devise::FailureApp
  def respond
    if http_auth?
      http_auth
    elsif warden_options[:recall]
        recall
    else
      redirect
    end
  end

  def redirect
      store_location!
      flash[:alert] = i18n_message unless flash[:notice]
      redirect_to "/"
  end

  def recall
    env["PATH_INFO"] = attempted_path
    flash.now[:alert] = i18n_message(:invalid)
    self.response = recall_controller.action(warden_options[:recall]).call(env)
  end

  protected

  def i18n_message(default = nil)
    message = warden.message || warden_options[:message] || default || :unauthenticated

    if message.is_a?(Symbol)
      I18n.t(:"#{scope}.#{message}", :resource_name => scope,
             :scope => "devise.failure", :default => [message, message.to_s])
    else
      message.to_s
    end
  end

  def warden_options
    env['warden.options']
  end

  def warden
    env['warden']
  end

  def recall_controller
    "#{params[:controller].camelize}Controller".constantize
  end


  def attempted_path
    warden_options[:attempted_path]
  end

  def store_location!
    session[:"#{scope}_return_to"] = attempted_path if request.get? && !http_auth?
  end

  def attempted_path
    warden_options[:attempted_path]
  end

  def http_auth?
    !Devise.navigational_formats.include?(request_format) || (request.xhr? && Devise.http_authenticatable_on_xhr)
  end
end

Запишите это в файле config/application.rb

config.autoload_paths += %W(#{config.root}/lib)

_________________ Редактировать __________________

Вы сказали, что когда "регистрация идет не так", это означает, что элемент управления должен быть в методе registrations_controller create. Наверное, там что-то должно быть неправильно. Попытайтесь добавить эти маршруты.

devise_for :users

  devise_scope :user do
    root :to => "devise/sessions#new"
    get "sign_in", :to => "devise/sessions#new"
    get "sign_out", :to => "devise/sessions#destroy"
    get "sign_up", :to => "devise/registrations#new"
  end

________________ Редактировать 2 ________________

Добавьте это в views/devize/registrations/new.html.erb

<%= devise_error_messages! %>

Ответ 2

Если вы используете ошибку undefined method 'users_url' for #<SessionsController:0x5072c88> при переопределении контроллера сеансов разработки, вы можете указать имя пути, как показано ниже. Важным дополнением, которое вы пропустили, является , :as => :users.

  devise_scope :user do
    root :to => "devise/sessions#new", :as => :users
    get "sign_in", :to => "devise/sessions#new"
    get "sign_out", :to => "devise/sessions#destroy"
    get "sign_up", :to => "devise/registrations#new"
  end

Вышеуказанное имя маршрута может противоречить существующим или будущим маршрутам. В качестве альтернативы я обнаружил, что эта настройка имеет тенденцию работать хорошо:

  devise_for :users,
    :path_names  => { :sign_out => 'logout', 
                      :sign_in  => 'login', 
                      :sign_up  => 'register' },
    :controllers => { :sessions => 'users/sessions' } do

      # Sessions
      post '/login'         => 'users/sessions#create',       :as => :user_session
      get  '/login'         => 'users/sessions#new',          :as => :new_user_session
      get  '/logout'        => 'users/sessions#destroy',      :as => :destroy_user_session

      # Passwords
      post '/password'      => 'devise/passwords#create',     :as => :user_password
      put  '/password'      => 'devise/passwords#update'
      get  '/password/new'  => 'devise/passwords#new',        :as => :new_user_password
      get  '/password/edit' => 'devise/passwords#edit',       :as => :edit_user_password

      # Registrations
      post   '/register'    => 'devise/registrations#create', :as => :user_registration
      get    '/register'    => 'devise/registrations#new',    :as => :new_user_registration
      get    '/account'     => 'devise/registrations#edit',   :as => :edit_user_registration
      put    '/account'     => 'devise/registrations#update'
      delete '/account'     => 'devise/registrations#destroy'

  end

Ответ 3

отладка подсказки пытается удалить любую запись (пользователь будет последовательным); если вы перейдете к шоу-шоу, это не вопрос конфигурации. Для этого случая следуйте (в других случаях ответят здесь)

Я не вижу, где в представлении вы вызываете файл корневого javascript.

Я несколько раз ударился головой об этом, используя разные настройки javascript в разных макетах. Независимо от того, что читает ваш заголовок, вызов

<%= javascript_include_tag 'my-differntly-fangled-application' %>

должен содержать соответствующий файл манифеста

//= require jquery
//= require jquery_ujs