2012-01-11 77 views
0

我称模型event_recurrences它包含2分重要的列event_idcached_schedule的Ruby/Rails - 高级分组与GROUP_BY

cached_schedule包含日期

event_id的阵列用于引用事件

我需要

  1. 获取所有event_recurrence对象TS @something.event_recurrences - 通过每次复发对象完成

  2. 去拿event_id和所有的 从cached_schedule

  3. 迭代通过每个月的日期,并吐出像下面

列表Jan

event_id date

事项标识日期

事项标识日期

二月

事项标识日期

...等等

要回顾一下event_id位于event_recurrence.event_id日期的event_id将发生在有位于阵列内event_recurrence.cached_schedule

一些我有一些不完整的代码可以使用...

此代码成功地使用created_at字段按月显示每个event_recurrence对象。

在我的控制器

@schedule_months = @something.event_recurrences.order("created_at DESC").group_by { |e| e.created_at.beginning_of_month } 

在我看来

<% @schedule_months.keys.sort.each do |month| %> 
    <div class="month"> 
     <%= month.strftime("%B %Y") %> 
    </div> 
    <% for event in @schedule_months[month] %> 
    <li><%= event %></li> 
    <% end %> 
<% end %> 

在此先感谢。

真诚,jBeas

回答

3

还有一些细节从你的问题......比如丢失,可以在cached_schedule跨越多个月的日期,或者他们都保证是在同一个月?

如果你只是想使用核心红宝石:

dates = [] 
@something.event_recurrences.each do |er| 
    er.cached_schedule.each { |date| dates << [date, er.event_id] } 
end 
@event_dates = dates.group_by { |(date,event_id)| date.mon } 
视图

然后:

<% @event_dates.keys.sort.each do |month| %> 
    <div class="month"> <%= month.strftime("%B %Y") %></div> 
    <% @event_dates[month].each do |(date,event_id)| %> 
     <li><%= date %> <%= event_id %></li> 
    <% end %> 
<% end %> 

您可能需要调整代码中使用一点取决于细节,但是,这将给你的想法。请注意使用解构赋值:@event_dates[month].each do |(date,event_id)|。这节省了一行代码,并表达了代码更清晰的功能。

如果您不介意将自己的扩展添加到核心Ruby类中,那么可以使此代码更清晰和更简洁。我经常用我称之为mappend的方法:

module Enumerable 
    def mappend 
    result = [] 
    each { |a| enum = yield a; enum.each { |b| result << b } if enum } 
    result 
    end 
end 

的名字是mapappend混合 - 它就像map,但它预计映射块的返回值也是Enumerable,它将所有返回的Enumerable“附加”到单个Array中。有了这个,你可以写:

@event_dates = @something.event_recurrences.mappend { |er| er.cached_schedule.map { |date| [date, er.event_id] }}.group_by { |(date,event_id)| date.mon } 

OK,这可能是很多关于一条线,但你的想法:这样可以节省您使用一个中间变量累积结果。

更新:类似mappend现在是Ruby核心库的一部分!它叫做flat_map

+0

例如,“cached_schedule”中的日期可以跨越多个月,还是都保证在同一个月内? - 他们跨越多个月。再次感谢!现在就试试这个! – jBeas 2012-01-11 16:36:09

+0

我设计了代码,所以它应该可以工作,即使日期跨越多个月(但不是在不同年份的同一月份)。我还没有测试过,所以你可能需要做一些调试,但就像我说的,它应该给你想法 – 2012-01-11 16:39:48

+0

有几件事要改变,但我从你的例子中得到它的工作。 :)我会在完成时更新示例。非常感谢你帮助我。 – jBeas 2012-01-11 16:59:09