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 ActiveRecord Basics AR Extensions Stateful Models

undefined method `name' for nil:NilClass

Rendered employees/show.html.erb within layouts/application (110.6ms) Completed 500 Internal Server Error in 116ms (ActiveRecord: 7.4ms)

ActionView::Template::Error (undefined method `name' for nil:NilClass):
    16:   <div class="entry">
    17:   <strong><%= entry.state %></strong>
    18:     <%= entry.time %>
    19:     <%= entry.account.name %>
    20:     <%= entry.created_at %>
    21:   </div>
    22: <% end %>

That part of code looks OK but there's a few other files involved.

You have an error that name is pointing at nothing, or nil:NilClass. So there could be something wrong with the way you've created your account instance.

Without a detailed walk-through I can't figure that out right now. If you have a GitHub repo, let me know and I'll try to replicate the issue tomorrow.

Steve.

84 Answers

I've no idea if this is to do with the issue you have but you have double-defined a variable in your accounts_controller - I'm just cruising through your code looking for stuff that looks off; this is the first I found:

class AccountsController < ApplicationController
    def index
        @accounts  = Account.all # delete this line
        @accounts = Customer.all
    end

    def show
        @account = Account.find(params[:id])

    end
end

Point @accounts at the Customer; delete the Account line.

Let me know if that helps,

Steve.

Start a new branch in git before you do this! git checkout -b new_branch_name

its not working Steve, i did the same as u said.

OK - I'm flying blind here so "it's not working" gives me nothing to go on. What errors do you get - did they change from what you posted before; what page are you visiting when you get those errors; have you restarted the server (you shouldn't need to for that, i don't think); have you tried navigating around your site and was that successful except for this page/view?

I have four employees, when i click on first two employee name it gave me the error-

NoMethodError in Employees#show Showing /Users/jitendragoyal/biller/app/views/employees/show.html.erb where line #19 raised:

undefined method `name' for nil:NilClass Extracted source (around line #19):

17 <strong><%= entry.state %></strong>
18  <%= entry.time %>
19  <%= entry.account.name %>
20 <%= entry.created_at %>
21  </div>
22 <% end %>

but when I click on the other two employees name it's working. i did everything, i have restarted the server many times.

You have probably created the first two employees before adding functionality to the database. Delete the two causing a problem inside the irb console. Use rails c and go find those two employees and delete them, then replace them with new one that reflect the new structure you have created.

Steve.

now the new error in rails console -

TimeEntry.all.each { |t| t.update_attributes(state: "submitted") }

TimeEntry Load (0.9ms) SELECT account_entries.* FROM account_entries WHERE account_entries.type IN ('TimeEntry') (0.3ms) BEGIN

Account Load (0.6ms) SELECT accounts.* FROM accounts WHERE accounts.id = 1 LIMIT 1

SQL (2.1ms) UPDATE account_entries SET state = 'submitted', updated_at = '2016-03-08 23:46:15' WHERE account_entries.id = 1 (2.6ms) ROLLBACK

NoMethodError: undefined method `update_balance!' for nil:NilClass

What did you type into the console to get that error?

i typed - TimeEntry.all.each { |t| t.update_attributes(state: "submitted") }

OK. That won't help with the problem. I think you have two employee objects that aren't possessing the updated properties because they were created earlier in the application's development. Those two employees need deleting via the console. This has nothing to do with time entries.

In the console, try something like Employee.first.destroy and see what that does on your Web page (view). If that removes one of the problem employees, type the same again in the console. You should only need to do that twice.

Be quick, it's nearly time for sleep here; I've been writing Rails all day and it's gone midnight here.

Steve.

Else I'll get back to you in the morning! :smile:

ok.i deleted all the employees through the console and create a new employee.but problem is same

sorry I disturbed u.

You aren't disturbing me at all, no. I want to help out.

I can't get to the bottom of the problem right now so I will pick this up in the morning.

Sorry I can't fix it now, but I must sleep.

Try Google for the error messages but bear in mind you have a nil problem, so something is pointing at nothing. Google can't help with that.

