Rails 3 - Devise request.referer always has sign_in url - ruby-on-rails-3

I am using devise. I want to redirect to previous page after sign in process is successful. The problem I am having is that the request.referer always has sign_in URL in it. How can I get the URL of the previous page without some explicit hooks.
def after_sign_in_path_for(resource)
stored_location_for(resource) || request.referer || search_index_path
end

I am not on my dev machine so can't verify it. But it should be.
#application controller
def store_return_to
session[:return_to] = request.uri
end
def redirect_back_or_default
redirect_to(session[:return_to] || root_url)
session[:return_to] = nil
end
#home_controller | or any other controller we want to use it.
before_filter :store_return_to
# Session/login_controlelr
Call this function after successful sign_in or sign_up
redirect_back_or_default
A bit off the track(devise) but will be helpful.

inside action controller put
before_action :store_return_to, unless: :devise_controller?
def store_return_to
store_location_for(resource, request.url)
end
Where resource is your devise model, :user per example

Related

Ruby on Rails : Redirect path after sign_up devise

I am using gem devise. And I overrided devise registrations controller and everything went great, but the problem is redirect path after it is saved. What I want to do is after user saved, it redirects to profile_path, but what I have now is user need to sign in before it redirect to profile path. How can I solve that?
Here is my register controller:
class RegistrationsController < Devise::RegistrationsController
def new
super
end
def create
#user= User.new(params[:user])
if #user.save
redirect_to profile_path, notice: 'User was successfully created.'
else
render action: "new"
end
end
def update
super
end
end
And this is my application controller which control the path after sign up and sign in:
class ApplicationController < ActionController::Base
protect_from_forgery
def after_sign_in_path_for(resource)
if request.path !~ /^\/admins\//i
resource.sign_in_count <= 1 ? '/profile' : root_path
end
end
end
Before I override the register controller, redirect after sign up went great. Would be really glad if anyone could help. Thanks.
You have to sign the user in in your create method:
if #user.save
sign_in(resource_name, resource)
current_user = #user # !! now logged in
redirect_to profile_path, notice: 'User was successfully created.'
else
You can look at the original create method in Devise::RegistrationsController to see how this works.

Rails use not condition with before_filter

I'm using before_filter in my application. I have a method logged_in? which returns true if the user is logged in.
def logged_in?
!!current_user
end
def current_user
#current_user = (User.find(session[:user_id]) if session[:user_id]) || false
end
Now in my users controller I want an action to execute only if a user is not logged in. For this I want to use the not condition with logged_in? method in before_filter as:
before_filter :!(logged_in?)
But this gives me an error. I'm resisting creating a new method for not logged in.
Please help me figure out the correct syntax to accomplish this.
While the accepted answer seems to work, I would have done it differently.
before_filter :login_required, unless: :logged_in?
def login_required
redirect_to login_path, notice: 'Please login'
end
This will execute the method login_required unless the user is already logged in. See http://robots.thoughtbot.com/post/159805303/before-filter-wisdom for more info.
You could pass a block to before_filter:
before_filter { |c| !c.logged_in? }
But this wouldn't really do anything, since the return value from the before filter isn't going anywhere. If you want to execute an action if a user is not logged in, then you should be putting that action into the before_filter.
For example, if the action was to redirect to the login page, path, you could do this:
before_filter { |c| redirect_to login_path unless c.logged_in? }
That's actually long enough to justify a method of its own:
before_filter :login_required
def login_required
redirect_to login_path unless logged_in?
end
application_controller.rb
before_filter :authorize
def current_user
#current_user ||= User.find_by(id: session[:user_id])
end
helper_method :current_user
protected
def authorize
unless User.find_by(id: session[:user_id])
redirect_to login_url, :notice => "Not Authorize Member"
end
end

Devise + Facebook Omniauth Error on redirect

I am using devise, omniauth & facebook-omniauth for my Rails 3.1 app. After authentication I wanted to redirect the user to the page was viewing. I have used the following code for the same:
def facebook
#user = Spree::User.find_for_facebook_oauth(request.env["omniauth.auth"], current_user)
if #user.persisted?
flash[:notice] = "Yipee! You were successfully authorized from your Facebook account!!"
sign_in #user, :event => :authentication
redirect_to request.referrer
end
This gives me the following error only at the time of user creation:
ActionController::ActionControllerError in Spree::OmniauthCallbacksController#facebook
Cannot redirect to nil!
The following times when the user has already been created, no errors are shown during & after log in.
How do you suggest I fix this? Thanks!
you can overwrite the functions for sign in/ sign up path in your application controller:
def after_sign_up_path_for(resource)
credit_path
return request.env['omniauth.origin'] || session[:return_to]
end
def after_sign_in_path_for(resource)
return request.env['omniauth.origin'] || session[:return_to]
end
use sessions to store the current path in the path that you want them to go to: session[:return_to] = request.url #store current location
or you create a method that will always be called once they go to a path and store that location. watch out for a giant loop redirection when you do that though.

