Rails中优雅的求和/分组等

时间:2010-07-21 20:06:07

标签: ruby-on-rails ruby

我有许多关联在一起的对象,我想布置一些仪表板来显示它们。为了论证:

  • 出版社 - 有很多书
  • 书 - 有一位作者,来自一位,经历多个州
  • 出版社作者 - 写了很多 书籍

我想得到一个说:

的仪表板
  • 出版社放了多少本书 这个月出去了吗?
  • 一本书多少钱 作者本月写道?
  • 每本书的状态(正在进行中,已发表)?

首先,我在考虑一些非常简单的代码:

@all_books = Books.find(:all, :joins => [:author, :publishing_house], :select => "books.*, authors.name, publishing_houses.name", :conditions => ["books.created_at > ?", @date])

然后我继续浏览我想要的每个子元素并将它们合并到新的数组中 - 例如:

@ph_stats = {}
@all_books.map {|book| @ph_stats[book.publishing_house_id] = (@ph_stats[book.publishing_house_id] || 0) + 1 }

这感觉不像铁轨 - 想法?

2 个答案:

答案 0 :(得分:1)

我认为最好的办法是将命名范围链接在一起,以便您可以执行以下操作:

@books = Books.published.this_month

http://api.rubyonrails.org/classes/ActiveRecord/NamedScope/ClassMethods.html#M001683 http://m.onkey.org/2010/1/22/active-record-query-interface

答案 1 :(得分:1)

您应该考虑编写此类查询所需的SQL,因此,以下查询在所有数据库中工作:

出版社的图书数量

PublishingHouse.all(:joins => :book, :select => "books.publishing_house_id, publishing_houses.name, count(*) as total", :group => "1,2")

作者本月撰写的书籍数量

如果你打算将它移到一个范围内 - 你需要把它放在一个lambda

Author.all(:joins => :books, :select => "books.author_id, author.name, count(*) as total", :group => "1,2", :conditions => ["books.pub_date between ? and ?", Date.today.beginning_of_month, Date.today.end_of_month])

这是由于使用Date.today,或者 - 你可以使用now():: date(特定于postgres)并根据它构建日期。

特定州的图书

不太确定这对你的数据模型是否正确

Book.all(:joins => :state, :select => "states.name, count(*) as total", :group => "1")

所有这些都是通过SQL的魔力完成的。