Rails & Devise: Override SessionsController

前端 未结 3 425
臣服心动
臣服心动 2021-02-01 23:22

I\'m trying to set up a sign in form on my home page. I managed to do it by following the Wiki

Except, if the login infos are incorrect, the /devise/session/new.ht

相关标签:
3条回答
  • 2021-02-02 00:13

    debugging hint attempt to delete any record (a user would be coherent); if you go to the show action, it is not a devise configuration matter. For this case, follow along (other cases are answered around here)

    I cannot see where in the view you are calling the root javascript file.

    I've banged my head on this one a few times, using different javascript set-ups in different layouts. Whatever your header reads, the call

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

    needs to have the relevant manifest file include

    //= require jquery
    //= require jquery_ujs
    
    0 讨论(0)
  • 2021-02-02 00:16

    You have to override your custom failure devise Class.

    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
    

    Write this under config/application.rb

    config.autoload_paths += %W(#{config.root}/lib)
    

    _________________Edit __________________

    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
    

    ________________Edit 2 ________________

    Add this in views/devise/registrations/new.html.erb

    <%= devise_error_messages! %>
    
    0 讨论(0)
  • 2021-02-02 00:17

    If you're running into the error undefined method 'users_url' for #<SessionsController:0x5072c88> when overriding the devise sessions controller you can provide a path name as below. The important addition that you missed is the , :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
    

    The above route name might conflict with existing or future routes. As an alternative, I have found that this setup tends to work well:

      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
    
    0 讨论(0)
提交回复
热议问题