Sorry again, I'll get back to you tomorrow. It's gone midnight here.

Steve. :+1:

No problem Steve, you have to sleep.I'll try to solve the problem. thank you so much.

Right - I have your project and it is running as a server. I had to drop the database and start again so it is currently empty. I'll create an employee and see if I can render the show view as I think that was the issue you were having.

I can render the show view with my new employee; I don't get the error. I will add some time entries to see if that's the issue.

Still I have same problem. don't know why?

I think it is due to entries you have created perhaps before some validation went in. Also, I cant access /accounts - that's a blank view, which it shouldn't be.

This is my account.rb file code-

class Account < ActiveRecord::Base

has_many :account_entries, dependent: :destroy

validates :name, presence: true, 
                 length: {in: 1..70, 
                          message: "Please use a decent name, sir."}, 
                 uniqueness: true

validate :your_name_is_not_dumb

def your_name_is_not_dumb
    if name.include?("dumb")
        errors.add(:name, "is dumb")
    end
end

def update_balance!
    update_attributes( balance: self.account_entries.sum(:amount) )

end

end

I typed - TimeEntry.all.each { |t| t.update_attributes(state: "submitted") }

now the new error in rails console -

TimeEntry Load (0.9ms) SELECT account_entries.* FROM account_entries WHERE account_entries.type IN ('TimeEntry') (0.3ms) BEGIN

Account Load (0.6ms) SELECT accounts.* FROM accounts WHERE accounts.id = 1 LIMIT 1

SQL (2.1ms) UPDATE account_entries SET state = 'submitted', updated_at = '2016-03-08 23:46:15' WHERE account_entries.id = 1 (2.6ms) ROLLBACK

NoMethodError: undefined method `update_balance!' for nil:NilClass

What do you get if you type Account.count in the console?

Account.count

(37.7ms) SELECT COUNT(*) FROM accounts

=> 1576

That's a lot of accounts!! I've got one!! :smile:

Have you considered dropping the database and starting again from an empty one?

Also, if you visit http://localhost:3000/employees/XX Instead of XX, go to the console and find the employee id of Employee.first; put that number in place of XX.

Let's find where this error originates. It feels as thought there's something amiss with the model but I can't find it!

Employee.first

Employee Load (168.0ms) SELECT accounts.* FROM accounts WHERE accounts.type IN ('Employee') ORDER BY accounts.id ASC LIMIT 1

=> #Employee id: 1582, type: "Employee", name: "jyoti", email: nil, about: nil, created_at: "2016-03-09 00:10:35", updated_at: "2016-03-09 00:10:35", city: nil, zipcode: nil, state: nil, employees: nil, balance: nil

It should then output an employee - does it not?

Here's my output from one console cursor to the next - it outputs an employee after the hash:

irb(main):005:0> Employee.first Employee Load (0.5ms) SELECT accounts.* FROM accounts WHERE accounts.type IN ('Employee') ORDER BY accounts.id ASC LIMIT 1 => #Employee id: 1, type: "Employee", name: "Steve", email: nil, about: nil, created_at: "2016-03-09 11:25:30", updated_at: "2016-03-09 11:25:30", city: nil, zipcode: nil, state: nil, employees: nil, balance: nil irb(main):006:0>

when I visit http://localhost:3000/employees/XX and type the 12 instead of xx.I got error-

Couldn't find Employee with 'id'=12 [WHERE accounts.type IN ('Employee')]

What do you get with Employee.count in the console?

Employee.count

(3.4ms) SELECT COUNT(*) FROM accounts WHERE accounts.type IN ('Employee')

=> 2

means output of this query is correct.I have only two employees.

My problem is when I typed - TimeEntry.all.each { |t| t.update_attributes(state: "submitted") }

now the new error in rails console -

TimeEntry Load (0.9ms) SELECT account_entries.* FROM account_entries WHERE account_entries.type IN ('TimeEntry') (0.3ms) BEGIN

Account Load (0.6ms) SELECT accounts.* FROM accounts WHERE accounts.id = 1 LIMIT 1

SQL (2.1ms) UPDATE account_entries SET state = 'submitted', updated_at = '2016-03-08 23:46:15' WHERE account_entries.id = 1 (2.6ms) ROLLBACK

NoMethodError: undefined method `update_balance!' for nil:NilClass

