Model Accessor Question

Hi guys,

I have a table, “calendar_items”, which has a date/time column named
“reminder”. What I want to do is have the user select “x minutes
before start” on the form which calculates the reminder date/time
field from the start date/time. I figured the best way for this to
happen is to have an “attr_accessor :reminder_select” which is the
string/select on the form and then in the model, calculate the
reminder field before saving the record. Only problem is, it doesn’t
work!

Can anyone see where I’ve gone wrong? My guess is that when Rails
attempts to take the form data and save it to the model, it’s calling
the “reminder_select” method again, which resets the variable (to
“none”) instead of using the form data.

Thanks in advance, here’s the code:

VIEW:
Start: <%= datetime_select ‘calendar_item’, ‘date_time’, {:order =>
[:day, :month, :year], :start_year => Time.now.year, :minute_step =>
Reminder: <%= select(:calendar_item, :reminder_select, %w{ none 5
minutes 15\ minutes 30\ minutes 1\ hour 2\ hours 6\ hours 12\ hours 1
\ day 2\ days 7\ days 14\ days }) %>

CONTROLLER: (uses the generated methods for edit/update)

MODEL:

class CalendarItem < ActiveRecord::Base
attr_accessor :reminder_select

before_save :calculate_reminder

def reminder_select
return “none” if !self.date_time or !self.reminder

 difference = self.date_time - self.reminder
 if difference > 0 and difference < 1.hour
   return difference.minutes.to_s + " minutes"
 elsif difference > 0 and difference < 1.day
   val = (difference / 60 / 60).to_i
   if val > 1
     val = val.to_s + " hours"
   else
     val = val.to_s + " hour"
   end
   return val
 elsif difference > 0
   val = (difference / 60 / 60 / 24).to_i
   if val > 1
     val = val.to_s + " days"
   else
     val = val.to_s + " day"
   end
   return val
 else
   return "none"
 end

end

protected

def calculate_reminder
if self.reminder_select == “none”
self.reminder = nil
return
end

 words = self.reminder_select.split(" ")
 if words[1][0..5] == "minute"
   self.reminder = self.date_time - (words[0].to_i).minutes
 elsif words[1][0..3] == "hour"
   self.reminder = self.date_time - (words[0].to_i).hours
 elsif words[1][0..2] == "day"
   self.reminder = self.date_time - (words[0].to_i).days
 end

end
end

On 17/01/2007, at 11:43 AM, Dan H. wrote:

Can anyone see where I’ve gone wrong? My guess is that when Rails
attempts to take the form data and save it to the model, it’s
calling the “reminder_select” method again, which resets the
variable (to “none”) instead of using the form data.

Fixed it. In case anyone needs this in the future, I fixed it with:

  • return “none” if !self.date_time or !self.reminder
  • return read_attribute(‘reminder_select’) if !self.date_time or !
    self.reminder

and then moved the calculate_reminder method out of protected.

Dan