natmegs natmegs - 4 years ago 170
Ruby Question

Column of type date will not display, "undefined method `to_formatted_s' for nil:NilClass" in Rails

I am displaying database data from a model called Show that has columns:

id: integer, title: string, show_date: date, description: text, ticket_cost: string, location: string, created_at: datetime, updated_at: datetime


The controller accesses each Show instance via:

@shows = Show.all.order(:show_date)


And the view displays the information using:

<% @shows.each do |show| %>
<h4><%= show.title %></h4>
<h5><span class="glyphicon glyphicon-map-marker"></span><%= show.location %></h5>
<h5><span class="glyphicon glyphicon-calendar"></span><%= show.show_date.to_formatted_s(:long_ordinal) %></h5>
<h5><span class="glyphicon glyphicon-usd"></span><%= show.ticket_cost %></h5>
<h5><%= show.description %></h5>
<% end %>


All of the show information (title, location, ticket_cost, description) is displaying on the view page but the date does not display, giving the error "undefined method `to_formatted_s' for nil:NilClass". Rails console shows date values for the show_date column so the value is not nil. Additionally, the shows are being ordered correctly by date, but the date itself will not display?

Edit: Added a line before show.title:

<%= debug show %>


Which displays debug information for each instance before printing the values to the screen. One instance does not have a date but all others do, and even for instances that have a non-nil date, the date is not displaying. An example of the debug information for one of the instances is:

--- !ruby/object:Show
raw_attributes:
id: 3
title: Show 3
show_date: 2017-03-05
description: Show 3 description
ticket_cost: "$3"
location: Show 3 location
created_at: &2 2017-02-05 21:19:15.000000000 Z
updated_at: &4 2017-02-05 21:19:15.000000000 Z
attributes: !ruby/object:ActiveRecord::AttributeSet
attributes: !ruby/object:ActiveRecord::LazyAttributeHash
delegate_hash:
id: !ruby/object:ActiveRecord::Attribute::FromDatabase
name: id
value_before_type_cast: 3
type: !ruby/object:ActiveModel::Type::Integer
precision:
scale:
limit: 4
range: !ruby/range
begin: -2147483648
end: 2147483648
excl: true
original_attribute:
title: !ruby/object:ActiveRecord::Attribute::FromDatabase
name: title
value_before_type_cast: Show 3
type: &1 !ruby/object:ActiveRecord::ConnectionAdapters::AbstractMysqlAdapter::MysqlString
precision:
scale:
limit: 255
original_attribute:
show_date: !ruby/object:ActiveRecord::Attribute::FromDatabase
name: show_date
value_before_type_cast: 2017-03-05
type: !ruby/marshalable:ActiveRecord::AttributeMethods::TimeZoneConversion::TimeZoneConverter
:__v2__: []
[]: &3 !ruby/object:ActiveRecord::Type::DateTime
precision: 0
scale:
limit:
original_attribute:
description: !ruby/object:ActiveRecord::Attribute::FromDatabase
name: description
value_before_type_cast: Show 3 description
type: !ruby/object:ActiveModel::Type::Text
precision:
scale:
limit: 65535
original_attribute:
ticket_cost: !ruby/object:ActiveRecord::Attribute::FromDatabase
name: ticket_cost
value_before_type_cast: "$3"
type: *1
original_attribute:
location: !ruby/object:ActiveRecord::Attribute::FromDatabase
name: location
value_before_type_cast: Show 3 location
type: *1
original_attribute:
created_at: !ruby/object:ActiveRecord::Attribute::FromDatabase
name: created_at
value_before_type_cast: *2
type: !ruby/marshalable:ActiveRecord::AttributeMethods::TimeZoneConversion::TimeZoneConverter
:__v2__: []
[]: *3
original_attribute:
updated_at: !ruby/object:ActiveRecord::Attribute::FromDatabase
name: updated_at
value_before_type_cast: *4
type: !ruby/marshalable:ActiveRecord::AttributeMethods::TimeZoneConversion::TimeZoneConverter
:__v2__: []
[]: *3
original_attribute:
new_record: false
active_record_yaml_version: 1

Answer Source

My guess is that sometimes your date really is nil... this can sometimes happen with old, test data hanging around. You can temporarily get around this by using try eg:

show.show_date.try(:to_formatted_s, :long_ordinal)

This will help you stop seeing this bug... and maybe get some more details of what is going on with your data that's causing the problem.

I'd also recommend adding some logging statements so you can see the data better (just while you're bugfixing)... eg:

<%= @shows.inspect %>

to see all the data you're getting and possibly spot the bad one.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download