Passing additional params to Devise new_user_session_path - ruby-on-rails

I am trying to implement Devise and Ominauth for multiple providers. One scenario is: user sign in with Twitter for the first time without creating an account first.
To handle this, I redirect user from callback link (/auth/twitter/callback) to sign up page to fill in email address.
However, I want to bring authentication information from the callback link {:provider => "twitter", :uid =>"123"} to sign up page (new_registration_path). Then when user submit sign up form, the authentication will be captured together with account information.
How should I go about doing this? I've tried
redirect_to(new_user_session_path, {:service => service})
where service = {:provider => "twitter", :uid =>"123"}
but service doesn't get passed through as a params.
What did I do wrong? Do I need to modify source code for Devise?
Thank you.

You're probabbly looking for this:
redirect_to(new_user_session_path(:argument => "value"))
And in controller after redirect (probably UserSessions#new) you can access argument with:
params[:argument]
You need to pass arguments to path helper not to redirect_to method.
In your example it should be:
redirect_to(new_user_session_path(service))
And in controller after redirect (probably UserSessions#new) you can access argument with:
params[:provider]
params[:uid]
or
redirect_to(new_user_session_path(:service => service))
and
params[:service][:provider]
params[:service][:uid]

Related

Rails devise registration two ways after sign_up

I want devise to redirect to specific controller index action( or specific page) after user is sign_up.
In detail, i have an app with 2 ways to sign-up : for the client and for the Professor . Actually, the 2 type use the same registration page, it works very nice but when they sign_up they are automatically redirect to the same page ...
So, i want to change the way like this :
- when user click on I want to become Professor i want to register (full name, mail, password) and redirect after sign_up to the Professor dashboard
- and when user click on Client i want to register with the "same way" BUT in the end, i want to redirect to the client's dashboard.
So, i started to change devise.rb to change this
config.allow_unconfirmed_access_for = 2.days (automatically login after sign_up)
And in my RegistrationsController, i override the after_sign_up_path_for to have something like
def after_sign_up_path_for(resource)
if 'user is Prof'
redirect_path_professor
else
redirect_path_client
end
end
but how can i check (in condition) if user click on Prof. or Client ?. Its the same resource (registration) ^^
Thanks
Why not using only one link, then let the user selects his role in the registration view?
If you really want two links for the same view, you should pass the role in a param (something link link_to 'Becoming a Professor', new_registration_path(role: 'professor'), then add an hidden_field in your registration form with the value of the param.
= f.input :role, as: :hidden, input_html: { value: params[:role] }
But don't forget to validate the content of the params to avoid the bad values sent by teasing users
Also, after_sign_in_path_for(resource) should be in application_controller. You'll need a column in users to specify the role, and your method will looks like something like this:
def after_sign_in_path_for(resource)
stored_location_for(resource) || (resource.role.professor? ? professor_dashboard_url : user_dashboard_url(resource))
end

Accessing Params in Rails 3.2

I am working through the RailsApps Stripe tutorial.
When a new subscriber is created through a devise registration controller they are then directed to their content page through a content controller. I want to use their name and email address created upon registration on their content page. But I can't seem to bring the params into the content controller.
I put#user = User.find(params[:id]) into the content_controller but I get the error "Couldn't find User without an ID".
On the error page it lists under Request Info > rack session: "warden.user.user.key"=>["User", [2],
So does that mean that ID of User #2 is being passed to the content_controller but that I can't access it?
I put#user = User.find(params[:id]) into the content_controller but I
get the error "Couldn't find User without an ID".
This error means that params[:id] = nil, i.e., you are not passing id in the params hash when redirecting the user to content page.
Possible Solutions:
With Devise you get a helper method called current_user which returns an instance of currently logged in user. So, you could directly use current_user to access the attributes of currently logged in user. For example:
To access name and email fields of currently logged in user, all you need to do is
current_user.name
current_user.email
In routes.rb, pass the id of the currently logged in user via the route of content page as below:
## Add :id dynamic segment to your content page route
get "content/:id", :to => "contents#action_name", :as => "content_page"
Since, I don't have the route details, you would need to modify the above route as per your requirement.
Next, when redirecting the user to content page after sign up just pass the currently logged in user as below in ApplicationController method named after_sign_up_path_for (You need to override this Devise method if you want to redirect the user to a different route than the default root path):
def after_sign_up_path_for(resource)
content_page_path(resource) ## Provide the path and pass resource to it
end
With Devise, you can access the currently logged in user via the current_user helper in your controller.
See documentation: https://github.com/plataformatec/devise#controller-filters-and-helpers

Implementing Single Sign On for Disqus in Rails

So I am currently using Disqus for my commenting system on my website It works perfectly but the downfall is that users need to have two accounts. One to access the site and another to comment!
Disqus offers SSO for this exact reason to allow a user to sign up only once (on the site) and automatically be given an 'in-app' disqus account to comment.
The people at Disqus have activated SSO for me and have linked me to various documentation. I was wondering if there are any good tutorials/documentation to show you how to do this with rails?
disqus_rails gem - Disqus service RoR wrapper
acts_as_disquser and Single Sign On
Disqus provides SSO service which gives ability to link your local users info to Disqus users, read more in Disqus tutorial. To do this, as and for linking model to Disqus thread - you have to add 'acts_as_disquser' line in your users model. You need pass there four attributes: 'id', 'username', 'email' and 'avatar'(avatar is an optional field, so you can omit this). Here is example:
class User < ActiveRecord::Base
acts_as_disquser :username => :full_name, :email => :email, :avatar => Proc.new{ avatar.url }
...
end
As you see, you can pass there or symbols, or procs. First will try to get instance variable with such name from model's instance, second will evaluate code inside Proc with context of model's instance. Important - only Proc are available for second way of defining attribute, no lambdas. Also, you may not implicitly pass acts_as_disquser :id => :id - it will try to get id automatically if it is not defined. Next, you need to specify in disqus_init helper attributes 'disquser' with current user instance, and 'sso' as boolean to enable or disable SSO.
<%= disqus_init :disquser => current_user, :sso => true %>
After this is done, when users will post comments via Disqus, their username, email and avatar will be taken from your site.
https://github.com/sandric/disqus_rails

'Cannot redirect to nil' error after adding a field to devise registration view

After adding this line to the devise/registrations/new.html.haml file (view):
%div
= f.label :account_type
%br/
= f.select(:account_type, [["Usertype1","usertype1"],["Usertype2","usertype2"]], {:selected => nil, :prompt => 'Pick One'})
I get the following error after clicking on the confirmation link in the confirmation e-mail:
ActionController::ActionControllerError in Devise::ConfirmationsController#show
Cannot redirect to nil!
It only happens if I select Usertype2 upon registration. I also made the account_type attr_accessible. The account_type seems to be getting assigned (I checked in the rails console) and the development logs don't have any further information.
I think this is the line in the devise confirmations controller where the error is occurring:
respond_with_navigational(resource){ redirect_to after_confirmation_path_for(resource_name, resource) }
Also, the account is being confirmed, but when trying to log in, I get the following:
undefined method `user_url' for #<Devise::SessionsController:0x9d1659c>
which is in the create action of the devise sessions controller.
Any help would be appreciated. Thanks!
John
The two errors you mentioned are one and the same, essentially when you are signing-in successfully Devise is unable to detect where to redirect you. This problem often occurs when you have multiple models or try to setup a custom redirect (post sign in) in the routes file.
Try to define the path in the ApplicationController.
Devise docs say that the after_sign_in_path_for method takes the actual model object (ie: the model being signed-in)
def after_sign_in_path_for(resource)
signed_in_path_for_user
end
Note: You can do the same for several Devise paths / variables (override them). Also for more information on doing this for multiple Devise models in the same app, you can look at this question and it's answer.

Devise, twitter - ask for confirmation email

I have implemented twitter authentication with devise using something very similar to this: https://github.com/plataformatec/devise/wiki/OmniAuth:-Overview
My question is, since twitter doesn't give you the email of the user, how can you direct the user back to the flow of:
User signs in with twitter
User is presented with an email form
User needs to confirm his/her email
clicking confirmation link sends user to site logged in
Devise pretty much takes care with #3 and #4. How should I structure my code to allow #2 to transit into #3 and #4?
Thanks!
Show new user form in twitter callback page. Store twitter token in hidden field. Then you can create new user in your controller and do what you want with the twitter token. User.create also sends confirmation email.
User.create(:email => params[:email], :password => params[:password], :password_confirmation => params[:password_confirmation])
Ryan Bates covers most of this in his screencast OmniAuth Part 2, to get the email confirmation all you need to do is add the confirmable option to devise.

Resources