Welcome to the Treehouse Community

The Treehouse Community is a meeting place for developers, designers, and programmers of all backgrounds and skill levels to get support. Collaborate here on code errors or bugs that you need feedback on, or asking for an extra set of eyes on your latest project. Join thousands of Treehouse students and alumni in the community today. (Note: Only Treehouse students can comment or ask questions, but non-students are welcome to browse our conversations.)

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and a supportive community. Start your free trial today.

Ruby User Authentication with Rails Adding User Support to Our Application Scoping Todo Lists

Switching to current_user.todo_lists.new does not work, moreover, makes more tests fail. HELP PLEAAASE!

Hi guys, I follow the User Authentication with Ruby course and I'm implementing it in my own app. The only difference being, you have todo_lists and todo_items, I have parks and trees. All of the relationships are the same, however, I'm not using "mark completed". Here is the problem:

All of my tests are passing. Then I write a test to see whether the shown parks user equals the user of the session. I write it into "POST create with valid params" of parks_controller_spec.rb (in the video's example it is todo_lists_controller_spec.rb):

it "creates a park for the current user" do
        post :create, {:park => valid_attributes}, valid_session
        park = Park.last
        expect(park.user).to eq(user)
      end

It fails:

1) ParksController POST create with valid params creates a park for the current user
     Failure/Error: expect(park.user).to eq(user)

       expected: #<User id: 1, first_name: "First", last_name: "Last", email: "user8@treebook.com", password_digest: "$2a$04$VSYZW1n5GA0Sa11EhrWhpO8EMcx0f8rsNN0YIyhX1Lf...", created_at: "2014-07-21 18:41:13", updated_at: "2014-07-21 18:41:13">
            got: nil

       (compared using ==)

So as the video suggests, I go to my parks_controller.rb and change create method from:

  def create
    @park = Park.new(park_params)

to:

  def create
    @park = current_user.parks.new(park_params)

In the video, this solves the problem. However, in my case, this does not make the test pass, moreover, it makes the rest of the tests in "POST create with valid params" fail:

1) ParksController POST create with valid params creates a new Park
     Failure/Error: post :create, {:park => valid_attributes}, valid_session
     NoMethodError:
       undefined method `parks' for nil:NilClass

I spent hours on this and I was not able to solve it. I believe I got my routes.rb correct, here they are:

Treebook::Application.routes.draw do
  get "/login" => "user_sessions#new", as: :login
  delete "/logout" => "user_sessions#destroy", as: :logout

  resources :users
  resources :user_sessions, only: [:new, :create]

  resources :parks do
   resources :trees
  end
  root 'parks#index'

Can anyone help?

3 Answers

Jason Seifer
STAFF
Jason Seifer
Treehouse Guest Teacher

Hey Matej Lukášik I think the problem is using build_stubbed in this case without giving the stubbed object an id. I'm speculating that in the id is necessary for the specific object to be found. There is also a space in between create (:user) that could be throwing issues. If these suggestions don't work, can you post a link to your code up on GitHub and I'll take a look?

Jason Seifer
STAFF
Jason Seifer
Treehouse Guest Teacher

Hey Matej Lukášik it looks like maybe your user isn't logged in when posting to the create action. Try signing them in during the test and let us know if it works. You can also stub the current_user in the test.

Juan Ordaz
Juan Ordaz
12,012 Points

Can you post the new RSpec syntax? I am having a painful time ha! Please!.

Hi Jason, I'm honoured to receive such a "VIP" treatment :D I'm creating and signing in the user as suggested in the video:

  let(:valid_session) { {} }
  let!(:user) { create (:user)}

 before do 
    sign_in(user)
 end

Here is the sign_in method in AuthenticationHelpers:

module AuthenticationHelpers

  module Controller
    def sign_in(user)
      controller.stub(:require_user).and_return(user)
      controller.stub(:user_id).and_return(user.id)
    end
  end

  module Feature
    def sign_in(user, options={})
      visit "/login"
      fill_in I18n.t("email"), with: user.email
      fill_in I18n.t("password"), with: options[:password]
      click_button I18n.t("login_button")
    end
  end
end

Here is also my helpers configuration path:

RSpec.configure do |config|
  config.include ParkHelpers, type: :feature
  config.include RailsDomIdHelper, type: :feature
  config.include FactoryGirl::Syntax::Methods
  config.include AuthenticationHelpers::Controller, type: :controller
  config.include AuthenticationHelpers::Feature, type: :feature

I also tried inserting sign_in(user) into the test:

      it "creates a park for the current user" do
        sign_in(user)
        post :create, {:park => valid_attributes}, valid_session
        park = Park.last
        expect(park.user).to eq(user)
      end

and inserting stubbed user:

 it "creates a park for the current user" do
        sign_in(build_stubbed(:user))
        post :create, {:park => valid_attributes}, valid_session
        park = Park.last
        expect(park.user).to eq(user)
      end

But I still get the same error message:

1) ParksController POST create with valid params creates a park for the current user
     Failure/Error: post :create, {:park => valid_attributes}, valid_session
     NoMethodError:
       undefined method `parks' for nil:NilClass
     # ./app/controllers/parks_controller.rb:29:in `create'
     # ./spec/controllers/parks_controller_spec.rb:92:in `block (4 levels) in <top (required)>

I'm stuck :-( It seems you are right about the user not being signed in, however I have no idea how to fix it ...

Brandon Burton
Brandon Burton
9,688 Points

Did you manage to fix this? I'm getting the same error and can't seem how to get my app to recognize that I'm logged in