按关联对象的属性进行分组

时间:2014-01-29 12:17:18

标签: ruby-on-rails ruby postgresql

class Event < ActiveRecord::Base
  has_many :meetings
end

class Meeting < ActiveRecord::Base
  belongs_to :event
end

如何编写mysql查询来搜索group_by会议DATE(start_at)的所有事件?

Event.inludes(:meetings).group ...

因此我希望获得Hash

{"2014-01-24"=>[#<Event id: , title: "First", created_at: "2014-01-24 16:02:52", updated_at: "2014-01-24 16:02:52">, #<Event id: 2, title: "Second", created_at: "2014-01-24 16:02:52", updated_at: "2014-01-24 16:02:52">], "2013-01-29"=>[#<Event id: 3, title: "Third", created_at: "2013-01-29 05:30:40", updated_at: "2014-01-29 05:30:40">], ...]}

P.S:我正在使用PostgreSQL

现在我通过这种方式得到它:

hash = {}
Meeting.where("extract(month from start_at) = ?", Date.today.month).pluck('DATE(start_at)').uniq.each do |date| 
  hash[date] = Event.includes(:meetings).where("DATE(meetings.start_at) = ?", date).references(:meetings)
end

但它对数据库产生了如此多的查询:(

1 个答案:

答案 0 :(得分:1)

Event.joins(:meetings).group('meetings.start_at')应该这样做。但是你想要的是一个group_by数组方法http://apidock.com/ruby/Enumerable/group_by所以你应该做的是

@ events.group_by {| e | e.meeting.start_date}

如果有很多人,你最好还是

result = Hash.new
Meeting.include(:events).each {|m| result[m.start_at]||=[]; result[m.start_at] << m.events}

并且可以使用一个衬垫

Meeting.includes(:events).inject(Hash.new) do |result, m|
  result[m.start_at]||=[]
  result[m.start_at] << w.events
  result
end

此代码应执行两个数据库调用,我认为