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 trial

Ruby

Getting an error on the 'gravatar_url' method when testing StatusController

I am on the Building Social Features in Ruby on Rails -> Creating Friendships -> join table video. Upon running the test, I receive the error 'Undefined method gravatar_url for nil:NilClass'

I got a similar error for the full_name method and this was fixed after several attempts to rewrite statuses and dropping/readding the database.

How could this particular error be solved?

9 Answers

The error your having is quite similar to the one at 2 min 52 seconds - where he's getting nil user for a status.

http://teamtreehouse.com/library/programming/build-a-simple-ruby-on-rails-application/testing-the-whole-app/testing-the-statuses-controller-3

Try making the statuses.yml both point to user micheal. ( if the statuses.yml's secondUser doesn't match to user.yml second_user - then when the test run instantiates status two: it will have a nil user and you'll see a problem when it asks a nil object for a method, in your case gravatar_url - which obv won't exist and program goes bang)

So, statuses.yml becomes:

one:
    content: "this is michael user status test"
    user: michael

two:
    content: "this is second user status test"
    user: michael

Rich

I was running into the same issue, and this fixed it. Thanks Richard!

Thank you Richard Wigley. Your last suggestion fixed the same problem for me. The user in the statuses.yml must correspond with the name of the fixture (header line) in users.yml (and this is case-sensitive, so if "jim" is the name in your second users.yml fixture, then your statuses.yml should have user: jim for the second one.)

The problem is the nil:NilClass. So the system is telling you that you are calling the method "gravatar_url" on a nil object. Calling a method on a nil object will result in an error being raised.

Problem will be something like my_object.gravatar_url

The likelihood is that you have objects in the database that were created before a relationship was added - these will have nil in them while newer objects will have none nil associations.

The quickest way to fix this is to delete all the objects in the database and then add them in again - nothing else needs to change since the data is the problem.

Rich

That makes sense. Coming from a db career "deleting everything from the db" tends to make me a bit nervous. Can you help fill in my sudo code below?

cd c:\path\treebook
rails c
#sudo code goes here?
exit
ruby -I test test/functional/statuses_controller_test.rb
#hopefully i dont get those errors here?

You need to get the line number of the crash so you can look at the line of code generating the error. That way you will know what attribute is causing the problem and give it extra focus during the bug fix.

I didn't notice it was in the test database. The test database is completely separate from the development database and in general test data is deleted after each test is run (I don't know how treehouse has set this up for the tutorial and I haven't done the exercise yet! so emphasise * in general *).

First thing I would do is make sure that the test database is the same schema as the development database (it's very easy to get out of step). In rails you do this with the command: rake db:test:prepare.

In general you want to run test prepare every time you create and run a migration on the development database. Running rake db:migrate does not change the test database.

Let me know how it goes...

Rich

Thanks for the reply Rich. The error is as follows

1) Error:
test_should_get_index(StatusesControllerTest):
ActionView::Template::Error: undefined method 'gravatar_url' for nil:NilClass
c:/path/treebook/app/views/statuses/index.html.erb:12:in 'block in _app_views_statuses_index_html_erb__960819892_42606468'

Line 12 of that file is this

<%= image_tag status.user.gravatar_url %>

In the app\models\user.rb file this method exists

def gravatar_url
    stripped_email = email.strip
    downcased_email = stripped_email.downcase
    hash = Digest::MD5.hexdigest(downcased_email)
    "http://gravatar.com/avatar/#{hash}.png"
end

My user in test\fixtures\users.yml look like the below

michael:
  first_name: "Michael"
  last_name: "Hopkins"
  email: "michael@hopkins.com"
  profile_name: "mhopkins"
  encrypted_password: <%= User.new.send(:password_digest, 'password') %>
  #password: "password"
  #password_confirmation: = "password"

second_user:
  first_name: "second"
  last_name: "user"
  email: "secondUser@secondUser.com"
  profile_name: "secondUser"
  encrypted_password: <%= User.new.send(:password_digest, 'password') %>
  #password: "password"
  #password_confirmation: = "password"

I'm not sure what the issue is here. Hopefully I've given enough info about my app to help diagnose it?

So, as discussed previously, from what I'm reading the status you are using in the test is returning nil for the user.

1 Can you show me the code for, test_should_get_index?

  1. How does the status test fixture associate with the user? I don't use fixtures in my testing so I'm pretty blind on that matter. I am imaging you have a status.yml and either the user associates itself to a status or a status associates itself with a user?

Rich

The test_should_get_index is the following

test "should get index" do
    get :index
    assert_response :success
    assert_not_nil assigns(:statuses)
end

I'm VERY new to rails so I will do my best to answer your second question. The statuses_controller_test gets users by using the sign_in method and then passing a user from the fixture to that method. For example, the test for should create status when logged in looks like this

 test "should create status when logged in" do
     sign_in users(:michael)
     assert_difference('Status.count') do
         post :create, status: { content: @status.content}
     end
     assert_redirected_to status_path(assigns(:status))
end

In my statuses.yml fixture I have the following

one:
    content: "this is michael user status test"
    user: michael

two:
    content: "this is second user status test"
    user: secondUser

I suppose my confusion is that when Jason Seifer was going through this tutorial, he didn't get the error. When I'm fairly certain he was working with the same code

EDIT: A correction to a statement above. The sign_in method is part of the Devise gem which was installed during the tutorial

Derek Saunders
Derek Saunders
5,167 Points

I did everything mentioned above and am still getting a nil error, I'm a little confused