devise+omniauth devise helper like current_user,user_signed_in? not working

I am using devise and create login with Facebook using omniauth, but having problem of lost the devise helper methods access like current_user and user_signed_in? methods are not working.
EDIT
AuthenticationController
def create
omniauth = request.env["omniauth.auth"]
user = User.find_by_provider_and_uid(omniauth["provider"], omniauth["uid"]) || User.create_with_omniauth(omniauth)
session[:user_id] = user.id
redirect_to dashboard_path(user.id), :notice => "Signed in!"
end
redirect_to USercontroller dashboard method
UserController
before_filter :logged_in
def dashboard
#user = User.find(params[:id])
#comment = Comment.new
#comments = #user.comments.all.paginate(:page => params[:page], :per_page => 5)
end
so here control should go to dashboard method after checking logged_in method in ApplicationController
logged_in method in ApplicationController
Application Controller
def logged_in
if user_signed_in?
return true
else
redirect_to root_path
flash[:message] = "please login"
end
end
when I logged in using facebook following code generated at console
Started GET "/users/52/dashboard" for 127.0.0.1 at Thu Mar 29 12:51:55 +0530 2012
Processing by UsersController#dashboard as HTML
Parameters: {"id"=>"52"}
Redirected to http://localhost:3000/
Filter chain halted as :logged_in rendered or redirected
Completed 302 Found in 2ms (ActiveRecord: 0.0ms)
in the above code control is render from logged_in method to root_path but it shold render dashboard_path
So I am guessing User_signed_in? helper is not working I also use current_user in stead of that generate same error
As I see, user_signed_in? is working, but returns false, as for Devise user is not logged in. To fix this, just replace the session id storing with Devise sign_in method in your controller action:
def create
omniauth = request.env["omniauth.auth"]
user = User.find_by_provider_and_uid(omniauth["provider"], omniauth["uid"]) || User.create_with_omniauth(omniauth)
sign_in(:user, user)
# actually if you really really need that id in the session, you can leave this line too :)
session[:user_id] = user.id
redirect_to dashboard_path(user.id), :notice => "Signed in!"
end
After creating the user account via Facebook, how do you sign in the user?
You should still be using devise helpers like sign_in_and_redirect. Something like:
user = User.build_from_omniauth(omniauth)
if user.save
sign_in_and_redirect(:user, user)
end
Then you should be able to use helpers like current_user and user_signed_in? (which just check if current_user is not nil).
Taking a look at your edit, my answer is still valid. What you need to do is use sign_in_and_redirect(:user, user) instead of just setting the id in the session.
You can easily customize where the user is redirected after sign in with devise.
Another thing, remove this logged_in filter, Devise has a authenticate_user! method that you can use as a before_filter. It will redirect the user to the sign in page, and when they login, it will redirect them to the page they were trying to access.
You're using Devise, so try to take advantage of that, and go read the doc ;)

Couldn't find User with id=1

I've a current_user method to handle authentication.
application_controller.rb
protect_from_forgery
helper_method :current_user
def current_user
#current_user ||= User.find(session[:user_id]) if session[:user_id]
end
but when I try to acces a to a page I get the following error:
Couldn't find User with id=1
app/controllers/application_controller.rb:10:in `current_user'
How can I pass #current_user a sort of default value so if there's no user it will redirect to login page.
Thanks for helping.
It looks like your session contains old data, specifically an id (1) of a user which no longer exists. Try handling the RecordNotFound exception raised by ActiveRecord, and returning nil:
def current_user
#current_user ||= User.find(session[:user_id]) if session[:user_id]
rescue ActiveRecord::RecordNotFound
end
To redirect, you should add a second before_filter which checks for a user and handles redirecting to the login path:
before_filter :require_user
def require_user
redirect_to login_path unless current_user
end
Remember to omit require_user for your login action by adding skip_before_filter :require_login to whichever controller manages your authentication.