Rails&Devise:覆盖SessionsController

Luc*_*cas 14 ruby-on-rails devise ruby-on-rails-3

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

但是,如果登录信息不正确,/devise/session/new.html.erb则会进行渲染.我不希望这样.我希望我的用户被重定向到root_url 带有 flash消息中的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
Run Code Online (Sandbox Code Playgroud)

我觉得我必须改变render_with_scope :new但是......怎么样?使用该版本,我收到错误undefined method 'users_url' for #<SessionsController:0x5072c88>

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

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

====编辑====

根据第一个答案建议,我还添加到initializers/devise.rb:

config.warden do |manager|
  manager.failure_app = CustomFailure
 end
Run Code Online (Sandbox Code Playgroud)

当用户没有登录并尝试访问"受限"区域时,他被重定向到root_url但是当登录出错时,我现在有以下错误:

The action 'devise/sessions#new' could not be found for Devise::SessionsController
Run Code Online (Sandbox Code Playgroud)

(PS:我删除了使用会话控制器执行的所有操作,如果成功则登录工作正常)

===编辑2 ===

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

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

<% 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 %>
Run Code Online (Sandbox Code Playgroud)

===最终更新===

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

Muh*_*lid 14

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

在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
Run Code Online (Sandbox Code Playgroud)

在config/application.rb下写下这个

config.autoload_paths += %W(#{config.root}/lib)
Run Code Online (Sandbox Code Playgroud)

_________________编辑__________________

你说当'注册出错'时,这意味着控件应该在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
Run Code Online (Sandbox Code Playgroud)

________________编辑2 ________________

在views/devise/registrations/new.html.erb中添加它

<%= devise_error_messages! %>
Run Code Online (Sandbox Code Playgroud)