Stan
Stan

Reputation: 141

.count method not working on Heroku app

I am trying to show a count of array items in the Index view of my app.

In the controller I have the following code in the controller Update method:

def update
params[:course][:member_ids] ||= []
params[:teacher_name]
params[:attendees]


@course=Course.find(params[:id])
@[email protected]


@course.update_attribute(:attendance, @count_attendance)

In the view I use the following to display the count of array elements

<td><%= course.attendance %></td>

The count shows on localhost but when deployed to heroku I get the following error:

NoMethodError (undefined method `count' for nil:NilClass):

What am I missing?

Upvotes: 0

Views: 170

Answers (2)

K M Rakibul Islam
K M Rakibul Islam

Reputation: 34338

undefined method `count' for nil:NilClass

This means, you are calling count on a nil object which means, @course.attendees is returning nil on your heroku database, so when you call: @course.attendees.count, it tries to call: nil.count and get the mentioned error.

Make sure, you have the attendees data for the @course in your heroku database and try again. It should work!

You can see if you have the data in the heroku database by logging into heroku rails console: heroku run rails console, and then grab the course, something like: course = Course.find(123) and then see if you have the attendees data for that particular course: course.attendees in the heroku db.

You can also use try, that way your app won't crash if it calls count on a nil object:

@course.attendees.try(:count)

Upvotes: 2

Richard Peck
Richard Peck

Reputation: 76784

As explained by K M Rakibul Islam, your problem is that you're calling .count on an undefined variable (@course.attendees).

--

The fix - according to this answer: ActiveRecord: size vs count - could be to use size instead of count:

@count_attendance = @course.attendees.size

If this still returns the same error, you'll want to use some conditional code to make sure you're only calling methods on attendees if any exist:

def update
   @course = Course.find params[:id]
   @course.update attendance: @count.attendees.size if @count.attendees.any?
end

counter_cache

A much better solution to this is the counter_cache functionality of Rails:

#app/models/attendee.rb
class Attendee < ActiveRecord::Base
   belongs_to :course, counter_cache: :attendance
end

#app/models/course.rb
class Course < ActiveRecord::Base
   has_many :attendees
end

From the docs:

The :counter_cache option can be used to make finding the number of belonging objects more efficient...

With these declarations, asking for the value of @customer.orders.size requires making a call to the database to perform a COUNT(*) query. To avoid this call, you can add a counter cache to the belonging model

--

The reason your functionality works in development, but not production, is that your development db will likely have attendees populated with the relevant data. Heroku uses a separate database, meaning that you have to accomodate for any nil responses.

Upvotes: 1

Related Questions