0

I have a show page where I need to both show the student's units and create a unit for them. However an error is being incurred when trying to do both.

In my controller

def show
  @student = Student.find(params[:id])
  @unit = @student.units.build
  @units = @student.units
end

In my view

<%= simple_form_for @unit, url: student_units_path(@student) %>
  # form...
<% end %>

<% @units.each do |unit| %>
  <tr>
    <td><%= unit.course %></td>
    <td><%= unit.mailing_date.strftime('%m/%d/%y') %></td>
  </tr>
<% end %>

The unit.course call works and any call that is only the first child of unit, however when I call a second method on unit I get this error:

undefined method `strftime' for nil:NilClass

despite knowing that the unit exists, hence the first call working

Will Sheehan
  • 25
  • 1
  • 5

2 Answers2

0

It seems your issue is that unit.mailing_date is nil, for newly-built records.

One solution would be to define a default value for mailing_date, either at the database level or in your application. For example, you could do something like:

class Unit < ActiveRecord::Base
  # ....
  after_initialize :set_default_mailing_date

  private
  def set_default_mailing_date
    self.mailing_date ||= Date.today
  end
end

Or alternatively, you could leave the mailing_date as nil and handle this gracefully in the view:

<td><%= unit.mailing_date.try!(:strftime, '%m/%d/%y') %></td>

If you are using ruby version 2.3+, then I would advise using the built-in safe navigation operator, rather than ActiveSupport's try! method:

<td><%= unit.mailing_date&.strftime('%m/%d/%y') %></td>

Finally, if you went with the above choice to leave the mailing_date as nil, then perhaps you'd like to display some default value in its place - for example:

<td><%= unit.mailing_date&.strftime('%m/%d/%y') || 'Not set' %></td>
Community
  • 1
  • 1
Tom Lord
  • 27,404
  • 4
  • 50
  • 77
0

As an alternative, I assume you don't want the new unit bound to the form being rendered which is what is causing the error.

You could do

@units = @student.units.reject(&:new_record?)

To remove the newly built unit from the collection

j-dexx
  • 10,286
  • 3
  • 23
  • 36