Format date time in find operation in Rails 3 - ruby-on-rails

I'm looking for a way to format date time in find(:all) so that when I render my results in JSON, the date time will look like
"March 20, 2011"
instead of
"2011-03-20T04:57:50Z"
Does anyone have any suggestion? Thanks.

OK, so you want to render the results in JSON formatted nicely. Instead of changing the format of the date on the way in, change it on the way out.
class Post
def formatted_created_at
created_at.strftime("%b %d, %Y")
end
def as_json(args={})
super(:methods=>:formatted_created_at, :except=>:date)
end
end

I would have used Date.parse(datestring) on the client to generate some usable content.

Time.now().strftime("%b %d, %Y)

Off the top of my head, you could do something like:
#posts = Post.all
#posts.all.each do |x|
x.date = x.date.strftime("%b %d, %Y")
end
#posts.to_json

That works (checked in Rails 3.1), put it into config/initializer/times_format.js. First two lines fix default time format (e.g. AR created_at). Third part is monkey patch for JSON.
Date::DATE_FORMATS[:default] = "%Y-%m-%d"
Time::DATE_FORMATS[:default] = "%Y-%m-%d %H:%M:%S"
class ActiveSupport::TimeWithZone
def as_json(options={})
strftime('%Y-%m-%d %H:%M:%S')
end
end

Look you use jbuilder? and for example index.json.jbuilder
json.array!(#textstrings) do |textstring|
json.extract! textstring, :id, :text
json.created_at textstring.created_at.to_formatted_s(:short)
json.url textstring_url(textstring, format: :json)
end
in this example I am use method .to_formatted_s
json.created_at textstring.created_at.to_formatted_s(:short
and i've got
[{"id":1,"text":"liveasda","created_at":"17 Nov 12:48","url":"http://localhost:5555/textstrings/1.json"},{"id":2,"text":"123","created_at":"17 Nov 14:26","url":"http://localhost:5555/textstrings/2.json"},

Related

Set expiration date and time with before_create Rails 4

I am adding expire function to advertisement. Expire should contain data and time Like this: 12.06.12 14:24
At this point I done like this:
I have additional column in database for advertisements called expiration
before_create :set_expiration_date
def set_expiration_date
self.expiration = Date.today + 56.days
end
This works great. Now in view I want to see this expiration date.
Advertisement#show
<%= #advertisement.expiration.to_formatted_s(:db) %>
but it gives me just this 2015-02-06
When I changed set_expiration_date to:
def set_expiration_date
self.expiration = Time.now + 56.days
end
That still was like 2015-02-06 without time.
So I wonder if only soulution would be having two columns expiration_date and expiration_time to my advertisement table.
Then having like this in my model:
before_create :set_expiration_date
before_create :set_expiration_time
def set_expiration_date
self.expiration_date = Date.today + 56.days
end
def set_expiration_time
self.expiration_time = Time.now
end
I think this solution is very ugly.
Is there any other simpier solution to my problem ? How can I store in single column date and time?
Thanks in advance!
Change the datatype of expiration from date to datetime.
Change expiration from date to datetime, and why do you don't use strftime to beter format your output
example:
<%= #advertisement.expiration.strftime("%b %d %Y, %H:%M") %>
See also strftime format meaning

As would be appropriate to make an exception in the model?

I have a method parse_date_if_not_null which parses the date and time. But it so happens that the user entered an incorrect date format and time, then you need to show the error. I implemented it this way.
But I think, catch here only wrong format exception.
As would be appropriate to make an exception?
def parse_date_if_not_null
unless self.date_string.blank?
begin
self.ends_at = DateTime.strptime self.date_string, '%m/%d/%Y %H:%M'
rescue
errors.add(:date_string, _("Wrong date format, example: MM/DD/YYYY HH/MM"))
end
end
end
Yes it will be appropriate to make an exception in the model, you can do something like this..
class ...
validate: parse_data_if_not_null
def parse_data_if_not_null
unless self.date_string.blank?
erros.add(:date_string, 'Wrong date format, example: ...') if ((self.ends_at = DateTime.strptime self.date_string, '%m/%d/%Y %H:%M') rescue ArgumentError) == ArgumentError)
end
end

How do I sort posts by date and time?

I'm running a toto powered blog and I'm trying to sort posts correctly by date (if I post more than once in a day, the articles get sorted alphabetically for that day). Right now in my config.ru I have the basic setting for the date with # set :date, lambda {|now| now.strftime("%d/%m/%Y") } and a setting for time # set :time, lambda {|now| now.strftime("at %H:%I%p") }
In my layout.rhtml articles are sorted like so: <% articles.select {|a| a[:date] <= Date.today}[0..4].each do |article| %> I know I need to add the :time in there somehow, but have no idea how.
Add a field called time to your articles:
title: The Wonderful Wizard of Oz
author: Lyman Frank Baum
date: 1900/05/17
time: 12:30:00 PST
Dorothy lived in the midst of the great Kansas prairies, with Uncle Henry,
who was a farmer, and Aunt Em, who was the farmer's wife.
Monkey patch the Article class before the server block:
require 'time'
class Article
def timestamp
self[:timestamp] ||= Time.parse("#{self[:date].strftime("%Y-%m-%d")} #{self[:time]}")
end
end
toto = Toto::Server.new do
Now in your layout you can use the timestamp method for sorting:
<% articles.select {|a| a.timestamp <= Time.now}[0..4].each do |article| %>

Putting Date and 1.month.ago together?

How would I put Date and 1.month.ago together when I have a date attribute called :purchase_date and want to put it inside a class method?
def self.last_month # Show only products of last month.
where(:purchase_date => Date.today.1.month.ago.end_of_month..Date.1.month.ago.beginning_of_month)
end
console gives a syntax error and taking it away Date.today gives me blank results compared to my other method:
def self.this_month # Show only products of this month.
where(:purchase_date => Date.today.beginning_of_month..Date.today.end_of_month)
end
Just 1.month.ago is enough, you don't need to prepend Date.today to 1.month.ago because 1.month.ago starts from today
You have mistake in your Date syntax, you might want to use something like this:
def self.last_month # Show only products of last month.
where(:purchase_date => 1.month.ago.beginning_of_month..1.month.ago.end_of_month)
end
def self.this_month # Show only products of this month.
where(:purchase_date => Date.today.beginning_of_month..Date.today.end_of_month)
end
Maybe:
def self.this_month
where(:purchase_date =>(Date.today - 1.month)..Date.today
end
If the future time needs to be farther out, like in the case of planned subscription orders, remember to use .since
def self.next_quarter # Show only product order in the next 3 months
where(:purchase_date => Date.today.beginning_of_month..3.months.since)
end

How do I output records grouped by date in Rails?

Right now my page looks something like this:
Record10, created on 02.11.11
Record9, created on 02.11.11
Record8, created on 29.10.11
Record7, created on 25.10.11
...
Now, what is the best way to render this way:
02.11.11
Record10
Record9
29.10.11
Record8
25.10.11
Record7
...
Another working example of what I'm trying to accomplish is SO's reputation page, where there dates and each date has 1+ actions.
#records.group_by{|g| g.date.strftime("%d.%m.%Y") }.each do |date, record_group|
puts date.strftime("%d.%m.%Y")
record_group.each do |record|
puts " Record#{record.id}"
end
end
use AR's group_by:
Record.all.group_by{ |u| u.created_at.beginning_of_day }

Resources