I have a Reservation model that takes an appointment attribute as date and has a virtual attribute duration that indicates how long the appointment will take. The real attribute, booking_end takes a Time that is referenced all over my application. However, for ease of input, we use duration instead of choosing another Time. The fields are below:
def duration
( (booking_end - date) / 1.hour ).round( 2 ) rescue nil
end
def duration=(temp)
if ( true if Float(temp) rescue false )
self.booking_end = time_round(date + temp.to_f.hours, 15.minutes)
else
errors.add(:duration, "must be a number, stated in hours.")
self.booking_end = nil
end
end
The whole thing fails when I reference the date field while creating a new record. I get a ‘nil’ error because date hasn’t been initialized. How can I fix this problem? The rest of this works when updating existing records.
When you call Reservation.new(:date => date, :duration => duration) ActiveRecord::Base assigns attributes values this way (see assign_attributes method):
Hash#each method iterates through the values the way that :duration key is accessed before :date one, so date is nil inside the duration= method:
So you’ll have to call duration= after initialization.
Or you can redefine Reservation#initialize to call super with :date and then update_attributes with the rest of parameters.