stumped by scheduler

I'm an amateur coder. Know enough to get into trouble, not enough to
get out of it.

I'm trying to make an office app for the photo studio I work for. Part
of this app is a scheduler.

Our assignments typically do not span more than a day.
I have defined starts_at and ends_at attributes in my model, both
datetime objects.

I have a datetime_select helper in the form to establish starts_at.

Because year, month and day will be the same for ends_at, I would
prefer the user not have to enter that redundant information. Ideally
I would like the user to only need to specify hour and minute for
ends_at, and have the rest picked up from starts_at.

For that reason, I added two textfield_tag helpers to the form to
capture how many hours and how many minutes we anticipated the event
to last.

I understand that a before_save callback in the model is a smart way
to go. I can't figure out how to do it.

Using raise params, I learned that the datetime_select helper does not
create a full blown datetime object but rather adds 5 items to the
params hash: starts_at(1i) - starts_at(5i)

I tried this (and multiple variations of this) to the before_save
method:

class Event < ActiveRecord::Base
  before_save :create_end
  def create_end
    self.ends_at.year = params[:starts_at[:1i]]
    self.ends_at.month = params[:starts_at[:2i]]
    self.ends_at.day = params[:starts_at[:3i]]
    self.ends_at.hour = params[:starts_at[:4i]] + params
[:duration_hours]
    self.ends_at.min = params[:starts_at[:5i]] + params
[:duration_minutes]
  end
end

That was a mess, so, following a helpful tip, I tried

def create_end
  ends_at = ends_at.change(:year => starts_at.year, :month =>
starts_at.month,
:day => starts_at.day, :hour => (starts_at.hour + params
[:duration_hours]),
:min => (starts_at.min + params[:duration_minutes]))
end

I'm clearly botching the syntax for the callback because nothing I
have tried has worked.

Help?
Thanks.

Steve

Well there is some funkiness todo with how time parameters are passed
around, but that is not the problem here. Equally the components of a
date or time object are readonly properties. What I think the core
misconception here is that params is a controller method therefore you
cannot call it from a model instance method. Usually you don't need
self.starts_at ? I'm not sure a callback is right for you here, are
you always going to want to update ends_at even on subsequent saves ?
You could instead have a method that takes a number of hours and
minutes and sets tends at correspondlingly, call that from your
controller. Lastly be careful about your calculations - not sureyour
examples wouldn't work if starts_at hour was 23 and duration_hours was
3 for example)

Fred

Thanks so much for taking the time to consider this Fred.

I got it working, thanks to some patient help from several complete
strangers. The generosity inside online communities is a wonderful
thing.

I had to add both duration_minutes and duration_hours to the model so
the callback could access them. I had initially been thinking of them
as just "disposable" items, not worth saving. Now I'm glad I did
because, to answer your question, yes we are just as likely to change
the duration of an assignment as we are to change its start time. Lots
of little last minute changes in our shop.
:frowning:
Once those attributes became available to the model, I could write a
before_save callback like this:

def create_end
  self.ends_at = starts_at.advance(:hours => duration_hours, :minutes
=> duration_minutes)
  end

So thanks again for your help. I learned some interesting things. Not
having worked with model callback methods before, I had not grasped
that the params method was not available to models. Thanks for that
insight.

Steve