Overriding Devise's registration controller to

2019-03-10 04:45发布

问题:

I have looked all over the place, and found a lot of info... but nothing works for me and I don't get it :(

I know that you are suppose to override the registration controller, like this:

class Users::RegistrationsController < Devise::RegistrationsController

def after_sign_up_path_for(resource)
  authors_waiting_path
end 

end

Then following the example showed by Tony Amoyal http://www.tonyamoyal.com/2010/07/28/rails-authentication-with-devise-and-cancan-customizing-devise-controllers/, I am supposed to change my routes to update the access the new controller:

devise_for :users, :controllers => { :registrations => "users/registrations" } do
#get '/author/sign_up', :to => 'devise/registrations#new'
#get '/client/sign_up', :to => 'devise/registrations#new'  
get '/author/sign_up', :to => 'users/registrations#new'
get '/client/sign_up', :to => 'users/registrations#new'      
end

Yes, I have something a bit strange here, because I am catching some specific path to send them to the registration page, this allows me to create effectively 2 registration scenario. I commented what I had before I had overridden the registration controller.

Even with all this and my authors_waiting_path being a valid path, it just keeps on going to the sign-in page after registration :(

This is really frustrating.

Alex

edit: I also found this on the devise wiki: https://github.com/plataformatec/devise/wiki/How-To:-Redirect-after-registration-(sign-up)

But I have no idea where to define this create method ? should I override the session controller ???

edit 2:

I put a dummy override of the controller:

  class Pouets::RegistrationsController < Devise::RegistrationsController

    def after_sign_up_path_for(resource)
      authors_waiting_path
    end 

    def new
      super
    end

    def create
      puts "was here"
      super
    end

    def edit
      super
    end

    def update
      super
    end

    def destroy
      super
    end

    def cancel
      super
    end

  end

And I never the "was here" in my logs.... I really have the feeling that it's totally ignoring the override... I must be doing something wrong :(

回答1:

Ok... I am able to override it so you should be either :0

Create folder app/controllers/users

put there registrations_controller.rb with: (option with session - but it will try sign_in and later redirect - it may be not intended behavior for you ). Furthermore this is from devise wiki and I am not sure if it works

class Users::RegistrationsController < Devise::RegistrationsController

  def create
    session["#{resource_name}_return_to"] = complete_path
    super
  end

end

restart application (just for ensure you don't trust anything)


All in all you must override Create If you want redirect only Users... if you want define some more complex scenario you should monkeypatch sign_in_and_redirect

so your controller will looks like

class Users::RegistrationsController < Devise::RegistrationsController
  # POST /resource/sign_up
  def create
    build_resource

    if resource.save
      set_flash_message :notice, :signed_up

      #sign_in_and_redirect(resource_name, resource)\
      #this commented line is responsible for sign in and redirection
      #change to something you want..
    else
      clean_up_passwords(resource)
      render_with_scope :new
    end
  end
end

second option try to monkeypatch helper ....

module Devise
  module Controllers
    # Those helpers are convenience methods added to ApplicationController.
    module Helpers
      def sign_in_and_redirect(resource_or_scope, resource=nil, skip=false)
        #intended behaviour for signups
      end
    end
  end
end


回答2:

I have tried the above solution and while it works, reading devise code, I have found that all you actually need in order to sign-out just registered user and redirect is:

  1. to add is_approved or similar to your user table and
  2. to add active_for_authentication? method in your User model

Code:

class User < ActiveRecord::Base

  # ... some code

  def active_for_authentication?
    super && is_approved
  end
end

Was a bit hard to find when I needed it, but that is all. I am actually writing it here in case someone else needs it.