This is the same error as the start of the thread; I'm trying to focus on one point. The issue is that something to do with account is pulling up a nil value; in Java terms, you have a Null Pointer Exception. The error will appear in many places and look slightly different, but I believe it is the same problem across the piece.

Let's rewind a little ... we've identified one employee; he has id 1582. So, let's go right back to the start and try localhost/employees/1582 - does that still produce the nil error on the account.name object?

TimeEntry.all.each { |t| t.update_attributes(state: "submitted") }

This query is not working.

I've answered above - let's try to focus on one point. Looking at a view that fails to render is much easier than understanding the workings of a loop that iterates over thousands of records!

If u need some file code of this project Ill send it to u.

I have your github project - I'm fine for code!

ok.

When I typed the http://localhost:3000/employees/1582- it show the Time entry Page and Im able to create Time Entries through the browser.

Cool - so it is now rendering employees/show.html.erb. Can you replicate the error at the start of this thread?

I've checked your models and controllers and can't see any issue with them, apart from the one point I made last night.

If that problem has gone away, do your views render as you would expect?

All the query is working correctly in console except- TimeEntry.all.each { |t| t.update_attributes(state: "submitted") }

Means problem is still same.I can't figure out the problem...

OK, so the problem is when operating on the account_entries.id. It sees the method update_balance as undefined. That's not the case, as we know, it is in your code. The issue is that the method is undefined for an object of nil::NilClass. So the issue is, again, the account entry, or account, pulling back a nil.

Walking through the code, the update_balance! method is held in the account model but it is called from the account_entry model via its own customer method, update_account_balance. Inside that method, it calls account.update_balance!. That's where it fails but that doesn't mean the lack of account stems from there. That could happen anywhere, annoyingly. I wonder if the lack of saving of the account instance at that point would cause it to drop the instance?

Worth a try - add this line in the update_account_balance! method inside AccountEntry - here's the whole method including the new line:

def update_account_balance!
  account.update_balance!
  account.save
end

It's a long shot, but worth a try.

Not working.

Yeah - I'm unsurprised but the line should be there, so leave it for now.

Where did the account_entry info come from; was it seeded through Faker?

Before we start to look at all the entries to see if there's some bit of relationship-vital info missing, let's look at the one we know fails. Your SQL output is:

SQL (2.1ms) UPDATE account_entries SET state = 'submitted', updated_at = '2016-03-08 23:46:15' WHERE account_entries.id = 1 (2.6ms) ROLLBACK

That's where it fails. So, it is trying to set the state of account_entries.id = 1 to 'submitted'. Does that entry even exist? In console what does AccountEntry.count give you, and then what does AccountEntry.find(1) give you?

Sorry this is taking ages - this is a tricky little bug!!

AccountEntry.count

(4.2ms) SELECT COUNT(*) FROM account_entries

=> 21

AccountEntry.find(1)

AccountEntry Load (0.4ms) SELECT account_entries.* FROM account_entries WHERE account_entries.id = 1 LIMIT 1

=> #TimeEntry id: 1, time: 1.0, customer_id: nil, employee_id: 1578, created_at: "2016-03-04 05:37:07", updated_at: "2016-03-04 05:59:26", account_id: 1, type: "TimeEntry", amount: 40, state: nil i

How to set the state of account_entries.id = 1 to 'submitted'.

Two things here; first your question, second some other thoughts ...

To set the time entry, something like:

a = AccountEntry.find(1)
a.state = 'submitted'

If that throws an error it should be clear what's wrong with the code. (It works!)

Should the Time Entries you load via the web page show up? They're not doing in my version of your app.

Load you server and go to /employees visit one of their show pages like:

Load the console and type TimeEntry.count, then add a time entry on the page so ther should be another TimeEntry ... type reload! into console then TimeEntry.count again. I get the same value returned - zero in my case. Do you get an incremented number?

