Reputation: 141
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
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
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
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 aCOUNT(*)
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