Rails & Devise: Override SessionsController



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

但是,如果登录信息不正确,则会呈现/devise/session/new.html.erb。我不想那样。我希望我的用户重定向到root_url,并带有闪存消息中的错误。

我可以为另一个功能覆盖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>

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

附言:那篇帖子对我处理订阅错误有很大帮助。也许这会对登录错误有所帮助?

===编辑===

根据第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

(附言:我删除了我对会话控制器所做的一切,如果成功,登录就会工作)

===编辑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

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

在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/design/registrations/new.html.erb 中

<%= devise_error_messages! %>

如果在重写设计会话控制器时遇到错误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

调试提示尝试删除任何记录(用户将是一致的);如果你去参加演出,那就不是设计配置的问题。对于这种情况,请跟随(其他情况在此处回答)

我看不出您在视图中调用根javascript文件的位置。

我已经试过几次了,在不同的布局中使用不同的javascript设置。无论你的标题是什么,呼叫

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

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

//= require jquery
//= require jquery_ujs

相关内容

  • 没有找到相关文章

最新更新