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