2012-06-19 37 views
0

行,所以我有这个帮手有没有更好的方式来做到的红宝石这个发现

def playlist_count(user, site_id) 
    user.companies.local(site_id).map(&:playlists).flatten.count 
end 

将返回播放列表计数所有公司

class Playlist < ActiveRecord::Base 
    belongs_to :company 
    scope :active, where('end_date >= ? AND player_id IS NOT NULL', Date.today) 

class Company < ActiveRecord::Base 
    has_many :playlists, :dependent => :destroy 
    scope :local, lambda{ |site_id| where(:site_id => site_id) } 

的问题是,它的帮手越来越丑陋,另一个问题是我需要活动播放列表(由我的范围在播放列表模型中定义)

有没有办法清理我的帮手或使用范围来取得活动的播放列表计数对于所有用户公司

+2

使Date.today评估的任何时间范围是叫你应该换你的活跃范围的说法在拉姆达。 'scope:active,lambda {where(...)}' –

回答

4

你可以运行查询反过来:

Playlist.active.where(:company_id => user.companies.local(site_id)).count 
+0

Does:company_id => user.companies.local(site_id)产生一个SQL in子句,因为有多于一条记录返回 – Trace

+0

是的,它产生类似' SELECT COUNT(*)FROM playlist WHERE playlist.company_id IN(SELECT company.id FROM FROM WHERE ...)' – Stefan

+0

啊,这个明显比我的好。 –

1

您可以将范围应用于关联。试试这个:

user.companies.local(site_id).map { |company| company.playlists.active.count }.sum 

另一个优点是,它会执行的,而不是从数据库中获取所有活动的播放列表和Ruby的计​​数他们select count(*) ... SQL语句。

如果您关心性能,在单个SQL语句中连接表和计数所有用户公司的活动播放列表会更有效,而不是遍历公司并对每个公司进行计数查询。

相关问题