如何按日期对约会列表进行分组?

时间:2012-10-17 02:13:54

标签: ruby ruby-on-rails-3 activerecord

我正在返回一份约会清单。

现在他们看起来像这样:

-Jan 1
--appointment @230
-Jan 1
--appointment @3
-Jan 1
--appointment @4
-Jan 2
--appointment @4
-Jan 2
--appointment @5

我想像

一样返回列表
-Jan 1
--appointment @230
--appointment @3
--appointment @4
-Jan 2
--appointment @4
--appointment @5

约会有一个“start_at”字段,它是一个DateTime。相对简单。 Jut不确定如何迭代集合,然后以最安全的方式对其进行分组。

感谢。

用户(是用户或培训师) has_many:约会 has_many:trainer_appointments,:class_name => “约会”,:foreign_key => “trainer_id”

预约

# Table name: appointments
#
#  id         :integer          not null, primary key
#  trainer_id :integer
#  start_at   :datetime
#  created_at :datetime         not null
#  updated_at :datetime         not null
#  user_id    :integer

这是一些游戏代码: u.trainer_appointments

=> [#<Appointment id: 6, trainer_id: 1, start_at: "2012-11-18 13:08:00", created_at: "2012-10-17 02:01:42", updated_at: "2012-10-17 02:01:42", user_id: 2>, #<Appointment id: 7, trainer_id: 1, start_at: "2012-11-18 13:08:00", created_at: "2012-10-17 02:02:00", updated_at: "2012-10-17 02:02:00", user_id: 2>, #<Appointment id: 8, trainer_id: 1, start_at: "2012-11-24 13:08:00", created_at: "2012-10-17 02:03:28", updated_at: "2012-10-17 02:03:28", user_id: 2>] 

返回3个约会。两个是在同一天。 1,在另一天。

希望以按日期分组的方式返回。 我试过这样的事情来弄清楚但是迷路了:

u.trainer_appointments.collect {|each| each.start_at}.uniq.collect {|each| u.trainer_appointments.find_by_start_at(each.to_date.beginning_of_day..each.to_date.end_of_day)}

返回了两个约会。两个日期之间。在第一天错过了第二名。

我知道代码在很多层面都是错误的。我只是想用迭代玩具。虽然没有得到我想要的东西。可能是因为uniq以某种方式限制了返回大小,即使我期望在最终数组中返回一个范围。

我不确定我需要迭代分组的实际结构。这不是我的专业知识。数组内的数组分组?我如何在视图中迭代它?

感谢。

3 个答案:

答案 0 :(得分:2)

如果您没有使用数据库的分组功能,最简单的方法是使用chunk:

require 'date'

# Make some test data
Appointment = Struct.new(:start_at)
data = ['2012-01-01 14:30', '2012-01-01 15:00', '2012-01-01 16:00',
 '2012-01-02 16:00', '2012-01-02 17:00']

appointments = data.map do |time|
  Appointment.new DateTime.parse(time)
end

# Use chunk to group array elements
appointments.
  sort { |a,b| b.start_at <=> a.start_at }. # always sort before chunking
  chunk { |appt| appt.start_at.to_date }. # chunk on day of the appointment
  each do |day, appts| # chunk emits two-element arrays
    puts
    puts "Day " + day.to_s
    appts.each { |appt| puts appt.start_at.strftime('%H:%M') }
  end

输出:

Day 2012-01-02
17:00
16:00

Day 2012-01-01
16:00
15:00
14:30

答案 1 :(得分:2)

您的收藏中的用户group_by

Ruby implementation要求传递给它的表达式求值为布尔值。

Rails implementation允许您传入一列,然后按该列对其进行分组。

您的代码应如下所示

u.trainer_appointments.
  collect {|a| a.start_at}.
  uniq.collect {|b| 
    u.trainer_appointments.
    group_by(b.to_date.beginning_of_day..b.to_date.end_of_day)
  }

find_by_start_at替换为group_by

编辑:确定范围!

# in User model (or the model for current_user)
class User < ActiveRecord::Base
  scope :mine, where(:trainer_id => current_user)
  scope :days!, where(:start_at.to_date.beginning_of_day)
  # the ! is there because "days" is a Ruby method
end

# in controller...
@client_appointments = @client.appointments.mine.group_by(&:days!)

注意:我不确定它是group_by(days!)group_by(:days!)还是group_by(&:days!)。你可能不得不玩它来看看它对你有用。

答案 2 :(得分:0)

使用以下内容结束:

    @client_appointments = @client.appointments.find(:all, :conditions => {:trainer_id => current_user}).group_by {|a| a.start_at.to_date.beginning_of_day }

然后像这样迭代:

- @client_appointments.sort.each do |month, appointments|
  %h2
    = month.to_s(:day_month)
  = render appointments