3

I'm on Rails 3.0. For a model's updated_at column, I need to output that as a user friendly format in JSON, so instead of seeing this 2011-09-14T22:01:32Z as the value, I would like to show less than a minute ago (or whatever user-friendly message I decide) for updated_at. I wrote a method that returns the output in the user-friendly format and now needs the functionality to be available in views, controller and model. What's the best way to do this so it isn't convoluted or bad practice.

EDIT Per answer from @klochner, here's what my date.rb looks like but now it throws date.rb:21:informat': wrong number of arguments (2 for 0) (ArgumentError)`

include ActionView::Helpers::DateHelper

class ActiveSupport::TimeWithZone
  def friendly
    format
  end
end

class Date
  def friendly
    format
  end
end

class Time
  def friendly
    format
  end
end

def format
  if self.today?
    format_time = ...
  elsif (self < Time.now.beginning_of_day) and (self > Time.now.yesterday.beginning_of_day)
    format_time = ...
  else
    format_time = ...
  end
end

@klochner suggestion changing format to format_helper works great. Thanks!

Johnny Klassy
  • 1,650
  • 5
  • 16
  • 22

1 Answers1

2

MonkeyPatch the ActiveSupport::TimeWithZone class, here's what I do (I put this in config/initializers/date.rb)

class ActiveSupport::TimeWithZone
  def mdy
    self.strftime("%m/%d/%Y")
  end
end
class Date
  def mdy
    self.strftime("%m/%d/%Y")
  end
end
class Time
  def mdy
    self.strftime("%m/%d/%Y")
  end
end

Then for any date object (or date field in an AR model), you can call mdy():

 > Time.now.mdy
 => "09/14/2011" 
> User.first.created_at.mdy
 => "02/27/2009" 
> Date.today.mdy
 => "09/14/2011" 

For json, you probably want to write an as_json method for the model that you're rendering. See this related answer: render :json does not accept options

Community
  • 1
  • 1
klochner
  • 8,077
  • 1
  • 33
  • 45
  • Good stuff, I was able to get the basics working, now the question is how to include this in JSON, I could create custom methods and include them using `:methods` in the JSON call but I prefer something more elegant if possible. Sorry I can't vote up for your answer yet since I don't have enough reputation points, if you vote my question up, it might help me to vote your answer up :) – Johnny Klassy Sep 15 '11 at 19:35
  • i don't understand why you can't include this in JSON - just use the instance method, it should be available everywhere. – klochner Sep 16 '11 at 02:54
  • What would be the syntax for the JSON call? Also, I ran into a new issue, `rails console` now throws a `wrong number of arguments (2 for 0) error in 'format' for `date.rb'. I have updated my question with the details of `format` method. – Johnny Klassy Sep 16 '11 at 17:29
  • you can fix the argument error by renaming format to format_helper – klochner Sep 16 '11 at 17:32
  • Sorry @klochner, I still don't have enough points to up vote your answer but I can now mark it as an answer. Yes, I just got 15 points and up vote your answer. – Johnny Klassy Sep 16 '11 at 17:32
  • Thanks, I ended up adding custom methods for the models I want included in the JSON output. Your suggestion is a good one though I don't see how I can `:include :only` for something like `comment.updated_at.friendly`. I think I can only `:include :only => [:updated_at, ...]`. – Johnny Klassy Sep 16 '11 at 18:14