Welcome to the Treehouse Community
Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.
Looking to learn something new?
Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.
Start your free trialJoshua Shroy
9,943 PointsAuthentication from Scratch: current_user returns nil
I am building a role based authentication system from scratch using a Treehouse's course User Authentication in Rails as a general guide along with some other resources. The app I am building is a simple blog.
I posted a previous issue in Stack Overflow concerning an undefined method for 'admin?' for nil:NilClass
that I suspected had more to do with the method following it...current_user
. You can see my post here: http://stackoverflow.com/questions/29522637/testing-admin-authorization
It turns out that I am correct. I found the same failure popping up in my posts_controller_spec.rb
as well, except the failure message is undefined method for 'posts' for nil:NilClass
.
I tried many combos such as signing in/logging in a user before running the specs and simple syntax changes, but still find I'm at a loss. Any insight is very appreciated.
Here is my code.
Failures:
1) PostsController#GET create with valid attributes
Failure/Error: post :create, post: attributes_for(:post)
NoMethodError:
undefined method `posts' for nil:NilClass
# ./app/controllers/posts_controller.rb:16:in `create'
# ./spec/controllers/posts_controller_spec.rb:40:in `block (4 levels) in <top (required)>'
spec/controllers/posts_controller_spec.rb
before :example do
allow(controller).to receive(:require_auth)
@user = build_stubbed(:user)
sign_in(@user)
end
describe "#GET index" do
before :each do
@post = create(:post)
get :index
end
it { expect(response).to be_success }
it { expect(assigns(:posts)).to eq([@post]) }
end
describe '#GET show' do
before :each do
@post = create(:post)
get :show, id: @post.id
end
it { expect(assigns(:post)).to eq(@post) }
end
describe '#GET create' do
context 'with valid attributes' do
before :each do
post :create, post: attributes_for(:post), id: @user.id
end
it { expect(Post.count).to eq(1) }
it { expect(flash[:success]).to eq('Your post has been saved!') }
it { expect(assigns(:post)).to be_a(Post) }
it { expect(assigns(:post)).to be_persisted }
it { expect(response).to redirect_to Post.first }
it "creates a post by the current_user" do
@post = Post.last
expect(@post.user).to eq(@user)
end
end
#more tests.....
app/controllers/application_controller.rb
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
add_flash_types :success, :error
private
helper_method :current_user
helper_method :logged_in?
def logged_in?
current_user
end
def current_user
@current_user ||= User.find(session[:user_id]) if session[:user_id]
rescue ActiveRecord::RecordNotFound
end
def require_auth
unless current_user
session[:target] = request.fullpath
redirect_to new_user_session_path,
notice: "You must be logged in to access that page."
end
end
def require_admin
unless current_user.admin?
redirect_to post_path,
notice: "Access denied."
end
end
end
app/controllers/posts_controller.rb
class PostsController < ApplicationController
before_action :require_auth, expect: [:index, :show]
#some methods...
def create
@post = current_user.posts.new(post_params)
if @post.save
flash[:success] = "Your post has been saved!"
redirect_to @post
else
flash[:error] = "There was an error saving your post."
redirect_to new_post_path
end
end
#some more methods...
end
1 Answer
Brandon Barrette
20,485 PointsIt appears to be a typo in your posts_controller:
before_action :require_auth, expect: [:index, :show]
Should be:
before_action :require_auth, except: [:index, :show]
except instead of expect
Joshua Shroy
9,943 PointsJoshua Shroy
9,943 PointsThanks for catching that! However, I'm still running into the same error with
undefinted method 'posts' for NilClass
..