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

予定には、DateTimeである「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つの予定を返します。2つは同じ日にあります。別の日に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)}

これは2つの予定を返しました。両方の日付の間。初日の2日欠席。

私はコードが非常に多くのレベルで間違っていることを知っています。私はただ繰り返しをいじろうとしていました。でも欲しいものが手に入らなかった。おそらく、最終的な配列で範囲が返されることを期待していたにもかかわらず、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_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!)。何が効果的かを確認するために、それをいじくり回さなければならない場合があります。

于 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 に答える