If the state is already 'submitted', it'll error out as the object will return false, a member of nil::NilClass.

So, if that is the case, the use of update_attributes is causing the state setting to fail; returning false, not an object of account. Any subsequent call of an account method on false will throw the error you're seeing. I think.

I got Incremented number

Odd - I don't. Your code must be ahead of what's in GitHub. I'm struggling here!!

I Updated the code

When I typed -TimeEntry.all.each { |t| t.update_attributes(state: "initial") }

instead of "submitted", i changed the state to "initial". Then Im not getting error.

It must be down to overwriting the same state?

Tried a bit more in console.

First, I created an Account and an AccountEntry:

a = Account.create(name: "AnAccount")
b = AccountEntry.create(account_id: a.id)
b.update_account_balance!

That works ... previously, that was failing due to the lack of association with the Account id. I'm trying to figure out why that was happening.

Your Commands is working.

Problem is that, When we set the state = "submitted", query is not executing.

Sorry Steve for today to bother u.

Hey, it's really not a problem - I'm still plugging away at it! :+1:

I think there's a direction that's allowed for the update_attributes to complete and allow the instance to be saved.

I don't get the error if I use console for

l = TimeEntry.last
l.update_attributes(state: 'submitted')

Do you? But I don't get the error with

TimeEntry.all.each { |t| t.update_attributes(state: "submitted") }

Are you still getting that? If so, show me the instance of TimeEntry that the SQL failed on. Let's compare those to mine to see what's different.

TimeEntry.all.each { |t| t.update_attributes(state: "initial") }

SyntaxError: (irb):9: syntax error, unexpected & ...t| t.update_attributes(state: "initial") } ... ^ (irb):9: syntax error, unexpected ')', expecting '}' ...tes(state: "initial") }

What's wrong with that?! I've been looking at this code for too long now - I can't see why that's a syntax error. Did you copy/paste it? It might have dragged some odd characters across if you did.

This seems to work now. You can't set the state to initial, which is correct; that's not a state - the code tries the change then issues the ROLLBACK command so it doesn't save. You can set the state to submitted. This code gives the COMMIT message:

TimeEntry.all.each { |t| t.update_attributes(state: "submitted") }

You can then change them all to approved with this:

TimeEntry.all.each { |t| t.update_attributes(state: "approved") }

You can then set them back to submitted too.

I get no errors.

TimeEntry.all.each { |t| t.update_attributes(state: "submitted") }

This Command is not working

In the console, right? And do you get a syntax error or a rails error?

sorry for late reply, I lost the internet connection.

I got rails error.

OK - and is that the same error as before? Can you paste it in ...

TimeEntry.all.each { |t| t.update_attributes(state: "submitted") }

TimeEntry Load (0.6ms) SELECT account_entries.* FROM account_entries WHERE account_entries.type IN ('TimeEntry') (0.2ms) BEGIN

Account Load (0.3ms) SELECT accounts.* FROM accounts WHERE accounts.id = 1 LIMIT 1 (0.3ms) ROLLBACK

NoMethodError: undefined method `update_balance!' for nil:NilClass

from /Users/jitendragoyal/biller/app/models/account_entry.rb:24:in `update_account_balance!'

I think that some of your TimeEntry instances aren't linked to an account_id. I'm trying to figure out how to test that theory - give me a minute.

take ur time,don't worry.

This is a pain, and there must be a way to do this in console but I can't figure it out.

So, I've created a new view folder called time_entries and inside there I've created a view called index.html.erb. That file holds this code:

<% @time_entries.each do |te| %>
  <%= te.account_id %>
<% end %>

So that loops through all the time entries and outputs the account_id. BUT, @time_entries doesn't exist. And nor does the index action. So, go to your time_entries_controller.rb and add:

def index
  @time_entries = TimeEntry.all
end

Now, we need a route else that'll not work at all. So find your config/routes.rb file and add this:

get 'time_entries', to: 'time_entries#index'

You could probably just add resources :time_entries to the root of the file, rather than inside a do block - same difference.

