How do I sort posts by date and time? - ruby-on-rails

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| %>

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

Not sure how to fill out missing paramters

This method is in tutor_session model
def self.tutor_minutes_ranking(users, start_date, end_date)
joins(:session_users)
.select('session_users.user_id, SUM(session_length)')
.where("session_users.user_id IN (?) and tutor_sessions.created_at > ? and tutor_sessions.created_at < ?", users, start_date.to_datetime, end_date.to_datetime)
.group('session_users.user_id')
.sum(:session_length, :order => 'sum_session_length DESC')
end
Ok, trying to get the total amount of minutes tutored in a month
This method is not written by me.
But I am trying to use it so I can display the total.
This is what I have in a different controller (ie, not tutor_session controller):
#total_minutes_month = TutorSession.total_minutes_for_user(current_user)
This is what I have in the view:
<% #total_minutes_month.each do |i| %>
<%= i.first %>
<% end %>
This is the error that comes up:
wrong number of arguments (1 for 3)
Obviously I didn't fill out the parameters for the second or third argument as displayed in the method.
The thing is, I'm not sure how to fill out the start_date, and end_date.
Advice?
Try this for the total time in this month:
TutorSession.total_minutes_for_user(current_user,
Time.now.beginning_of_month,
Time.now)
and something like this for the last month:
TutorSession.total_minutes_for_user(current_user,
1.month.ago.beginning_of_month,
1.month.ago.end_of_month)
#spickermann's answer is correct to solve your arguments error
However, when you mention you're then receiving an undefined_method error for the .each statement - the problem will be caused by #total_minutes_month having only the value of 0 - meaning there's no array/hash to cycle through
If you want to display the data you have from your method as it is now, you'll be best doing something like:
#app/views/controller/view.html.erb
<%= #total_minutes_month #-> should display total minutes for user %>
I'd personally attach the method to the user model's association, so you can call current_user.tutor_sessions.first.total_minutes_month:
#app/models/user.rb
Class User < ActiveRecord::Base
has_many :tutor_sessions, through :session_users do
def self.tutor_minutes_month(start, end)
joins(:session_users)
.select('session_users.user_id, SUM(session_length)')
.where("session_users.user_id IN (?) and tutor_sessions.created_at > ? and tutor_sessions.created_at < ?", id, start.to_datetime, end.to_datetime)
.group('session_users.user_id')
.sum(:session_length, :order => 'sum_session_length DESC')
end
end
end
Something like this will allow you to call current_user.tutor_sessions.first.total_minutes_month to give you the minutes per tutor session

After 24 Hours of recent status, create new status

Rails 3.2 Twitter App.
SOLUTION: Props to correct answer. I overlook the simple stuff sometimes. Ended up putting a line into my huge view. It was easier to me. Looks like this.
<% #ribbits.each do |ribbit| %>
<% if ribbit.user != current_user%>
<% if ribbit.user.following? current_user %>
<% if ribbit.created_at > (Time.now - 1.day) %>
etc.
I've got one last feature I'm trying to figure out. If a user's most recent status was created more than 24 hours ago, I'd like to create a new status of "yadayadayada" for them.
Here's how the most recent status is displayed.
users_controller.rb
def buddies
#ribbits = Ribbit.where("(ribbits.user_id, ribbits.created_at) IN (SELECT user_id, MAX(created_at) FROM ribbits WHERE user_id IN (?) GROUP BY user_id ORDER BY MAX(created_at) DESC LIMIT 10)", buddies_ids).order("created_at DESC")
/users/buddies.html.erb
<% #ribbits.each do |ribbit| %> ... etc
Something like this is either going in my users_controller.rb or ribbits_controller.rb
if #ribbits.user.ribbit created_at > (Time.now - 1.day)
Ribbit.new(:status => "sdfaklsdf")
end
Ribbits are tweets.
If you don't need this "default" status in the database, then you can just push the logic into the User model.
Something like:
class User < ActiveRecord::Base
def current_ribbit
if ribbit created_at > (Time.now - 1.day)
default_ribbit
else
ribbit
end
end
def self.default_ribbit
Ribbit.new(:status => "sdfaklsdf")
end
end
I think what you are looking of is a scheduler. You can use Delayed Job or Sidekiq for this. Sidekiq let's you create jobs at a specific time.

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 }

Format date time in find operation in Rails 3

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"},

Resources