我需要编写一个查询,该查询仅计算之前未参加过事件的个人。
以下是模型
class Individual < ActiveRecord::Base
has_many :attendances, dependent: :destroy
has_many :events, through: :attendances
end
class Attendance < ActiveRecord::Base
belongs_to :event
belongs_to :individual
end
class Event < ActiveRecord::Base
has_many :attendances, dependent: :destroy
has_many :individuals, through: :attendances
end
在我看来,我有两个不同的查询。每个查询都会测量每个会计年度的事件参与情况。
查询2015财年:
<%= Event.published.joins( :attendances => :individual ).where(
:events => {:fiscal_session => "2014-10-01".."2015-09-30"}
).distinct.count(:individual_id) %>
质疑2016财年:
<%= Event.published.joins( :attendances => :individual ).where(
:events => { :fiscal_session => "2015-10-01".."2016-09-30"}
).distinct.count(:individual_id) %>
问题在于2016财年的查询不会忽视2015财年参加活动的个人。
我正在使用postgresql,并且我已经尝试编写范围和辅助方法来过滤2015年度参加的个人。但我还没有能够弄明白。
例如,2015财年:
<%= Individual.joins(attendances: :event).where(
:events => {:fiscal_session => "2014-10-01".."2015-09-30"}
).group('individuals.id').having('count(attendances.id) > 0').count %>
结果是:
{2787=>1, 3469=>1}
这是2016财年
<%= Individual.joins(attendances: :event).where(
:events => {:fiscal_session => "2015-10-01".."2016-09-30"}
).group('individuals.id').having('count(attendances.id) > 0').count %>
结果如下:
{2905=>1, 3444=>1, 2787=>1, 2790=>1, 2858=>1}
如您所见,individual_id 2787
计算两次。我不想在2016财年的查询中计算2787
。
使用Rails和ActiveRecord实现所需计数的正确方法是什么?
答案 0 :(得分:2)
我认为,实现目标的最佳方式是进行两次查询。
ignore_individuals = Event
.published
.joins(attendances: :individual)
.where(
'events.fiscal_session <= ?', '2015-09-30'
)
.pluck(:individual_id)
Event
.published
.joins(attendances: :individual)
.where.not(individual_id: ignore_individuals)
.where(
events: { fiscal_session: "2015-10-01".."2016-09-30" }
).distinct.count(:individual_id)
答案 1 :(得分:1)
我认为您正在寻找:Individual.includes(:events).where( events: { id: nil } ).count
这些人从未参加任何活动。
答案 2 :(得分:1)
不是积极的但是如果您正在寻找2016年参加过活动的个人数量,并且您的桌子上有时间戳,我相信您可以做到
Individual.joins(:attendances).where("attendances.created_at > ?", "01-01-2016").count