So, what we've done there is created a loop in the view to iterate over all the time entries. In the controller, we've created an action for that type of view, the index action, and have created the @time_entries variable that's available across all the MVC files. To get the page to work, we've added a route that sends all requests for /time_entries to the right view, using the correct controller.

I hope that made sense ... in my browser, I have 4 numbers, one for each time entry, and no nil values. Have a go and see what you get, and I'll refine this a little further, to see if I can get it to correct the issues you're having.

Try this in the index.html.erb file after you've tried the first bits of code - it may be better - I can't test it as I can't create unlinked TimeEntry instances:

<% @time_entries.each do |te| %>
  <% if te.account_id.nil? %>
    <p>Time entry: <%= te.id %> has a nil account_id: <%= te.account_id %><p>
   <% end %>
<% end %>

This iterates over the same set of entries and outputs a string only if there's no account_id. I think! Try the other one first; see if there's some nil values, then substitute this code in. That will enable you to highlight the precise records that are causing a problem. We may be able to make it overwrite the nil entries make your database complete, assuming that's what the problem is. That's my theory at the moment!!

[EDIT - changed == nil to .nil? - nicer code]

Hi Jitendra,

Let me know how you got on or if I need to explain what I'm going on about!

Thanks,

Steve.

Hi Steve,sorry yesterday my internet was doing problem. Stiil i m getting same error.

My internet is awful too - but that's the only downside of living in a rural area; the rest is great!

What happened when you added the new view, controller and route? Did you try all that?

yeah i tried, but still not working.

OK - I asked you to add a route, a view and add code to a controller. What's 'still not working'? This is all new code.

I think we have different timings.means here is morning now and there?

It is 22:18 here now.

ok.

Means same problem as last night.

State = Submitted is not working

nil class error

Yes. My code wasn't there to fix the error; that exists within your database. It is there to identify what's wrong with your database.

Have you implemented all the code changes in my post about time_entries?

Yes I have implemented.But Nothing make difference.....what should i do?

I think you should read through the code and understand what it is doing. It changed nothing that you have done already, so it would alter none of that.

Visit /time_entries and see what it says. I gave the view code two options. Use the first option initially and see what that says.

And then try the second option with the <p> styling. The first should fill the browser with numbers; the second should be more filtered.

It is entirely possible that neither option will help solve this, but they will narrow down the potential issues.

Anyway, I've been training all evening so I'm knackered; and the Mac is outta gas. Try the above; push the changes to git and paste your screens into here. I will pick this up in the morning. 22:38 here now - I'm hitting the sack; early morning swim & bike set to do tomorrow.

Read through the code; post the results.

:smile: :+1:

Ok.thanks Steve.

Hi Steve, I tried to solve the issue.I think, the problem is between account_id and time_entries.I m sharing some screenshots to understand the issue--

I agree that is where the problem lies; that's what the code I wrote was trying to pull out - records where a TimeEntry has no account_id. Unfortunately, the screen shot you posted shows that my code didn't work the same on your machine as it did on mine. That's a pity. What have you run to produce a list of customers?

This is the Customer list.

customer list

I have some time_entries for few customers.like i have time_entry for customer "Kessler Denesik and Mayer and Sons".When I clicked on the Customer link for "Kessler Denesik and Mayer and Sons" on http://localhost:3000/accounts page it give me error--

Accounts#show

Yes, I figured this was the issue. Did you run the code that I suggested? That will highlight all cases where there's no account_id for a TimeEntry.

It didn't give me error for those customers for which i don't have time entries.

I don't understand; what happened when you opened the view for /time_entries?

Imgur

http://localhost:3000/accounts

This is the faker list of customer.

I don't remember the command. I did follow the video.give me a minute.

I have already run your code but it doesn't work.

Imgur

Right, so that's the code for the View, what happens when you visit the view?

Imgur

That's in the wrong place. Take the line outside the do block. Add it after the first end.

You can either add the get to: line at the root of the routes.rb file, or just move resources :time_entries outside of the block too; copy the line outide of the block:

resources :employees do
  resources :Time_entries
