Reputation: 464
I have a helper that checks if a user is signed in or not:
def signed_in?
!current_user.nil?
end
I also have a helper that allows views and controllers to access the user object by checking the session:
def current_user
@current_user ||= User.find_by_session(session[:user_id])
end
In one of my controllers, it works fine to pull up the user object
def index
@households = current_user.households.all
@household = current_user.households.build
respond_to do |format|
format.html
format.xml { render xml: @households }
end
end
The other controller, however, chokes on the current_user helper when it tries to call the households relation:
def home
@households = current_user.households.all
@household = current_user.households.build
respond_to do |format|
format.html
format.xml { render xml: @households }
end
end
The error:
undefined method `households' for nil:NilClass
I'm pretty stumped and could not find any posts related to this specific subject. I'm new to rails though. Am I asking this question in the wrong way?
Thanks in advance.
Upvotes: 0
Views: 763
Reputation: 464
I hate to jump on here and answer my own question, but I had trouble with this for so long that I want anyone having the same problem to be able to figure this one out.
This turned out to be a mixture of many of the answers on this page as well as Michael Hartl's tutorial book.
I was using helper methods, but had not included the helpers in application_controller.rb
:
class ApplicationController < ActionController::Base
include ControllerAuthentication
include SessionsHelper
...
I also was verifying that a user was signed in to display them dynamic content in my view home.html.erb
:
<% if signed_in? %>
<!-- show the user dashboard -->
...
But I had no such verification on the controller static_pages_controller.rb
:
def home
if signed_in?
@households = current_user.households.all
@household = current_user.households.build
end
Because of all of this, the error:
undefined method `households' for nil:NilClass
was thrown continually while a user was not signed in and was trying to visit the root_path
. In other cases I could have redirected, but I wanted the user to see dynamic content on the home page if they were logged in and a static landing page if they were not.
Thanks everyone for the help!
Upvotes: 0
Reputation: 263
Might have just spotted why your current_user method is returning nil. Your searching by session not by ID. Try this:
def current_user
@current_user ||= User.find(session[:user_id])
end
OR if you want to be more explicit:
def current_user
@current_user ||= User.find_by_id(session[:user_id])
end
Upvotes: 1
Reputation: 263
The problem isn't that the current_user helper method is unavailable to the second controller, it's that your current_user method is not finding a user and returning nil. Then your attempting to call the households method on the returned nil object.
If the current_user method was not available in that controller you would see an error message such as:
undefined local variable or method `current_user' for #<YourController:0x1057870e8>
This means you have a flaw in the flow of your logic. Either the session parameter hasn't been set yet by the time it hits that method, or it was set but to a user_id that doesn't exist.
Try adding:
def home
@households = (logged_in? ? current_user.households.all : nil)
@household = (logged_in? ? current_user.households.build : nil)
respond_to do |format|
format.html
format.xml { render xml: @households }
end
end
Replacing nil with whatever your fallback data should be.
Upvotes: 1
Reputation: 21791
Try to include module into your second controller.
For example, helper module looks like this:
module UserHelper
def current_user
@current_user ||= User.find_by_session(session[:user_id])
end
end
Then include it into your controller:
class YourController < ApplicationController
include UserHelper
def home
@households = current_user.households.all
@household = current_user.households.build
respond_to do |format|
format.html
format.xml { render xml: @households }
end
end
end
Upvotes: 1