I'm getting the following error after upgrading from 'rails', '2.3.15' to 'rails', '3.2.17'
Processing by HomeController#index as HTML
Completed 500 Internal Server Error in 320.9ms
SystemStackError (stack level too deep):
.bundle/ruby/1.9.1/gems/actionpack-3.2.17/lib/action_dispatch/middleware/reloader.rb:70
I know the error is somewhere in following method:
def current_user
return #current_user if defined?(#current_user)
#current_user = current_user_session && current_user_session.record
Authorization.current_user = #current_user
end
Would be awesome if someone that has implemented authlogic with rails 3 can give me some hints.
Thanks a lot!
Here is my full application controller:
class ApplicationController < ActionController::Base
helper :all # include all helpers, all the time
helper_method :current_user_session, :current_user
helper_method :current_user
helper_method :current_division
rescue_from Authorization::AttributeAuthorizationError, :with => :rescue_auth_error
protect_from_forgery # See ActionController::RequestForgeryProtection for details
# Scrub sensitive parameters from your log
around_filter :clear_current_user
before_filter :require_user
before_filter :configure_mailers
private
def rescue_auth_error(exception)
if current_user.present?
UserSession.find(current_user.id).destroy
flash[:error] = "Your session has expired. Please log in again."
redirect_to root_url
end
end
def clear_current_user
remove_instance_variable :#current_user if defined?(#current_user)
remove_instance_variable :#current_user_session if defined?(#current_user_session)
yield
remove_instance_variable :#current_user if defined?(#current_user)
remove_instance_variable :#current_user_session if defined?(#current_user_session)
Authorization.current_user = nil
end
def current_user_session
return #current_user_session if defined?(#current_user_session) && !#current_user_session.nil?
#current_user_session = UserSession.find
# #current_user_session = current_division.user_sessions.find
end
def current_user
return #current_user if defined?(#current_user)
#current_user = current_user_session && current_user_session.record
Authorization.current_user = #current_user
end
def require_user
unless current_user
store_location
# flash[:notice] = "You must be logged in to access this page"
redirect_to new_user_session_url
return false
end
end
def require_no_user
if current_user
store_location
# flash[:notice] = "You must be logged out to access this page"
redirect_to account_url
return false
end
end
def store_location
session[:return_to] = request.request_uri
end
def redirect_back_or_default(default)
redirect_to(session[:return_to] || default)
session[:return_to] = nil
end
def current_division
#current_division ||= Division.find_by_code('prd')
end
def configure_mailers
Notifier.configure(request)
end
def permission_denied
flash[:error] = "You do not have permission to access that page."
redirect_to root_url
end
end
This gem was causing the error:
gem 'rd_searchlogic', :require => 'searchlogic', :git => 'git://github.com/railsdog/searchlogic.git'
Replaced with:
gem 'ransack'
All is good now.
Related
I'm running into a NoMethodError while working through Hartl's Rails Tutorial. This error started showing up in chapter 11. Not sure where to track the problem back to. This is the error message:
NoMethodError in StaticPagesController#home undefined method `signed_in?' for #<StaticPagesController:0x007fa1b44a4ab8>
Rails.root: /Users/dbk/projects/apster
Application Trace | Framework Trace | Full Trace
app/controllers/static_pages_controller.rb:4:in `home'
And here's the code from my StaticPagesController:
class StaticPagesController < ApplicationController
def home
if signed_in?
#micropost = current_user.microposts.build
#feed_items = current_user.feed.paginate(page: params[:page])
end
end
end
Here's my ApplicationController:
class ApplicationController < ActionController::Base
# Prevent CSRF attacks by raising an exception.
# For APIs, you may want to use :null_session instead.
protect_from_forgery with: :exception
include SessionsHelper
end
Here's my sessions helper file:
module SessionsHelper
def sign_in(user)
session[:user_id] = user.id
end
def remember(user)
user.remember
cookies.permanent.signed[:user_id] = user.id
cookies.permanent[:remember_token] = user.remember_token
end
def current_user
if (user_id = session[:user_id])
#current_user ||= User.find_by(id: session[:user_id])
elsif (user_id = cookies.signed[:user_id])
user = User.find_by(id: cookies.signed[:user_id])
if user && user.authenticated?(cookies[:remember_token])
log_in user
#current_user = user
end
end
end
def logged_in?
!current_user.nil?
end
def forget(user)
user.forget
cookies.delete(:user_id)
cookies.delete(:remember_token)
end
def sign_out
forget(current_user)
session.delete(:user_id)
#current_user = nil
end
def redirect_back_or(default)
redirect_to(session[:return_to] || default)
session.delete(:return_to)
end
def store_location
session[:return_to] = request.url if request.get?
end
end
A NoMethodError means exactly that. A method that does not exist, or is not loaded, was called. This happens because you called your method logged_in? in SessionsHelper.
def logged_in?
!current_user.nil?
end
But you are calling signed_in? in StaticPagesController, which does not exist, and hence the error.
def home
if signed_in?
# ...
end
end
I am new to programming and getting the following errors while trying to get through the 9th chapter of Rails Tutorial. I checked the code several times but still didn’t understand why my local variable or method isn’t being defined. Every time I rewrite the code I get similar errors: undefined local variable or method ‘current_user’.
Error:
ERROR["test_layout_links", SiteLayoutTest, 0.888518]
test_layout_links#SiteLayoutTest (0.89s)
ActionView::Template::Error: ActionView::Template::Error: undefined local variable or method `current_user' for #<#<Class:0x007fcd97c44cf0>:0x007fcd97c4c4a0>
app/helpers/sessions_helper.rb:22:in `logged_in?'
app/views/layouts/_header.html.erb:8:in `_app_views_layouts__header_html_erb__1982327839123609485_70260496954760'
app/views/layouts/application.html.erb:12:in `_app_views_layouts_application_html_erb___2753884707929057206_70260450931560'
test/integration/site_layout_test.rb:6:in `block in <class:SiteLayoutTest>'
app/helpers/sessions_helper.rb:22:in `logged_in?'
app/views/layouts/_header.html.erb:8:in `_app_views_layouts__header_html_erb__1982327839123609485_70260496954760'
app/views/layouts/application.html.erb:12:in `_app_views_layouts_application_html_erb___2753884707929057206_70260450931560'
test/integration/site_layout_test.rb:6:in `block in <class:SiteLayoutTest>'
sessions_controller
class SessionsController < ApplicationController
def new
end
def create
user = User.find_by(email: params[:session][:email].downcase)
if user && user.authenticate(params[:session][:password])
log_in user
params[:session][:remember_me] == '1' ? remember(user) : forget(user)
redirect_back_or user
else
flash.now[:danger] = 'Invalid email/password combination' #Not quite right!
render 'new'
end
end
def destroy
log_out if logged_in?
redirect_to root_url
end
end
users_controller
class UsersController < ApplicationController
before_action :logged_in_user, only: [:edit, :update]
before_action :correct_user, only: [:edit, :update]
def show
#user = User.find(params[:id])
end
def new
#user = User.new
end
def create
#user = User.new(user_params)
if #user.save
log_in #user
flash[:success] = "Welcome to the Sample App!"
redirect_to #user
else
render 'new'
end
end
def edit
end
def update
if #user.update_attributes(user_params)
flash[:success] = "Profile updated"
redirect_to #user
else
render 'edit'
end
end
private
def user_params
params.require(:user).permit(:name, :email, :password,
:password_confirmation)
end
# Before filters
# Confirms a logged-in user.
def logged_in_user
unless logged_in?
store_location
flash[:danger] = "Please log in."
redirect_to login_url
end
end
# Confirms the correct user.
def correct_user
#user = User.find(params[:id])
redirect_to(root_url) unless current_user?(#user)
end
end
sessions_helper
module SessionsHelper
#logs in the given user.
def log_in(user)
session[:user_id] = user.id
end
#Remembers a user in a persistent session.
def remember(user)
user.remember
cookies.permanent.signed[:user_id] = user.id
cookies.permanent[:remember_token] = user.remember_token
end
#Returns the user corresponding to the remember token cookie.
def current_user?(user)
user == current_user
end
#returns true if the user is logged in, false otherwise.
def logged_in?
!current_user.nil?
end
#Forgets a persistent session.
def forget(user)
user.forget
cookies.delete(:user_id)
cookies.delete(:remember_token)
end
#logs out the current user.
def log_out
forget(current_user)
session.delete(:user_id)
#current_user = nil
end
# Redirects to stored location (or to the default).
def redirect_back_or(default)
redirect_to(session[:forwarding_url] || default)
session.delete(:forwarding_url)
end
# Stores the URL trying to be accessed.
def store_location
session[:forwarding_url] = request.url if request.get?
end
end
sessions_helper_test
require 'test_helper'
class SessionsHelperTest < ActionView::TestCase
def setup
#user = users(:michael)
remember(#user)
end
test "current_user returns right user when session is nil" do
assert_equal #user, current_user
assert is_logged_in?
end
test "current_user returns nil when remember digest is wrong" do
#user.update_attribute(:remember_digest, User.digest(User.new_token))
assert_nil current_user
end
end
I think you may be missing the current_user method. It's defined here.
Though the name is similar, current_user is a completely different method to current_user?. The question mark is a convention that typically means the method will return either true or false.
You're missing a current_user method in your sessions_helper.rb. Check back in Chapter 8.57
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 !
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
I have the standard current_user methods in my application_controller.
def current_user_session
return #current_user_session if defined?
(#current_user_session)
#current_user_session = UserSession.find
end
def current_user
return #current_user if defined?(#current_user)
#current_user = current_user_session &&
current_user_session.record
end
In my UserSessionController create method, I checked for
registration_complete? (simply a check on a value of a column, which
works fine) and then redirect the user to the user edit page if the
registration is not complete. When I debug this, I can see that the
attempted_record for the #user_session object exists and it's pointing
to the correct user, but the current_user method in
the redirect_to edit_user_path(current_user),
always returns nil.
What's going wrong here?
def create
#user_session = UserSession.new(params[:user_session])
# uses a block to prevent double render error...
# because oauth and openid use redirects
#user_session.save do |result|
if result
flash[:notice] = "Login successful!"
if #user_session.new_registration?
logger.info "Session controller : new
registration"
logger.info "Complete -
#{#user_session.registration_complete?}"
flash[:notice] = "Please review profile"
redirect_to edit_user_path(current_user)
else
if #user_session.registration_complete?
logger.info "Session Controller - registration
complete"
else
flash[:notice] = "Please complete profile"
logger.info "Session Controller - registration
not complete"
redirect_to edit_user_path(current_user)
#current_user nil here
end
end
redirect_to current_user ? profile_url(current_user) :
login_url
else
if #user_session.errors.on(:user)
# if we set error on the base object, likely it's
because we didn't find a user
render :action => :confirm
else
render :action => :new
end
end
end
end
I have seen this and used that very same authentication system on one of my applications. You don't mention it and that's why I'm proposing this to you if you do have then I'd need to see more of your application_controller, so anyway try and add this before the methods.
helper_method :current_user
I just had a duh moment, try doing this instead of passing a block to the save method.
if #user_session.save
# rest of your logic here
end
"if result" might not do what you expect it to do.
Else inspect this #user_session.record instead of current_user, if it's still nul your problem is not current_user.
I need to get home, I'll check back later tonight.
I had similar issue with authlogic and rails 3, and the problem that i figured out was
the apache http authentication that was enabled in my production server,
here is the solution to get that fixed, check Rails + Authlogic #current_user problem - "Show" method no longer works
Try to use this to rails2:
class ApplicationController < ActionController::Base
helper :all # include all helpers, all the time
protect_from_forgery # See ActionController::RequestForgeryProtection for details
#Authlogic
filter_parameter_logging :password
helper_method :current_user
private
def current_user_session
return #current_user_session if defined?(#current_user_session)
#current_user_session = UserSession.find
end
def current_user
return #current_user if defined?(#current_user)
#current_user = current_user_session && current_user_session.record
end
end
and this to rails3:
class ApplicationController < ActionController::Base
helper :all # include all helpers, all the time
protect_from_forgery # See ActionController::RequestForgeryProtection for details
helper_method :current_user
private
def current_user_session
return #current_user_session if defined?(#current_user_session)
#current_user_session = UserSession.find
end
def current_user
return #current_user if defined?(#current_user)
#current_user = current_user_session && current_user_session.record
end
end
/config/application.rb
# Configure sensitive parameters which will be filtered from the log file.
config.filter_parameters += [:password]