devise: adding notice after sign up (with confirmable) - ruby-on-rails

I added :confirmable to my Rails app subsequently. The problem is that when I sign up after adding :confirmable I don't get a notice displayed after the sign up for with telling me what happened, for instance:
You will receive an email with instructions about how to confirm your account in a few minutes.
Why doesn't notice appear and how can I add that notice after adding :confirmable?
Thanks for help

Notice does not appear because the devise is redirecting to your root path which is probably protected by devise authentication. When you hit root_path, you get redirected back to sign_in page (because devise couldnt sign-in the user since it is not activated yet). You can verify that by looking on your development log after you enter user information and hit "sign-up" button - you will see in the log one request for registering a user, then a request navigating to your root url (whatever is in your routes.rb) and then redirect navigation to sign_in page because of authentication.
During redirect all flash messages are lost (since flash messages are only valid for next request only) and when you get redirected from root_path to sign_in page, you are making to requests. So you either need to use flash.keep on the first request before it gets redirected, or change the after_sign_up path so redirection does not happen. I recommend changing after_sign_up path since it's easier and looks as a right way to go about it.
To do that, you need to use your own controller for registrations and add after_sign_up_path method that returns url for redirect:
# app/controllers/registrations_controller.rb
class RegistrationsController < Devise::RegistrationsController
private
def after_inactive_sign_up_path_for(resource)
new_user_session_path
end
end
#config/routes.rb
devise_for :users, :controllers => { :registrations => "registrations" }
I also recommend reading similar question to yours: Rails 3 and Devise: Redirecting to page following signup (confirmable)

Related

Which controller and action are being accessed with Rails, Devise, and Omniauth

