首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >可能会覆盖计数的工作方式,或者找到更好的方法来实现这一点

可能会覆盖计数的工作方式,或者找到更好的方法来实现这一点
EN

Stack Overflow用户
提问于 2011-10-05 13:35:52
回答 1查看 325关注 0票数 1

我在我的艺术家模型中有这个范围,它为我提供了艺术家,按照他们在特定时间段内的受欢迎程度的顺序。popularity_caches表中的popularity是每天计算的。

代码语言:javascript
复制
scope :by_popularity, lambda { |*args|
  options = (default_popularity_options).merge(args[0] || {})

  select("SUM(popularity) AS popularity, artists.*").
from("popularity_caches FORCE INDEX (popularity_cache_group), artists FORCE INDEX (index_artists_on_id_and_genre_id)").
where("popularity_caches.target_type = 'Artist'").
where("popularity_caches.target_id = artists.id").
where("popularity_caches.time_frame = ?", options[:time_frame]).
where("popularity_caches.started_on > ?", options[:started_on]).
where("popularity_caches.started_on < ?", options[:ended_on]).
group("artists.id").
order("popularity DESC")
}

这似乎起作用了,除非我想要获取计数:Artist.by_popularity.count。我得到了一个时髦的哈希作为回报(可能是在这段时间内拥有popularity_caches的艺术家的数量):

代码语言:javascript
复制
#<OrderedHash {295954=>1, 20143=>1, 157532=>1, 181291=>1, 300086=>1, 50100=>1, 262898=>1, 293888=>1, 130158=>2, 279943=>1, 336758=>1, 100201=>1, 134290=>2, 22726=>3, 144620=>2, 62497=>2 # snip

这可能是我想要的SQL:

代码语言:javascript
复制
SELECT COUNT(DISTINCT(artists.id)) AS count_all
FROM popularity_caches FORCE INDEX (popularity_cache_group), artists FORCE INDEX (index_artists_on_id_and_genre_id)
WHERE (popularity_caches.target_type = 'Artist')
  AND (popularity_caches.target_id = artists.id)
  AND (popularity_caches.time_frame = 'week')
  AND (popularity_caches.started_on > '2011-02-28 16:00:00')
  AND (popularity_caches.started_on < '2011-10-05')
ORDER BY popularity DESC

为了获得计数,我必须创建一个独立的方法,该方法的功能基本相同,只是SQL的格式有所不同。它有点糟糕,因为当我想分页时,我必须传递两件事:

代码语言:javascript
复制
@artists = Artists.by_popularity(some args).paginate(
  :total_entries => Artist.count_by_popularity(pass in the same args here as in Artist.by_popularity),
  :per_page => 5,
  page => ...
)

我闻起来很香,因为它很易碎。

在ARel中有没有办法做到这一点?也许可以覆盖它的计数方式(distinct artists.id)并删除group by,这样它就不会返回计数的哈希?

谢谢!

EN

回答 1

Stack Overflow用户

发布于 2014-10-16 10:44:46

使用神奇的scuttle.io解决了问题

代码语言:javascript
复制
PopularityCach.select(
  Arel::Nodes::Group.new(Artist.arel_table[:id]).count.as('count_all')
).where(
  PopularityCach.arel_table[:target_type].eq('Artist').and(
    PopularityCach.arel_table[:target_id].eq(Artist.arel_table[:id]).and(
      PopularityCach.arel_table[:time_frame].eq('week').and(
        PopularityCach.arel_table[:started_on].gt('2011-02-28 16:00:00').and(
          PopularityCach.arel_table[:started_on].lt('2011-10-05')
        )
      )
    )
  )
).order(:popularity).reverse_order
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7657090

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档