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 trialLuke Thomas
9,077 Pointsundefined method `user' for nil:NilClass
I get an error when I try to add the name back into the status.
NoMethodError in Statuses#index Showing /Users/ryan/Projects/treebook/app/views/statuses/index.html.erb where line #9 raised:
undefined method `user' for nil:NilClass Extracted source (around line #9):
<% @statuses.each do |status| %>
<div class="status">
<strong><%= @status.user.full_name %></strong>
<p><%= status.content %></p>
<div class="meta">
<%= link_to time_ago_in_words(status.created_at) + " ago", status %>
Any help?
3 Answers
Aurelien Schlumberger
6,127 PointsYou made a typo. On the third line you made the variable status as an instance variable with the @ sign. Rails assumes you are referring to @status that is not present in your controller.
<% @statuses.each do |status| %>
<div class="status">
<strong><%= status.user.full_name %></strong>
<p><%= status.content %></p>
<div class="meta">
<%= link_to time_ago_in_words(status.created_at) + " ago", status %>
EDIT: To be more clear. Since you are referring to the instance variable @status that does not exist it cannot find any association with the User model. Ruby will accept a new instance variable even if its nil, because a nil variable is still an object and nil itself is an object (thats why everything is an object in Ruby). However Rails will return an error if the association is nil.
Maciej Czuchnowski
36,441 PointsLuke Thomas did this answer help you or do you still have problems with this error?
Luke Thomas
9,077 PointsThanks Aurelien, now I get this:
Showing /Users/ryan/Projects/treebook/app/views/statuses/index.html.erb where line #9 raised:
undefined method `full_name' for nil:NilClass Extracted source (around line #9):
<% @statuses.each do |status| %>
<div class="status">
<strong><%= status.user.full_name %></strong>
<p><%= status.content %></p>
<div class="meta">
<%= link_to time_ago_in_words(status.created_at) + " ago", status %>
Here's all my instances of full_name:
/Users/ryan/Projects/treebook/app/models/user.rb:
7 has_many :statuses
8
9: def full_name
10 first_name + " " + last_name
11 end
/Users/ryan/Projects/treebook/app/views/statuses/index.html.erb:
7 <% @statuses.each do |status| %>
8 <div class="status">
9: <strong><%= status.user.full_name %></strong>
10 <p><%= status.content %></p>
11 <div class="meta">
/Users/ryan/Projects/treebook/app/views/statuses/show.html.erb:
3 <p>
4 <strong>Name:</strong>
5: <%= @status.user.full_name %>
6 </p>
Edit: Had a friend look at it and fix it up.
We changed from Status.new to current_user.statuses.new to automatically assign the status to the current user, because otherwise the status didn't get assigned to a user.
Aurelien Schlumberger
6,127 PointsYes, if you want to create a new post and programmatically input data of the current user, then its better to use the method current_user. A user has many status relationship, so the status it can fetch information about the given user and vice-versa. current_user will provide all of his info if he/she has a session going on.
I think I am missing something with your full_name error. You can also try prepend self in front of your properties first_name and last_name. But I think the problem is somewhere else. Also in your user model, did you add attr_accessible? Also make sure that you belongs_to :user in your Status model.
def full_name
self.first_name + " " + self.last_name
end
Justin Black
24,793 PointsGoing through this right now... I've already done odot course (painfully).. and now doing this ( 'cause why not complete all the ruby videos? )...
Been on the same video for about 30 minutes now.. 3 sub-tutorials, and still got an error on the index... for me, I was a moron and added the @ before status like the OP did.. Removing that fixed my errors beautifully... Now I feel dumb lol
Luke Thomas
9,077 PointsRE make sure that you belongs_to :user in your Status model [done] RE did you add attr_accessible? [yes]
Hmm I think you're right, I think the problem I'm having with full_name is because first_name and last_name aren't working properly... so the problem is somewhere else.
My full_name variable wasn't returning anything, so I changed it to
def full_name
if first_name and last_name
first_name + " " + last_name
else
"Has no name"
end
end
And now "Has no name" is returning as all my user name - so that's why I think my first_name & last_name variables aren't working properly. Any ideas on this one Aurelien?
Aurelien Schlumberger
6,127 PointsWell that makes sense. If the user is missing the first_name AND last_name your original full_name method returns nil + " " + nil. If one of the two property is nil, the method cannot return a string. In ruby you cannot concatenate different data type, nil being a data type different than a string.
So make sure your users have a first_name and a last_name.
You can adapt your full_name method however you want it so it doesn't break. How about the following?
1) Make sure that default in your database that the properties first_name and last_name have a default value of type string "" if you want to use the following method. You can also use .present? method instead of .blank? to make sure that the properties are not blank ("") or nil, but beware that present can return a different boolean than blank.
2) Add conditions to check if the properties are not blank and return the string that you want. I added extra conditions so that it only adds the whitespace when needed.
def fullname
if self.first_name.blank? && self.last_name.blank?
return "has no name"
else
if self.first_name.blank?
return self.last_name
elsif self.last_name.blank?
return self.first_name
else
return self.first_name + " " + self.last_name
end
end
end
3) I usually prepend self when I try to access a property of a given user from a method stored in my model
def my_first_name
self.first_name if self.first_name.present?
end
4) You can refactor the code in step 2 by using ternary operators to make the code shorter. I made it more verbose to explain the problem.
5) There are other tricks out there such as creating a method that automatically converts nil to an empty string "".
Let me know what you think and if this works out for you :)
Below is the code in action in Rails Console (rails c)
1.9.3-p484 :001 > first_name = ""
=> ""
1.9.3-p484 :002 > last_name = ""
=> ""
1.9.3-p484 :003 > def new_fullname(first_name, last_name)
1.9.3-p484 :004?> if first_name.blank? && last_name.blank?
1.9.3-p484 :005?> return "has no name"
1.9.3-p484 :006?> else
1.9.3-p484 :007 > if first_name.blank?
1.9.3-p484 :008?> return last_name
1.9.3-p484 :009?> elsif last_name.blank?
1.9.3-p484 :010?> return first_name
1.9.3-p484 :011?> else
1.9.3-p484 :012 > return first_name + " " + last_name
1.9.3-p484 :013?> end
1.9.3-p484 :014?> end
1.9.3-p484 :015?> end
=> nil
1.9.3-p484 :016 > new_fullname(first_name, last_name)
=> "has no name"
1.9.3-p484 :017 > first_name = "Aurelien"
=> "Aurelien"
1.9.3-p484 :018 > new_fullname(first_name, last_name)
=> "Aurelien"
1.9.3-p484 :019 > first_name = ""
=> ""
1.9.3-p484 :020 > last_name = "Schlumberger"
=> "Schlumberger"
1.9.3-p484 :021 > new_fullname(first_name, last_name)
=> "Schlumberger"
1.9.3-p484 :022 > first_name = "Aurelien"
=> "Aurelien"
1.9.3-p484 :023 > new_fullname(first_name, last_name)
=> "Aurelien Schlumberger"
Aurelien Schlumberger
6,127 PointsWith this in mind, you can do a lot of cool things.
For example if you want to preserve the privacy of the user, you could display the last_name with only an initial.
If the user has a Chinese name 金山星, the first name and last name are in reverse order 山星 being the first name, and 金 the last name.
You can also add a link to the profile of the user if the user has a name.
and so on...
Luke Thomas
9,077 PointsI tried your method for full_name to be
def fullname
if self.first_name.blank? && self.last_name.blank?
return "has no name"
else
if self.first_name.blank?
return self.last_name
elsif self.last_name.blank?
return self.first_name
else
return self.first_name + " " + self.last_name
end
end
end
I signed up as a new user and double checked that i had a first and last name. Still returns "has no name".
So neither names are being stored :(
Where should I look to see why this is happening?
P.s. Never seen Rails C before but just tried it and ran your code, very helpful.
Luke Thomas
9,077 PointsFinally figured this out, followed the steps on here by sajad zada: https://teamtreehouse.com/forum/creating-relationships-between-users-and-statuses-fails-using-statususerfirstname-on-show-statuses-view