I am trying to access attributes about the current_user inside my controllers.
class MatchfinderController < ApplicationController
def c(value, t_array)
t_array.min{|a,b| (value-a).abs <=> (value-b).abs }
end
def show
peeps = User.find(:all, :conditions => ["id != ?", current_user.id])
user_a = []
peeps.each do |user|
user_a.push user.rating
end
closest_rating = c(current_user.rating, user_a)
#opponent = User.find(:all, :conditions => ["id != ? AND rating = ? ", current_user.id, closest_rating])
end
end
current_user is working in the view just fine however returns nil in the controller.
Here is my SessionsHelper.
module SessionsHelper
def sign_in(user)
cookies.permanent[:remember_token] = user.remember_token
self.current_user = user
end
def current_user=(user)
#current_user = user
end
def current_user
#current_user ||= User.find_by_remember_token(cookies[:remember_token])
end
def signed_in?
!current_user.nil?
end
end
The SessionsHelper is included by ApplicationController
class ApplicationController < ActionController::Base
protect_from_forgery
include SessionsHelper
end
Here is my SessionsController
class SessionsController < ApplicationController
def new
end
def create
user = User.find_by_email(params[:email])
if user && user.authenticate(params[:password])
sign_in user
redirect_to root_url, notice: "Logged in!"
else
flash.now.alert = "Email or password is invalid"
render "new"
end
end
def destroy
cookies[:remember_token] = nil
redirect_to root_url, notice: "Logged out!"
end
end
put your code in application controller and mark it as helper_method in this way you can use that method in both helper as well as controller
helper_method :current_user
def current_user=(user)
#current_user = user
end
I think helpers are only available to the view. Try putting this near the top of your controller:
include SessionsHelper
Related
I have some code here that is supposed to create a session upon login, and create "#current_user". However, neither of these things are working, and after 2 days of speculating, I can't figure out why.
Users controller:
class UsersController < ApplicationController
def new
#user = User.new
end
def create
#user = User.new(user_params)
if #user.save
redirect_to login_path
flash[:success] = "Account created. You may now log in"
else
redirect_to '/signup'
flash[:warning] = "Something went wrong. Try again."
end
end
private
def user_params
params.require(:user).permit(:username, :jabber_id, :password)
end
end
Sessions controller:
class SessionsController < ApplicationController
def new
end
def create
#user = User.find_by_username(params[:session][:name])
if #user && #user.authenticate(params[:session][:password])
session[:user_id] = #user.id
redirect_to '/posts'
else
session[:user_id] = nil
flash[:warning] = "Failed login- try again"
redirect_to '/login'
end
end
def destroy
session[:session_id] = nil
redirect_to login_path
end
end
Application controller:
class ApplicationController < ActionController::Base
def current_user
return unless session[:user_id]
#current_user ||= User.find(session[:user_id])
end
def require_user
redirect_to '/login' unless current_user
end
end
if a user has not signed in and visits localhost:3000/projects, this error occurs undefined method `projects' for nil:NilClass
I want to change it so it will be redirected to sign_in page. But using something like
if signed_in?
#projects=current_user.projects
else
link_to 'Please sign in first' ,signin_path
end
will raise errors
This is how the SessionsHelper looks like
module SessionsHelper
def sign_in(user)
remember_token = User.new_remember_token
cookies.permanent[:remember_token] = remember_token
user.update_attribute(:remember_token, User.digest(remember_token))
self.current_user = user
end
def signed_in?
!current_user.nil?
end
def current_user=(user)
#current_user = user
end
def current_user
remember_token = User.digest(cookies[:remember_token])
#current_user ||= User.find_by(remember_token: remember_token)
end
def sign_out
current_user.update_attribute(:remember_token,User.digest(User.new_remember_token))
cookies.delete(:remember_token)
self.current_user = nil
end
end
and here is my ApplicationController
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
include SessionsHelper
end
class ProjectsController < ApplicationController
def index
#projects=Project.all
end
end
if current_user
#projects = current_user.projects
else
redirect_to signin_path, notice: "Please sign in first"
end
Also it is common practice to define current_user method in application_controller.rb.
There are questions similar to this but none were able to help me. I am still learning rails and am making a basic user signup system. In the signin method of the SessionsHelper module, I use the self keyword.
module SessionsHelper
def sign_in(user)
remember_token = User.new_remember_token
cookies.permanent[:remember_token] = remember_token
user.update_attribute(:remember_token, User.encrypt(remember_token))
self.current_user = user
end
def current_user=(user)
#current_user = user
end
def current_user
remember_token = User.encrypt(cookies[:remember_token])
##current_user ||= User.find_by_remember_token(:remember_token) #The find_by method might not work
#current_user ||= User.where(remember_token: remember_token).first
end
def signed_in?
!current_user.nil?
end
end
I include the module in the ApplicationController class like so:
class ApplicationController < ActionController::Base
protect_from_forgery
include SessionsHelper
end
I think that means that the keyword self in the SessionsHelper module would therefore always refer to the ApplicationController class. However, shouldn't the current_user actually rrefer to the Sessions_controller? The sign_in method is also in the SessionsController and the UsersController, but based on my understanding of self, when the method is called inside these classes, it should still refer to the ApplicationController because that is where the SessionsHelper module is included. Here is the code for the UsersController:
class UsersController < ApplicationController
def new
#user = User.new
end
def create
#user = User.new(params[:user])
if #user.save
sign_in #user
flash[:success] = "Welcome to the Sample App"
redirect_to #user
else
render 'new'
end
end
end
Here is the SessionsController:
class SessionsController < ApplicationController
def new
end
def create
user = User.find_by_email(params[:session][:email].downcase)
if user && user.authenticate(params[:session][:password])
sign_in user
redirect_to user
else
flash.now[:error] = 'Invalid email.password combination'
render 'new'
end
end
end
Thanks to anyone who can help. I've been trying to understand this for hours.
#...snip
self.current_user = user
end
The self here is the class this module has been included into. So it executes the next line
def current_user=(user)
#current_user = user
end
This stores an instance variable on the controller -- the ApplicationController. Generally, all other controller inherit from the ApplicationController, so this affects the whole system.
I'm following this tutorial: http://ruby.railstutorial.org/
I have a problem with my sessions. Every time I login to my application, I get no session but get redirected to my user page. And create/register users works, too.
sessions_helper.rb
module SessionsHelper
def sign_in(user)
cookies.permanent[:remember_token] = user.remember_token
#current_user = user
#self.current_user = user
end
def signed_in?
#current_user != nil
#!#current_user.nil?
end
def current_user
#current_user ||= User.find_by_remember_token(cookies[:remember_token])
##current_user ||= User.find_by_remember_token(cookies[:remember_token])
end
def current_user?(user)
#current_user = user
end
def sign_out
self.current_user = nil
cookies.delete(:remember_token)
end
def store_location
session[:return_to] = request.url
end
end
session_controller.rb
class SessionsController < ApplicationController
def new
#title = "| Signin"
end
def create
user = User.find_by_email(params[:session][:email].downcase)
if user && user.authenticate(params[:session][:password])
sign_in user
redirect_to user
else
#Fehlermeldung anzeigen falls login nicht erfolgreich war
flash.now[:error] = "Invalid email/password combination"
render 'new'
end
end
def destroy
sign_out
redirect_to root_url
end
end
I see at least one mistake:
def current_user?(user)
#current_user = user
end
Should be
def current_user?(user)
#current_user == user
end
==, not =, because you should check that current_user equals some other user, not make an assignment.
I am not able to solve this syntax error I have on permission.rb. It says it needs a extra "end" but when I do add it Safari is unable to load the page. I have tried several different methods on both files, none seem to work. Any ideas?
Error:
SyntaxError in UsersController#new
/Users/lexi87/dating/app/controllers/application_controller.rb:20: syntax error, unexpected keyword_end, expecting end-of-input
Rails.root: /Users/lexi87/dating
Application Trace | Framework Trace | Full Trace
app/controllers/users_controller.rb:1:in `<top (required)>'
permission.rb (without the extra 'end'):
class Permission < Struct.new(:user)
def allow?(controller, action)
if user.nil?
controller == "galleries" && action.in?(%w[index show])
elsif user.admin?
true
else
controller == "galleries" && action != "destroy"
end
end
application_controller:
class ApplicationController < ActionController::Base
protect_from_forgery
private
def current_user
#current_user ||= User.find(session[:user_id]) if session[:user_id]
end
helper_method :current_user
def current_permission
#current_permission || ::Permission.new(current_user)
end
end
def authorize
if !current_permission.allow?(params[:controller], params[:action])
redirect_to root_url, alert: "Not authorized."
end
end
end
UPDATE
Here's my users_controller:
class UsersController < ApplicationController
before_filter :authorize
def new
#user = User.new
end
def profile
#profile = User.profile
end
def create
#user = User.new(params[:user])
if #user.save
UserMailer.registration_confirmation(#user).deliver
session[:user_id] = #user.id
redirect_to root_url, notice: "Thank you for signing up!"
else
render "new"
end
end
def show
#user = User.find(params[:id])
end
def edit
#user = User.find(params[:id])
end
def index
#users = User.all
end
def destroy
User.find(params[:id]).destroy
flash[:success] = "User deleted."
redirect_to users_url
end
def update
#user = User.find(params[:id])
if #user.update_attributes(params[:user])
flash[:success] = "Account updated"
redirect_to #user
authorize! :update, #user
else
render 'edit'
end
end
end
It looks like you need another end in permission.rb and you need to move one in application_controller.rb:
class ApplicationController < ActionController::Base
protect_from_forgery
private
def current_user
#current_user ||= User.find(session[:user_id]) if session[:user_id]
end
helper_method :current_user
def current_permission
#current_permission || ::Permission.new(current_user)
end
end # this shouldn't be here
def authorize
if !current_permission.allow?(params[:controller], params[:action])
redirect_to root_url, alert: "Not authorized."
end
end
# it should be here
corrections
1.
You definetely need the end at the end of the permission.rb
2.
you do not need and end to end the private section of ApplicationController. Everything below the private keyword is considered 'private'. So you need to move the "authorize" method.
solution
So the complete code is (with moving one method into "public"):
permission.rb:
class Permission < Struct.new(:user)
def allow?(controller, action)
if user.nil?
controller == "galleries" && action.in?(%w[index show])
elsif user.admin?
true
else
controller == "galleries" && action != "destroy"
end
end
end
application_controller:
class ApplicationController < ActionController::Base
protect_from_forgery
def authorize
if !current_permission.allow?(params[:controller], params[:action])
redirect_to root_url, alert: "Not authorized."
end
end
private
def current_user
#current_user ||= User.find(session[:user_id]) if session[:user_id]
end
helper_method :current_user
def current_permission
#current_permission || ::Permission.new(current_user)
end
end
You don't have to close the private keyword.
The end after
def current_permission
is not necessary !