I've got a Reservation model that can take a scheduled appointment attribute as date and it has an online attribute duration that signifies how lengthy the appointment will require. The actual attribute, booking_end requires a Time that's recommended throughout my application. However, for easy input, we use duration rather than selecting 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 entire factor fails after i reference the date area while developing a new record. I recieve a 'nil' error because date has not been initialized. How do i fix this issue? The relaxation of the works when upgrading existing records.

Whenever you call Reservation.new(:date => date, :duration => duration) ActiveRecord::Base assigns characteristics values by doing this (see assign_characteristics method):

attributes.each do |k, v|
  ...
  respond_to?("#{k}=") ? send("#{k}="", v) 
  ...

Hash#each method iterates with the values the way in which :duration secret is utilized before :date one, so date is nil within the duration= method:

ruby-1.8.7-p302 > {:date => Date.today, :duration => 5}.each do |key,value|
ruby-1.8.7-p302 >     puts "#{key} = #{value}"
ruby-1.8.7-p302 ?>  end
duration = 5
date = 2010-11-17

So you will need to call duration= after initialization.

Or redefine Reservation#initialize to call super with :date after which update_characteristics using the relaxation of parameters.

I attempted to initialize the model with

Reservation.new(params[:reservation][:date]) 

after which call update_attributes onto it. This works in console, although not otherwise. The only real workaround that appears to consider hold is draining duration from the params hash after which passing it back before save. This appears really stupid, though, and most likely not the best or Rails method of doing things. Using 4 lines where you ought to suffice.

duration = params[:reservation][:duration]
params[:reservation].delete('duration')
@reservation = Reservation.new(params[:reservation])
@reservation.duration = duration
# Then go to save, etc.

Can there be an additional way to initialize the model or possibly access the characteristics hash from the model?