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 trialJack McDowell
37,797 PointsNoMethodError in Statuses#show
Can someone help me with a NoMethodError in Statuses#show error? I'm using rails 4 and I forgot that this wonderful framework hates backwards compatibility. Anyway, I tried Lee Geertsen and Maciej Czuchnowski 's solutions and I can't get it to work. If anyone can help, here is my broken GitHub repo.
P.S. Does it just get worse from here or are the compatibility issues over? I'm trying to decide if I should just fire up a VM instead and download the program files.
3 Answers
Maciej Czuchnowski
36,441 PointsJack, I downloaded your project locally.
The error states: undefined method `first_name' for nil:NilClass
. Ths means that @status.user
is nil. This in turn means that you did not assign any user to the status. If you run rails c
and check Status.last
you will notice that one of the parameters states user_id: nil
- the user was not assigned, so Rails can't do nil.first_name.
If you look closely at the Rails server log, you will notice this line when new status was created:
Unpermitted parameters: user_id, content
This means that you are passing user_id and content correctly, but because of strong parameters, you have to overtly allow these parameters to be saved in the database.
You need to add this to your statuses_controller file:
private
def status_params
params.require(:status).permit(:user_id, :content)
end
also, your create method has to start like this to use these status_params:
def create
@status = Status.new(status_params)
You need to permit parameters this way every time you want to pass them through a form and save in the database.
Juan Ordaz
12,012 PointsIn your statuses controller, you need to modified the [:create, :update, :destroy] actions. I don't know if the above answers are the best, because in the console you can see that the statuses.user_id returns nil, when query the Status.first.user_id. This is because, you are creating a status that does not belong to anybody. So when you are trying to render show view, the status has no user_id then you can not have access to the last_name attribute thats why you see and error. So you have to tell you controller who is writing the status. I tried to follow the video but is out of date and is ok( struggle to find an answer is the best way to learn). Devise gives you " current_user helper." In your controllers, use current_user helper like is shown below. This is the most conventional way to fix the bug(I think). The controllers should do this job(to check users credentials), not the model like in the video shows. The video is not wrong, is just that there has been many changes in Rails 4. Struggle == Learn.
def create
@status = current_user.statuses.new(status_params)
respond_to do |format|
if @status.user == current_user
@status.save
format.html { redirect_to @status, notice: 'Status was successfully created.' }
format.json { render :show, status: :created, location: @status }
else
format.html { render :new }
format.json { render json: @status.errors, status: :unprocessable_entity }
end
end
end
def update
respond_to do |format|
if@status.user == current_user
@status.update(status_params)
format.html { redirect_to @status, notice: 'Status was successfully updated.' }
format.json { render :show, status: :ok, location: @status }
else
format.html { render :edit }
format.json { render json: @status.errors, status: :unprocessable_entity }
end
end
end
def destroy
if @status.user == current_user
@status.destroy
respond_to do |format|
format.html { redirect_to statuses_url, notice: 'Status was successfully destroyed.' }
format.json { head :no_content }
end
else
redirect_to statuses_path
end
end
Maciej Czuchnowski
36,441 PointsYeah, you can't really do this course using Rails 4 and newest versions of gems unless you really know how and what to do and like experimenting a lot. What is your problem exactly? You show action seems to be empty: https://github.com/jackmcdowell/RubySocialMediaSite/blob/broken_authentication/app/controllers/statuses_controller.rb#L12
Jack McDowell
37,797 PointsHello Maciej Czuchnowski , I changed the statuses controller to what the project files have but I still have the same problem (changes are pushed to GitHub). 1) Run rake db:drop db:create db:migrate 2) Create user (/users/sign_up): works and creates user 3) Post new status: Shows user name under user drop down. 4) Select user and post content: Broken After I click submit, it says on /statuses/1
"NoMethodError in Statuses#show" line 3 highlighted
<p>
<strong>Name:</strong>
<%= @status.user.first_name %><%= @status.user.last_name %>
</p>
And if I just go to the root it says "NoMethodError in Statuses#index" line 3 highlighted
<% @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 %>
Jack McDowell
37,797 PointsJack McDowell
37,797 PointsThank you Maciej Czuchnowski , the problem is with the strong parameters as you mentioned. I tried your fixes and it looks like it is one step closer to working, but I'm going to try finishing the project with rails 3.2 and maybe come back to this when I'm a better rails programmer. Coming from PHP I'm having to get adjusted to the innovation over standardization of Rails!