Rails&Devise:覆盖SessionsController

我正在尝试在我的主页上设置登录表单。 我设法通过遵循Wiki来做到这一点

但是,如果登录信息不正确, /devise/session/new.html.erb呈现/devise/session/new.html.erb 。 我不希望这样。 我希望我的用户被重定向到root_url ,并显示flash消息中的错误。

我能够覆盖registrations_controller.rb的另一个function,但覆盖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 #的错误undefined method 'users_url' for #

好吧,我会等你的宝贵帮助

PS:这篇文章帮助我处理了订阅错误。 也许它有助于登录错误?

====编辑====

在第一个答案建议之后,我还添加了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:我删除了我用会话控制器做的所有事情,如果成功,登录工作正常)

===编辑2 ===

在此Wiki之后 ,重定向工作完美, 我没有任何错误通知。

我正在显示警报/通知flash消息,如果这改变了什么

     "flash_#{name}" %>    "flash_#{name}" %>   

===最终更新===

接受的答案有效。 只是不要忘记显示flash alerts

您必须覆盖自定义故障设计类。

在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 / devise / registrations / new.html.erb中添加它

 <%= devise_error_messages! %> 

如果您在覆盖设计会话控制器时undefined method 'users_url' for #的错误undefined method 'users_url' for #可以提供如下路径名称。 您错过的重要补充是, :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 

调试提示尝试删除任何记录(用户将是连贯的); 如果你去展示动作,它不是一个设计配置问题。 对于这种情况,请继续(其他案例在这里回答)

我无法在视图中看到您调用根javascript文件的位置。

我几次在这个问题上猛烈抨击,使用不同布局的不同javascript设置。 无论你的标题是什么,电话都是

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

需要有相关的清单文件包含

 //= require jquery //= require jquery_ujs