I'm using Devise and Omniauth in my Rails 4 application. In my view I have a button to "Login With Facebook" that directs the user to user_omniauth_authorize_path(:facebook). This works as expected and sends the user to /users/auth/facebook. Then, that URL appears to be correctly redirecting the user to the Facebook login page.
How can I determine which controller/action are being used for this redirect? I would like to set a return_url before redirecting to Facebook. I was able to do this in my regular Session and Registration controllers by subclassing the Devise version and adding my code, like this:
class Users::SessionsController < Devise::SessionsController
def new
return_url = params[:return_url]
store_location_for(:user, return_url) unless return_url.nil?
super
end
end
Then, I tell devise to use my new controllers:
devise_for :users, controllers: { sessions: 'users/sessions' }
I'm trying to accomplish the same sort of thing with the omniauth functionality? Is there some way to find out which controller is being accessed when the user visits /users/auth/facebook? If so, can I subclass it and add functionality in the same way I did above?
UPDATE
I found the controller/action by running 'rake routes'. Here's what it says:
user_omniauth_authorize GET|POST /users/auth/:provider(.:format) users/omniauth_callbacks#passthru {:provider=>/facebook/}
So I was able to find the passthru method that is being used, but that has left me even more confused. It's in Devise::OmniauthCallbacksController and says:
def passthru
render status: 404, text: "Not found. Authentication passthru."
end
I'm confused how this method is resulting in the user being redirected to Facebook.
It looks like you can pass parameters to the user_omniauth_authorize_path, and then retrieve them in the callback URL using request.env["omniauth.params"]. So, I changed my link to: user_omniauth_authorize_path(:facebook, { return_url: '/test_redirect_path' }
Then in my OmniauthCallbacksController I added:
store_location_for(:user, request.env["omniauth.params"]["return_url"])
before the call to sign_in_and_redirect #user.
This seems to have done the trick.

Get target path before authentication

I'm using Devise for user authentication in a rails application, and so certain routes are wrapped in a authenticate tag to allow access only to users who are logged in.
authenticate :user do
post '/user/orders/new', to: 'user/orders#new', as: :new_user_order
end
For example, when a user tries to create a new order when they're not logged in, they're redirected to a sign in page.
What I want is for the user to be directed to the new order page after logging in.
Currently, we're using request.referrer which redirects the user back to the page they were on before trying to create a new order. I can't seem to figure out a way of getting the path they were targeting before being sent to sign in.
Anybody know how I could do this?
Thanks
You need to provide a before filter for user authentication in the controller and not mention it in routes . Just put the following code in the controller and it should redirect to sign-up if the user isn't logged in -
before_filter :authenticate_user
You need to override Devise's after_sign_in_path_for(resource_or_scope) method, you can do it in application controller
def after_sign_in_path_for(resource_or_scope)
# new_order_path
end
Hope that helped!
You can persist the last url - in session[:bookmark] and by doing something like this -
prepend_before_filter :set_bookmark
def set_bookmark
session[:bookmark] = request.url
end
And within SessionsController, you can use value of session[:bookmark] if it exists or after_sign_in_path_for

How to pass through parameters during Devise login

How do I pass parameters during the Devise sign-in process?
I have a collection of users, each with their own profile page. I want them to be able to view their own profile page but none of the other users' profile pages, unless they're an admin in which case they have access to everything in the application.
I created a Users controller, and applied the following code to the beginning of the controller. I replaced looking up by ID with their username, so /users/username to access a profile:
filter_access_to :all do
current_user == User.find_by_username(params[:id]) or
has_role? :admin
end
And I specified in routes.rb:
root :to => "users#show"
When the user accessed http://appli.cat.ion they would be prompted for login credentials, then be redirected to the root_path which is the show action of the Users controller. Unless I can pass along the id param during the sign-in process, this will result in an endless redirect loop. Is there something in Devise that helps with this problem?
I believe the following two Devise methods can help:
after_sign_in_path_for(resource)
and
stored_location_for(resource)
I've overriden after_sign_in_path to the following:
def after_sign_in_path_for(resource)
user_root_path(:id => current_user.username)
end
which provides the desired effect: user logs in, gets redirected to their profile page, but only if I return nil in stored_location_for like:
def stored_location_for(resource)
nil
end
Again, my goal is to redirect a user to their profile page if having navigated to (http)://appli.cat.ion/ directly if they've signed-in. If a user navigates to (http)://appli.cat.tion/otherresources then I want to sign the user in, then redirect them to the page they requested. If I return nil in stored_location_for then the user will ALWAYS get redirected to their profile page no matter what, which is undesirable at best, and unusable at worst. I think that if I navigate to the application sign-in directly then stored_location would return nil, and upon signing in be directed to my profile page, but it is just redirecting me to the root_path.
I think you can create a profile action within the UsersController which does a redirect to the user show page, then mark it as user root.
In UsersController:
class UsersController < ApplicationController
...
def profile
redirect_to user_url(:id => current_user.username)
end
...
end
In routes:
resources :users do
get 'profile', :on => :collection, :as => :user_root
end
And don't need to use the after_sign_in_path hook.

Rails 3 and Devise: Redirecting to page following signup (confirmable)

I have a Rails 3 project with Devise, confirmable enabled so the user has to confirm their account through email after registration. Currently the project returns the user to the login page and throws a "You've signed up successfully..." notice. What I want to do instead is redirect them to a "thank you" page, with further instructions (check your email, spam folder, blah blah).
My first stop was the Devise wiki, where I found this page. Looked easy enough, I made the following alterations and followed the directions exactly...
/app/controllers/registrations_controller.rb
class RegistrationsController < Devise::RegistrationsController
protected
def after_sign_up_path_for(resource)
"http://google.com"
end
end
/config/routes.rb
devise_for :users, :controllers => { :registrations => "registrations" }
The one modification I had to make over the direction was moving the "registrations" folder out of the /app/views/devise view folder and into the top /app/views folder, as an error returned that the views were now missing. Anyway, despite the controller override appearing to work (I don't think the views would have originally broken otherwise), those directions do NOT work...the page ignores the after_sign_up and returns to the login page after signing up.
Went hunting on the internet including other Stack Overflow threads, but nothing I found has worked for me...either answers confuse redirecting sign up for sign IN, or what they're actually doing is changing the redirect after sign in (as Devise normally automatically signs in after registration without confirmable enabled).
Other things I have tried...
Moving the after_sign_up_path_for(resource) into the application controller. Doesn't work. Oddly enough, doing the same with after_sign_in_path_for(resource) and signing in as a user DOES redirect.
Moving the registrations_controller.rb from /app/controllers/ into /app/controllers/users folder and updating all routes/references/etc accordingly. No go.
Copying Devise's registrations_controller.rb into my own registrations_controller.rb. Didn't work, just threw up an error and I rolled it all back.
I tried def after_inactive_sign_up_path_for(resource), as I thought maybe the fact that the account wasn't active yet was the culprit. This is also ignored.
It's also worth mentioning I have tried restarting my project after these major changes, but nothing takes.
Has anyone had any success with pulling this off with confirmable enabled?
I'm just putting #Shannon's comment into an answer to make it easier to find.
If you are requiring email confirmation after sign-up, your user will be left in an in-between state where they have signed up but not clicked the link emailed to them to confirm their account. This is an inactive sign up. To redirect in this situation you need to specify:
def after_inactive_sign_up_path_for(resource)
"http://example.com"
end
Which version of devise are you using? I'm pretty sure that this issue was recently resolved so you probably need the latest version from the repo which is still a release candidate (although it should be out soon as they were waiting for omniauth 0.2 to get out of beta which recently happened).
I am using Devise 1.2.rc2 from the github repo with rails 3.0.5. I added the code that you mentioned to my custom RegistrationsController and was forwarded to google as expected after creating a new account.
A cutdown version of my RegistrationsController (in app/controllers/users)
class Users::RegistrationsController < Devise::RegistrationsController
protected
def after_sign_up_path_for(resource)
"http://google.com"
end
end
My routes.rb entry
devise_for :users, :controllers => { :registrations => "users/registrations" }
From my Gemfile
gem 'devise', :git => "git://github.com/plataformatec/devise.git"
Let me know if you're having problems on the latest version of devise.
Another way would be to do this in application controller
def after_sign_in_path_for(resource)
resource.sign_in_count <= 1 ? '/edit_profile' : root_path
end

How to redirect a user after registration when using Devise?

I am using Rails 2.3 and Devise to handle user registration / authentication.
I need to redirect a user to an external 3rd party website immediately after a user signs up for an account. Been looking in the code & online but cannot see how to do this.
How can I alter the devise flow to redirect the user?
The answer listed as the "correct" answer specifically refers to after sign_in... If you want to do redirect a user after sign_up you need to override the following:
def after_sign_up_path_for(resource)
"http://www.google.com" # <- Path you want to redirect the user to after signup
end
Full details can be found on the wiki.
Add to your Application Controller
# Devise: Where to redirect users once they have logged in
def after_sign_up_path_for(resource)
"http://www.google.com" # <- Path you want to redirect the user to.
end
Here is the list of Devise helpers you can use http://rdoc.info/github/plataformatec/devise/master/Devise/Controllers/Helpers
I hope that helps =)
If you are using Devise's confirmations (meaning the user is not activated immediately after they sign up), you need to overwrite the after_inactive_sign_up_path_for method.
# controllers/registrations_controller.rb
class RegistrationsController < Devise::RegistrationsController
def after_inactive_sign_up_path_for(resource)
"http://somewhere.com"
end
end
Make sure to tell devise to use your RegistrationsController.
# config/routes.rb
devise_for :users, :controllers => {:registrations => 'registrations'}

Resources