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 trialMark Lavelle
2,910 PointsNoMethodError: undefined method `user_friendships' for nil:NilClass
I am having trouble with creating the friendship module. test is not recognising the user_friendships method in the create method.
Marks-MacBook-Pro:treebook Redeye$ ruby -Itest test/controllers/user_friendships_controller_test.rb
Run options: --seed 56989
# Running tests:
EE............
Finished tests in 0.229584s, 60.9799 tests/s, 74.0470 assertions/s.
1) Error:
UserFriendshipsControllerTest#test: #create with a valid friend_id should assign a friend object. :
NoMethodError: undefined method `user_friendships' for nil:NilClass
app/controllers/user_friendships_controller.rb:19:in `create'
test/controllers/user_friendships_controller_test.rb:93:in `block (3 levels) in <class:UserFriendshipsControllerTest>'
2) Error:
UserFriendshipsControllerTest#test: #create with a valid friend_id should assign a user_friendship object. :
NoMethodError: undefined method `user_friendships' for nil:NilClass
app/controllers/user_friendships_controller.rb:19:in `create'
test/controllers/user_friendships_controller_test.rb:93:in `block (3 levels) in <class:UserFriendshipsControllerTest>'
14 tests, 17 assertions, 0 failures, 2 errors, 0 skips
It is recognising it in the new method though. I have checked the server shell window for what is happening
the following is the log from the terminal shell
Started GET "/user_friendships/new?friend_id=marko" for 127.0.0.1 at 2014-02-28 11:31:21 +0000
Processing by UserFriendshipsController#new as HTML
Parameters: {"friend_id"=>"marko"}
User Load (0.3ms) SELECT "users".* FROM "users" WHERE "users"."id" = 2 ORDER BY "users"."id" ASC LIMIT 1
User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."profile_name" = 'marko' ORDER BY "users"."id" ASC LIMIT 1
Rendered user_friendships/new.html.erb within layouts/application (2.1ms)
Rendered layouts/_header.html.erb (0.4ms)
Completed 200 OK in 19ms (Views: 15.0ms | ActiveRecord: 0.5ms)
Started POST "/user_friendships" for 127.0.0.1 at 2014-02-28 11:31:24 +0000
Processing by UserFriendshipsController#create as HTML
Parameters: {"utf8"=>"?", "authenticity_token"=>"r+Kgh/7SwbvIFJmCrLEPNBjIaTJkWa7EbRCVZXBYa2A=", "user_friendship"=>{"friend_id"=>"#<User:0x007fdac84e78e8>"}, "commit"=>"Yes, add Friend"}
Redirected to http://localhost:3000/
Completed 302 Found in 1ms (ActiveRecord: 0.0ms)
Started GET "/" for 127.0.0.1 at 2014-02-28 11:31:24 +0000
Processing by StatusesController#index as HTML
Status Load (0.3ms) SELECT "statuses".* FROM "statuses"
User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? ORDER BY "users"."id" ASC LIMIT 1 [["id", 1]]
CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? ORDER BY "users"."id" ASC LIMIT 1 [["id", 1]]
User Load (0.1ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? ORDER BY "users"."id" ASC LIMIT 1 [["id", 2]]
CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? ORDER BY "users"."id" ASC LIMIT 1 [["id", 2]]
Rendered statuses/index.html.erb within layouts/application (9.4ms)
User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = 2 ORDER BY "users"."id" ASC LIMIT 1
Rendered layouts/_header.html.erb (1.4ms)
Completed 200 OK in 23ms (Views: 21.1ms | ActiveRecord: 0.8ms)
in particular it seems that the problem stems from here,
Started POST "/user_friendships" for 127.0.0.1 at 2014-02-28 11:31:24 +0000
Processing by UserFriendshipsController#create as HTML
Parameters: {"utf8"=>"?", "authenticity_token"=>"r+Kgh/7SwbvIFJmCrLEPNBjIaTJkWa7EbRCVZXBYa2A=", "user_friendship"=>{"friend_id"=>"#<User:0x007fdac84e78e8>"}, "commit"=>"Yes, add Friend"}
Redirected to http://localhost:3000/
Completed 302 Found in 1ms (ActiveRecord: 0.0ms)
I am using rails 4 but have worked around the strong params as best i could. don't think that is what is causing problem. Tried the answer Jason gave on another thread for the same problem that involved adding .profile_name to the valid friend_id context but that has had no effect what so ever. the browser raises the else part of the method , i.e. it flashes an error and returns the root_path.
here is my User Friendships Controller
class UserFriendshipsController < ApplicationController
before_filter :authenticate_user!, only: [:new]
def new
if params[:friend_id]
@friend = User.where(profile_name: params[:friend_id]).first
raise ActiveRecord::RecordNotFound if @friend.nil?
@user_friendship = current_user.user_friendships.new(friend: @friend)
else
flash[:error] = "Friend required"
end
rescue ActiveRecord::RecordNotFound
render file: 'public/404', status: :not_found
end
def create
if params[:friend_id]
@friend = User.where(profile_name: params[:friend_id]).first
@user_friendship = current_user.user_friendships.build(friend: @friend)
else
flash[:error] = "Friend required"
redirect_to root_path
end
end
end
Oh and the test is the user friendships controller test
require 'test_helper'
class UserFriendshipsControllerTest < ActionController::TestCase
context "#new" do
context "when not logged in" do
should "redirect to the login page" do
get :new
assert_response :redirect
end
end
context "when logged in" do
setup do
sign_in users(:mark)
end
should "get new page and return success" do
get :new
assert_response :success
end
should "set a flash error if the friend_id params is missing" do
get :new, {}
assert_equal "Friend required", flash[:error]
end
should "display the friend's name" do
get :new, friend_id: users(:rea)
assert_match /#{users(:rea).full_name}/, response.body
end
should "assign a new user friendship" do
get :new, friend_id: users(:rea)
assert assigns(:user_friendship)
end
should "assign a new user friendship to the correct friend" do
get :new, friend_id: users(:rea)
assert_equal users(:rea), assigns(:user_friendship).friend
end
should "assign a new user friendship to the currently logged in user" do
get :new, friend_id: users(:rea)
assert_equal users(:mark), assigns(:user_friendship).user
end
should "returns a 404 status if no friend is found" do
get :new, friend_id: 'invalid'
assert_response :not_found
end
should "ask if you really want to friend the user" do
get :new, friend_id: users(:rea)
assert_match /Do you really want to friend #{users(:rea).full_name}?/, response.body
end
end
end
context "#create" do
context "when not logged in" do
should "redirect to the login page" do
get :new
assert_response :redirect
assert_redirected_to login_path
end
end
context "when logged in" do
setup do
sign_in users(:mark)
end
end
context "with no friend_id" do
setup do
post :create
end
should "set the flash error" do
assert !flash[:error].empty?
end
should "redirect to the site root path" do
assert_redirected_to root_path
end
end
context " with a valid friend_id" do
setup do
post :create, friend_id: users(:adam).profile_name
end
should "assign a friend object" do
assert assigns(:friend)
end
should "assign a user_friendship object" do
assert assigns(:user_friendship)
end
end
end
end
Do I need to add the create method to the before_filter to authenticate_user from devise
to access current_user method ?
If I do that it raises a whole lot of errors.
I could go on adding code and error messages form the console but I think there is enough info there for someone smarter than me to figure out what I'm doing.
Thanks in advance and a pint on me in Dublin if you can help.
Cheers
Mark
1 Answer
JoJo KoKo
4,712 PointsThat error usually means that your calling the method "user_friendships" on a nil class. I.E. if you are calling --> @object.method_name and @object is nil, it will return this error message
Mark Lavelle
2,910 PointsThanks Jojo I was calling it on nothing as I had the test in the wrong place.
Mark Lavelle
2,910 PointsMark Lavelle
2,910 PointsEh... (sheepish sideways glance) remember ALWAYS CHECK FOR TYPOS I had one of the contexts out of context ( see what I did there Jason?? ) Unnested the contexts and read through the tests while re-watching Jason and found an extra end..
context "when logged in" do setup do sign_in users(:mark) end end <-- this one should not be there as the following tests don't have a logged in user if it <strong>is</strong> there