Wednesday, April 6, 2011

Time comparison trouble with Rails

I have a very simple task at hand. If the last time a record was updated has been longer than 15 minutes, display a button. Otherwise, don't display the button.

The field is a datetime.

My view code:

<% if @object.display_button? -%>
  my button
<% end -%>

My display button method on that object:

def display_button?
  return false if last_updated.nil?
  if Time.now - last_updated > 15.minutes
    true
  else
    false
  end
end

I also have this unit tested, which are passing, but when it comes to the implementation, it doesn't seem to work.

Is my logic correct or would there be a better way of accomplishing this?

From stackoverflow
  • if last_updated < 15.minutes.ago
    

    The minutes method returns an integer I believe, and subtracting time object yields another time object. So your expression compares an int to a time and does something that you dont expect.

    15.minutes.ago yields a time object that can be directly compared to another time object.


    Also, never ever do if (something) return true; else; return false in ruby. Your method will return the value of that last expression executed in it, so you can vastly simplify that entire method:

    def display_button?
      last_updated && last_updated < 15.minutes.ago
    end
    

    Isn't that easier to read?

    Squeegy : is `last_updated` a time object? I was assuming it was. Go to script/console and type in "15.minutes.ago", you should get a time object back like "Tue, 24 Feb 2009 16:46:05 UTC +00:00". So be sure that last_updated is a time object too. Look at Time#since and Time#until too to calculate these.
    mwilliams : What's odd, is if I use this display_button method in the console, I return my true/false just fine when manually setting that object attribute, but inside the view, nothing changes. Will keep poking around.
    James A. Rosen : You probably also want to define the display_button? method in a Helper, not in the Model, since the Model doesn't really care whether a button is displayed. So something like "def display_button?(model)..."

0 comments:

Post a Comment