Rails redirections with new users and logins - ruby-on-rails

So I'm trying to get the user to return to the page they were looking at before they click "log in"
This is what I got in my user application controller:
def redirect_back_or_default(default)
redirect_to(session[:return_to] || default)
session[:return_to] = nil
end
And this is what I have in my sessions controller:
def new
#user_session = UserSession.new
session[:return_to] = request.referer
end
end
def create
#user_session = UserSession.new(params[:user_session])
if #user_session.save
flash[:notice] = "Login successful!"
redirect_back_or_default(home_path)
else
render :action => :new
end
end
This works fine most of the time but if a user logs in right after they register to the site, they will get redirected to a blank page. I imagine this is the "create" action because it was the last action before going to user sessions new.
So I tried this:
def new
#user_session = UserSession.new
unless request.referer == join_path
session[:return_to] = request.referer
end
end
And this tries to take me back to the login page after I log in.
What I'd really like to do is have the user see their profile when they log in for the very first time.
This wouldn't give me a user id and raised a routing error
def create
#user_session = UserSession.new(params[:user_session])
if #user_session.save
flash[:notice] = "Login successful!"
redirect_back_or_default(user_path(current_user))
else
render :action => :new
end
end
Anybody gone through these redirecting acrobatics before? I can't seem to get it to work. I'm using authlogic if that helps.

Found a great solution at: http://ethilien.net/archives/better-redirects-in-rails/

Related

How to I redirect back to my topics/show page?