end      # after this
resources :time_entries # this copied
get 'time_entries', to: 'time_entries#index' # or this - same difference

Imgur

Imgur

Yes, because your route is hidden inside a doblock.

You are talking about these two lines -

get 'time_entries', to: 'time_entries#index'

ok, i did it.it give me blank page--

Imgur

That's good and bad at the same time. :smile:

One last thing to confirm my suspicions ... revert the view code back to:

<% @time_entries.each do |te| %>
  <%= te.account_id %>
<% end %>

This will give you a load of numbers and it means that I'm wrong - every TimeEntry has an account_id. Try that view code first, but I think we need to start again.

I reverted the code and result is-

Imgur

I thought you'd have more than that ... in console, what does TimeEntry.count give you? 32?

As u said.

yes 32

Dammit. There's some swearing going on here. lol.

I'm sure there's something wrong with a relationship in that database, but it isn't the TimeEntry to account_id one.

I've run out of ideas. If it were me, I'd drop the database and start with a fresh build and new Faker data. If the issue still persists, we'll need to drag Jason or Hampton into this, after we tidy up exactly what we're asking! This must be one of the longest threads in Treehouse!!

Yeah you are right Steve.This is the longest thread in treehouse community.now what i should to do next..

I honestly would drop the database and rebuild it from scratch. That way, if there's some dodgy relationships across the models they'll be reset with new data. You'll lose everything that's in there at the moment, but it's fake data anyway, and it can be replaced. It isn't guaranteed to fix the issue, but at least you'll know that everything's fresh and there's no legacy records hanging around.

If it still fails, we'll need to look at the state_machine code as that could be causing it. Or, perhaps, download the project files from Treehouse and compare across to yours? There must be a difference somewhere!! That might be a starting point. We're not going to pin it down ourselves; although I don't think we were far away - but we weren't close enough, either! Sorry!

Thanks Steve for your help.but There is no project file regarding to biller.Hampton didn't explain many things, so I didn't learn too much.Thats why Im not good at ACTIVE RECORD BASICS.

If I recall correctly, I got a little further than you did, but not very, before having my own issue that I couldn't fix. Some of the other Rails courses are similar, in that the explanations are perhaps a little too brief (or missing!) so many people drop the courses.

There are project files for it. You need to determine if the download is for the beginning of that section, or the end. It is usually the end, so you want to download the ones from the previous secion. In my, limited, experience setting up the project from these files can be a massive chore but you may find it more straightforward!

Treehouse are revamping their Rails courses for future release, which I'm looking forward to. There's also a couple of other sources of free Rails courses that I've found useful. I'm not saying they're better than Treehouse but they do provide a useful alternative view, in my opinion. I found that they supplemented what Treehouse had taught me.

For some Download it says u need to upgrade to pro.i don't have pro subscription.

I'm not on Pro subcription and I just downloaded the files from here.

thanks

hi

Hi! :smile:

how r u? I want to ask one question.

All good, thanks. You? And what can I help with?

how to create a rail instance for existing database?

I've never done that - however, I Googled, "build a rails application for an existing database" which comes up a lot of resources that will guide you through it.

This looks like a Gem that might be of assistance, too. But there's a lot of helpful links with that search.

ok.thanks Steve

Hi Steve,r u there?

I am now!

i do have access of company database through VPN but i dont know how to access the ruby code of that database.I can connect the my laptop to that server.

The database may not be using Ruby. I'd suggest asking your IT guys for access, if they're happy to grant it. If it is run using Rails the code is compiled when it is deployed leaving an application on the Web server. So, you can't access it directly, but you'd need access to the project in Staging or Development.

i have access of company database server , which i am accessing via mysql workbench. now he gave me task , to perform task i need to access ruby code and i am so new , i don't know if i can access rails using server database ?

is it possible to access rails instance when server access been given. ?

i am using tunnelblick to connect company DB.

Try running a console on the Rails instance. Navigate to the root of the server and run rails c - that should give you access to the instances and tables. Without knowing what you're dealing with, I'm only going to be guessing here!