1

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

现在它们看起来像这样:

-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”字段,它是一个日期时间。比较简单。只是不确定如何遍历集合,然后以最合理的方式对其进行分组。

谢谢。

用户(是用户或培训师) has_many :appointments has_many :trainer_appointments, :class_name => "Appointment", :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 以某种方式限制了返回大小,即使我期望在最终数组中返回一个范围。

我不确定迭代分组需要什么实际结构。这不是我的专长。数组中的数组分组?我将如何在视图中迭代它?

谢谢。

4

3 回答 3

2

您收藏的用户group_by

Ruby 实现要求传递给它的表达式计算为布尔值。

Rails 实现允许您传入一个列,并按该列对它进行分组。

您的代码应如下所示

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_atgroup_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!). 你可能不得不玩弄它,看看什么对你有用。

于 2012-10-17T05:30:38.487 回答
2

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

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
于 2012-10-17T02:56:18.657 回答
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
于 2012-10-17T08:43:37.907 回答