导轨和设计:覆盖 SessionsController [英] Rails & Devise: Override SessionsController
问题描述
我正在尝试在我的主页上设置登录表单.我按照 维基
I'm trying to set up a sign in form on my home page. I managed to do it by following the Wiki
除非登录信息不正确,否则会呈现 /devise/session/new.html.erb
.我不想要那个.我希望我的用户被重定向到 root_url
WITH 闪存消息中的错误.
Except, if the login infos are incorrect, the /devise/session/new.html.erb
is rendered.
I don't want that. I want my user to be redirected to the root_url
WITH the errors in a flash message.
我能够为另一个功能覆盖 registrations_controller.rb
但覆盖 sessions_controller.rb
给我带来了很多麻烦.
I was able to override registrations_controller.rb
for another feature but override sessions_controller.rb
gives me a lot of trouble.
我应该改变什么来做我想做的事?如果登录正确,我仍然希望用户被重定向到 after_sign_in_path
.原始控制器在这里
What am I suppose to change to do what I want ? I still want the user to be redirected to after_sign_in_path
if the sign in went right.
The original controller is here
到目前为止,我知道我必须在我的 routes.rb
So far, I know I have to do that in my routes.rb
devise_for :users, :controllers =>{:注册=>"注册", :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>
I have the feeling that I have to change the render_with_scope :new
but ...how?
With that version, I get the error undefined method 'users_url' for #<SessionsController:0x5072c88>
好吧,我会等待你的宝贵帮助
Well, I'll wait for your precious help
PS:帖子帮助我处理订阅错误.也许它有助于解决登录错误?
PS: That post helped me a lot for handling errors on subscription. Maybe it'll help for sign in errors?
==== 编辑 ====
按照第一个回答的建议,我还添加了initializers/devise.rb
:
Following the 1rst answer advice, I also added to initializers/devise.rb
:
config.warden do |manager|
manager.failure_app = CustomFailure
end
当用户未登录并尝试访问受限"区域时,他被重定向到 root_url
但当登录出错时,我现在有以下错误:
When the user is not logged and tries to access a "restricted" area, he gets redirected to root_url
but when the sign in goes wrong, I now have the following error :
The action 'devise/sessions#new' could not be found for Devise::SessionsController
(PS:我删除了我对 Session Controller 所做的一切,如果成功登录就可以了)
(PS: I deleted everything I did with Session Controller and the log in works if successful)
=== 编辑 2 ===
按照这个Wiki 重定向完美但我没有任何错误通知.
Following this Wiki the redirection works perfectly BUT I don't have any error notification.
如果有任何改变,我会显示警报/通知闪烁消息
And I'm displaying the alert/notice flash message with that if that changes anything
<% 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
The accepted answer works. Just don't forget to display flash alerts
推荐答案
您必须覆盖自定义故障设计类.
You have to override your custom failure devise Class.
在 lib/custom_failure.rb 下添加这个自定义故障类
Add this custom failure class under 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 下写这个
Write this under config/application.rb
config.autoload_paths += %W(#{config.root}/lib)
_________________编辑_____
_________________Edit __________________
您说当注册出错"时,这意味着控件应该在registrations_controller create
方法中.我想那里一定有问题.尝试添加这些路由.
You said when the 'sign up goes wrong', this means the control should be in registrations_controller create
method. Something must be wrong there, I guess. Try to add these routes.
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 ________________
________________Edit 2 ________________
在 views/devise/registrations/new.html.erb 中添加这个
Add this in views/devise/registrations/new.html.erb
<%= devise_error_messages! %>
这篇关于导轨和设计:覆盖 SessionsController的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!