Access instance variables from model?


#1

Can I make my model methods aware of the context (preferably instance
variables) where they are run, without having to pass them arguments?

The app in question should be time zone aware, so something like
user.events[0].starts_in should check against @logged_in_user.now rather
than Time.now.

I could send the user as an argument
(user.events[0].starts_in(:timezoned => @logged_in_user)), but there are
a number of methods where this applies, and it seems more DRY to just
read it from the context.

I do realize this might not be ideal MVC, so I’m open for work-around
suggestions.


#2

On Apr 7, 2006, at 12:07 AM, Henrik N wrote:

there are
a number of methods where this applies, and it seems more DRY to just
read it from the context.

I do realize this might not be ideal MVC, so I’m open for work-around
suggestions.

Two suggestions:

  1. I think events.first is far better than events[0]

  2. How about this: user.localtime(user.events.first.starts_in)

  3. Wouldn’t starts_at be a better column name? At first I thought
    starts_in must be a method to calculate the interval between
    now and event start time, but that doesn’t make sense in this
    context because the interval between now and a time has nothing
    to do with timezones at all (i.e. if something happens in three
    hours, it happens in three hours regardless of what time zone
    you’re in)

  4. Just in case you’re not already doing this, when handling
    timezones, store all times in UTC, and convert all times
    to user local times for display. This prevents eliminates
    conversion on all operations except display.


– Tom M.


#3

Tom M. wrote:

On Apr 7, 2006, at 12:07 AM, Henrik N wrote:

there are
a number of methods where this applies, and it seems more DRY to just
read it from the context.

I do realize this might not be ideal MVC, so I’m open for work-around
suggestions.

Two suggestions:

  1. I think events.first is far better than events[0]

True, thanks.

  1. How about this: user.localtime(user.events.first.starts_in)

Well, in this case (see my answer to 3 below) I would actually return a
time distance in words rather than a time to be converted. There might
be other methods like event.happening_right_now or whatever, that could
return booleans. It seems like the most elegant solution is to perform
time zone calculations within the model, but I suppose maybe then I’ll
have to pass the user/time zone as an argument.

  1. Wouldn’t starts_at be a better column name? At first I thought
    starts_in must be a method to calculate the interval between
    now and event start time, but that doesn’t make sense in this
    context because the interval between now and a time has nothing
    to do with timezones at all (i.e. if something happens in three
    hours, it happens in three hours regardless of what time zone
    you’re in)

This was just a made-up example, though I do actually have some
“starts_in”-ish code that is time zone dependent. A simple example would
be new_day.starts_in, which would give different results for different
time zones. If the events occur at some time zone dependent time, the
starts-in value will differ.

  1. Just in case you’re not already doing this, when handling
    timezones, store all times in UTC, and convert all times
    to user local times for display. This prevents eliminates
    conversion on all operations except display.

I’m definitely doing that already. :slight_smile:

Thanks!

/ H