Hey all so in my code I am just redirecting back to the index of all the topics and theoretically I would like to redirect back to the page.
this is my controller for this page, right now I am just using topics_path as a stand in.
class LikesController < ApplicationController
def index
end
def create
#bookmark = Bookmark.find(params[:bookmark_id])
like = current_user.likes.build(bookmark: #bookmark)
if like.save
flash[:notice] = "Successfully liked bookmark."
else
flash.now[:alert] = 'Error in liking bookmark. Please try again.'
end
redirect_to topics_path
end
def destroy
#bookmark = Bookmark.find(params[:bookmark_id])
like = current_user.likes.find(params[:id])
# Get the bookmark from the params
# Find the current user's like with the ID in the params
if like.destroy
flash[:notice] = "Successfully unliked bookmark."
else
flash.now[:alert] = 'Error in unliking bookmark. Please try again.'
end
redirect_to topics_path
end
end
this is the line from rake routes that I was to redirect_to
bookmarks_show GET /bookmarks/show(.:format) bookmarks#show
If you wish to redirect back to a specific topic's page... then you'll need to pass the topic_id through as a param so you can use it in the redirection.
Add it into the form/link you're using eg:
(note: totally making this up, obviously your code will be different)
<% form_for #like do |f| %>
<%= f.hidden_field :topic_id, #topic.id %>
Then in your create action, you just redirect using that eg:
def create
#bookmark = Bookmark.find(params[:bookmark_id])
like = current_user.likes.build(bookmark: #bookmark)
if like.save
flash[:notice] = "Successfully liked bookmark."
else
flash.now[:alert] = 'Error in liking bookmark. Please try again.'
end
redirect_to topic_path(:id => params[:topic_id])
end
Note: if you want to use some other page (eg the bookmark page) then use that instead... this is a "general howto" not a "use this code exactly as you see it here" :)

redirecting logged in users to index if they try to access /login

So I'm after a simple solution which I can't seem to work out. New to rails, so trying to learn and get the basics down.
When users aren't logged in and they try and access various pages, they are redirected to /login. What I want is to stop them form being able to view the /signin page IF they are already logged in.
How can I achieve this?
Update
application_controller
def current_user
#current_user ||= User.find_by_auth_token!(cookies[:auth_token]) if cookies[:auth_token]
end
sessions_controller
class SessionsController < ApplicationController
layout "empty"
def create
user = User.find_by_user_name(params[:user_name])
if user && user.authenticate(params[:password])
if params[:remember_me]
cookies.permanent[:auth_token] = user.auth_token
else
cookies[:auth_token] = user.auth_token
end
flash[:success] = "You are now logged in"
redirect_to '/'
else
flash[:error] = "Invalid username or password"
redirect_to '/login'
end
end
def destroy
cookies.delete(:auth_token)
flash[:error] = "You have successfully logged out"
redirect_to '/login'
end
private
end
Add before_action for the action /login view, if you have current_user than you can do it like this
before_action :check_session, only: [:login]
def login
# login page action
end
private
def check_session
redirect_to root_path unless current_user.blank?
end
Hope that helps!

using redirect and if multiple times

My question is actually fairly simple, how do I make a create action which checks if a user is logged in, and if she/he is then redirect to the dashboard instead of rendering the index page where they've got links and stuff to go to and sign up. Also why is the code below not working.
class UsersController < ApplicationController
def new
#user = User.new
end
def create
if current_user.nil?
redirect_to dplace_index_path
if current_user
#user = User.new(params[:user])
if #user.save
auto_login(#user)
redirect_to dplace_index_path
end
end
end
end
end
Your code isn't doing what you expect because the if statements are actually nested (you want elsif with this same structure -- or see my suggested fix below). Here's what your code, when properly formatted, actually looks like:
def create
if current_user.nil?
redirect_to dplace_index_path
if current_user
#user = User.new(params[:user])
if #user.save
auto_login(#user)
redirect_to dplace_index_path
end
end
end
end
Logically, you will never get down into the second if statement, because current_user must be nil to enter the first. Try something like this instead:
def create
if current_user
#user = User.new(params[:user])
if #user.save
auto_login(#user)
redirect_to dplace_index_path
end
else
redirect_to dplace_index_path
end
end
I rearranged the code, but it should logically do what you want now. I put the "happy path" first (the current_user exists), and moved the redirect into the else statement.
General user authentication:
def create
user = User.find_by_email(params[:email])
if user && user.authenticate(params[:password])
session[:user_id] = user.id
redirect_to dashboard_url, :notice => "Logged in!"
else
flash.now.alert = "Invalid email or password"
render "new"
end
end
Try:
def create
if current_user.blank? # .blank? will check both blank and nil
# logic when user is not logged in
redirect_to index_path
else
# logic when user is logged in
redirect_to dashboard_path
end
end
def create
redirect_to dplace_index_path unless current_user
# no need to check current_user again
#user = User.new(params[:user])
if #user.save
auto_login(#user)
redirect_to dplace_index_path
end
end

Template not found on Rails when I just redirect

I'm making a Rails app where I have a method:
def updateAttributes_post
if logged_in?
userPlucky = User.where(:screen_name=>session[:screen_name]).all
userPlucky.each do | user |
user.update_attributes(:email => params[:emailAddr], :password=>params[:passwordStr])
if user.save
flash[:success] = "Succesfully updated attributes!"
redirect_to '/dashboard'
else
errors = Array.new()
for i in 0..user.errors.full_messages.count
errors.push(user.errors.full_messages[i])
end
session[:error] = errors
flash[:error] = "Error saving"
redirect_to '/update'
end
end
else
redirect_to root_path
end
end
which is called on a POST request. The thing is on every if I'm redirecting on both cases, but I'm still getting a Template not found`. If I add a template with the name it asks it just renders the blank template without doing nothing. What I'm doing wrong?
If no user matches (ie userPlucky is empty), you do not call any redirect_to.

Authentication Problem - not recognizing 'else' - Ruby on rails

I can't seem to figure out what I am doing wrong here. I have implemented the Super Simple Authentication from Ryan Bates tutorial and while the login portion is functioning correctly, I can't get an error message and redirect to happen correctly for a bad login.
Ryan Bates admits in his comments he left this out but can't seem to implement his recommendation. Basically what is happening is that when someone logs in correctly it works. When a bad password is entered it does the same redirect and flashes 'successfully logged in' thought they are not. The admin links do not show (which is correct and are the links protected by the <% if admin? %>) but I need it to say 'failed login' and redirect to login path. Here is my code:
SessionsController
class SessionsController < ApplicationController
def create
if
session[:password] = params[:password]
flash[:notice] = 'Successfully logged in'
redirect_to posts_path
else
flash[:notice] = "whoops"
redirect_to login_path
end
end
def destroy
reset_session
flash[:notice] = 'Successfully logged out'
redirect_to posts_path
end
end
ApplicationController
class ApplicationController < ActionController::Base
helper_method :admin?
protected
def authorize
unless admin?
flash[:error] = "unauthorized request"
redirect_to posts_path
false
end
end
def admin?
session[:password] == "123456"
end
helper :all # include all helpers, all the time
protect_from_forgery # See ActionController::RequestForgeryProtection for details
#
end
You need to use Ruby's comparison operator == rather than the assignment operator =. Your create action should be:
def create
if session[:password] == params[:password]
flash[:notice] = 'Successfully logged in'
redirect_to posts_path
else
flash[:notice] = "whoops"
redirect_to login_path
end
end
Edit: The problem is that nowhere in your SessionsController are you actually checking the entered password against the correct password. Change your create method to this:
def create
if params[:password] == '123456'
session[:password] = params[:password]
flash[:notice] = 'Successfully logged in'
redirect_to posts_path
else
flash[:notice] = "whoops"
redirect_to login_path
end
end
It's not ideal having the password hard-coded like this and storing it in the session for use by the admin? helper method, but this is supposed to be super simple authentication.
if #YOU MISSING SOMETHING HERE WHICH Returns TRUE IF USER IS VALID
session[:password] = session[:password]
flash[:notice] = 'Successfully logged in'
redirect_to posts_path
else
flash[:notice] = "invalid login" #CHange if messaage for invalid login
redirect_to login_path
end
it must be
if session[:password] == params[:password]
You never have a fail condition due to:
if session[:password] = session[:password]
This will always be true. You probably want something like:
if session[:password] == 'canihazpasswrd' then
do_something_here
Edit: Refer #john's answer. :)
Try this:
def create
if session[:password] == '123456'
flash[:notice] = 'Succesfully logged in'
redirect_to home_path
else
flash[:notice] = "Incorrect Password!"
redirect_to login_path
end
end
The thing is that the tutorial you used does no user's authentication. It only checks if the login belongs to an admin, so some content will be showed.
This way you'll never have wrong login/password, just admin/non-admin.

Resources