I everyone, I've some issue to handling exception in ruby. I doesn't understand why my statement doesn't work.
Error : Couldn't find User with id=14
I want to redirect to the login page.
def login_required
begin
if session[:user_id] == nil
redirect_to login_path, :notice => "You are not logged"
elsif User.find(session[:user_id])
return nil
end
rescue ActiveRecord::RecordNotFound
redirect_to login_path, :notice => "No user corresponding in database"
end
end
Hope you can help me.
Cordially,
Aubin
def login_required
begin
if session[:user_id] == nil
redirect_to login_path, :notice => "You are not logged"
elsif User.find_by_id(session[:user_id]).nil?
#rescue ActiveRecord::RecordNotFound (use if u want to use User.find)
redirect_to login_path, :notice => "No user corresponding in database"
return nil
end
end
end
The only reason for this to not work is that ActiveRecord is actually finding a row
User.find(session[:user_id])
Try logging the session[:user_id] and looking into DB using SQL.
On another note, you can use
session[:user_id].nil?
instead of
session[:user_id] == nil
I would rewrite your method as follows:
def login_required
return redirect_to(login_path,
:notice => "You are not logged") if session[:user_id].blank?
user = User.find_by_id(session[:user_id])
return user if user.present?
redirect_to login_path, :notice => "No user corresponding in database"
end
Related
session[:user_id] = user.id this session not working but its working in get method(login)
# Working fine here
# get 'users/login'=>'users#login'
def login
session[:user_id] = 1
end
# post 'users/auth'=>'users#loginpost'
def loginpost
user = User.authenticate(request.POST['name'], request.POST['password'])
if user
# But not working here:(
session[:user_id] = user.id
redirect_to root_url, :notice => "You are Successfully logged in ^^"
else
render html: '<strong>HTML String</strong>'
#render users_login_url, :notice => "You are entered invalid email or password"
end
end
While trying to follow a tutorial, I raised an error when I test the "Sign out" link. I checked the difference with the tutor, but I couldn't figure out why I can't do it my way and why the error occurs on this spot.
My code:
class SessionsController < ApplicationController
def create
if user = User.authenticate(params[:email], params[:password])
session[:user_id] = user.id
redirect_to(session[:intended_url] || user), notice:"Welcome back, #{user.name}"
session[:intended_url] = nil
else
flash.now[:alert] = "Invalid email/password combination! you are a failure"
render :new
end
end
def destroy
session[:user_id] = nil
redirect_to root_url, notice: "You're now signed out!"
end
end
The correction code:
class SessionsController < ApplicationController
def new
end
def create
if user = User.authenticate(params[:email], params[:password])
session[:user_id] = user.id
flash[:notice] = "Welcome back, #{user.name}!"
redirect_to(session[:intended_url] || user)
session[:intended_url] = nil
else
flash.now[:alert] = "Invalid email/password combination!"
render :new
end
end
def destroy
session[:user_id] = nil
redirect_to root_url, notice: "You're now signed out!"
end
end
The error that was raised:
SyntaxError in SessionsController#destroy
C:/Users/xcpro/ve2/2B3/app/controllers/sessions_controller.rb:6:
syntax error, unexpected ',', expecting keyword_end
...ession[:intended_url] || user), notice:"Welcome back, #{user... ...
^
The problem is that method redirect_to take parameters only in parentheses, however notice also should passed in it. Add parentheses around all redirect_to parameters:
redirect_to( (session[:intended_url] || user), notice: "Welcome back, #{user.name}" )
or maybe space after redirect_to would work also:
redirect_to (session[:intended_url] || user), notice: "Welcome back, #{user.name}"
I followed the tutorial from railscast about authentication. Because I have two models that should be authenticated I changed the session create code a little bit:
def create
if User.find_by_username(params[:username]) != nil
user = User.find_by_username(params[:username])
if user && user.authenticate(params[:password])
session[:user_id] = user.id
redirect_to root_path, notice: "Eingeloged als User"
end
elsif Admin.find_by_username(params[:username]) != nil
admin = Admin.find_by_username(params[:username])
if admin && admin.authenticate(params[:password])
session[:user_id] = admin.id
redirect_to adminpage_index_path, notice: "Eingeloged als Admin"
end
else
flash[:error] = "Benutzername oder Password ist falsch"
render 'new'
end
end
If I login as user it works, and when I type in a false password it also works. But somehow when I want to login as admin I get the error:
Template is missing
Missing template sessions/create
I don't know why I get this error! I mean where does my code say that it should redirect to session create ? Thanks
My routes:
get 'login', to: 'sessions#new', as: 'login'
get 'logout', to: 'sessions#destroy', as: 'logout'
resources :users
resources :sessions
Look at the logic in your controller action:
if admin && admin.authenticate(params[:password])
session[:user_id] = admin.id
redirect_to adminpage_index_path, notice: "Eingeloged als Admin"
end
If you have provided a valid username and an invalid password, what is going to happen?
You're not going to get into that if statement - you're going to continue through the controller action, fall out the bottom, and the default behaviour in Rails is to render a view at the end of an action if no other behaviour is requested. Hence it's trying to render the create view for your create action - which doesn't exist.
You need to handle the invalid-password case for both users and admins.
Also, why are you calling find_by_username twice for both users and admins?
I think you are missing the else part in Admin authentication..
It should be,
def create
if User.find_by_username(params[:username]) != nil
user = User.find_by_username(params[:username])
if user && user.authenticate(params[:password])
session[:user_id] = user.id
redirect_to root_path, notice: "Eingeloged als User"
else
redirect_to root_path, notice: "Your Notice"
end
elsif Admin.find_by_username(params[:username]) != nil
admin = Admin.find_by_username(params[:username])
if admin && admin.authenticate(params[:password])
session[:user_id] = admin.id
redirect_to adminpage_index_path, notice: "Eingeloged als Admin"
else
redirect_to root_path, notice: "Your Notice"
end
else
flash[:error] = "Benutzername oder Password ist falsch"
render 'new'
end
end
So it looks like the faulty line is the redirect_to adminpage_index_path, notice: "Eingeloged als Admin" . It may help if you post your routes (run rake routes from your terminal). If it's saying the template is missing though, likely you don't have an index.html.erb in your app/views/adminpages/ folder? Is there a file there? (Also make sure you have the appropriate app/contollers/adminpages_controller and appropriate index action.
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
Record id 116 doesn't exist so it should return nil to #conversation.
I tried to make it redirect when it gets nil, but it still shows the error when I access example.com/messages/show?id=116 .
The error is
undefined method `is_participant?' for nil:NilClass
I definitely see 'is_participant' method existing in
/usr/local/lib/ruby/gems/1.9.1/gems/mailboxer-0.7.0/app/models/conversation.rb
messages_controller.rb
def show
#conversation = Conversation.find_by_id(params[:id])
unless #conversation.is_participant?(current_user)
flash[:alert] = "You do not have permission to view that conversation."
redirect_to :controller => 'messages', :action => 'received'
end
#messages = Message.find_by_id(params[:id])
current_user.read(#conversation)
end
You need to check that #conversation is not nil before you call a method on it. Try
unless #conversation.present? && #conversation.is_participant?(current_user)
You can check for presence of a value or rescue for that error.
def show
#conversation = Conversation.find_by_id(params[:id])
redirect_to somewhere_path if #conversation.nil?
unless #conversation.is_participant?(current_user)
flash[:alert] = "You do not have permission to view that conversation."
redirect_to :controller => 'messages', :action => 'received'
end
#messages = Message.find_by_id(params[:id])
current_user.read(#conversation)
end
or the Rescue!
def show
#conversation = Conversation.find_by_id(params[:id])
unless #conversation.is_participant?(current_user)
flash[:alert] = "You do not have permission to view that conversation."
redirect_to :controller => 'messages', :action => 'received'
end
#messages = Message.find_by_id(params[:id])
current_user.read(#conversation)
rescue NoMethodError
redirect_to somewhere_path
end
Notice that the rescue way is not very friendly, since it can rescue other error and making you have a pain to debug some errors. For example if current_user has no method named read, it would throw and error that would be catch there and you wouldn't notice it came from there.
Christoph Petschnig answer is right, just wanted to mention there is a nice shorthand for
unless #conversation.present? && #conversation.is_participant?(current_user)
which is
unless #conversation.try(:is_participant? , current_user)
try will return nil is #conversation is nil which eventually evaluates to false in the if statement.